Link to home
Start Free TrialLog in
Avatar of mactep13
mactep13

asked on

Releasing Critical Section

I have determined that my program does not release the Critical Section object when it exits>
It inits the critical section with InitializeCriticalSectionandSpinLock(m_CS, 250);
 
Then, I should really be calling DeleteCriticalSection(m_CS);, but I am not. When the program exists, will the Critical Section resource be returned to windows or not?
I mean, when you allocate memory and not release it, Windows OS will release memory for you. Will it release the resource as well? I know for a fact that a GDI resource will NOT be released. But what about the Critical Section?

I am having a deadlock possibility which I can not reproduce, but if I exhausted all of my critical section resources, that could explain why this deadlock occures.

Any help would be appreciated.

Thanks,

Mactep
Avatar of mactep13
mactep13

ASKER

Actually, the init call is:

InitializeCriticalSectionAndSpinCount(m_CS, 250);

Thanks.
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
BTW, to ensure that critical sections are entered and released properly, I use a helper object that takes care of that, e.g.

struct locked_scope {

    locked_scope (CRITICAL_SECTION& rcs) : m_rcs(rcs) { EnterCriticalSection(&m_rcs);}
    ~locked_scope () { LeaveCriticalSection(&m_rcs);}

    CRITICAL_SECTION& m_cs;
};


...and here's a class that takes care about the construction/destruction:

class spinlock {

public:

      spinlock();
      ~spinlock();

      void enter ();
      void leave ();
        CRITICAL_SECTION& get() { return m_lock);
private:

      CRITICAL_SECTION m_lock;
};

spinlock::spinlock () {

      InitializeCriticalSection ( &m_lock);
}

spinlock::~spinlock () {

      DeleteCriticalSection ( &m_lock);
}

void
spinlock::enter () {

      EnterCriticalSection ( &m_lock);
}

void
spinlock::leave () {

      LeaveCriticalSection ( &m_lock);
}
And to put the above together:

class foo {

void SyncedFunction ();

spinlock lock;
};

void foo::SyncedFunction () {

locked_scope(lock.get());

// do anything here
}


FYI:
You'll notice that in the wrapper class I posted, I declared a copy constructor and assignment operatore private with no implementation.

For added safety, you should either add a copy constructor and assignment operator, or declare them private with
no implementation.

You also want to avoid declaring the wrapper class via new, because then you remove the security of the destructor call.

Whit the wrapper class you can easily protect a resource via following method:
ThreadSafeObject<foo> My_foo_obj(new foo);

You can then treat My_foo_obj as a pointer of foo type.
My_foo_obj->MyFooFunction();

The destructor for ThreadSafeObject will not only delete foo, but it will also call DeleteCriticalSection.