Thread: CRITICAL_SECTION, deleted?

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Arrow CRITICAL_SECTION, deleted?

    Hey, just a quick question: How can you tell if a critical section has been deleted or not? Apparently checking if it's NULL won't work since it's a struct, and we're supposed to treat it as 'logically opaque'.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    As usual, use a flag variable. Wrap the flag variable and the CRITICAL_SECTION in a single structure if you like. Use a C++ class. Of course, access to the flag variable may also have to be synchronized.

    http://cboard.cprogramming.com/showt...5&pagenumber=2

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Wrap the flag variable and the CRITICAL_SECTION in a single structure if you like. Use a C++ class. Of course, access to the flag variable may also have to be synchronized.
    Ah haaaha, I love those things that go a full circle in orbit and then whack you in the back of the head.

    Ah well, I'm using 2 events and 2 CRITICAL_SECTIONS together, and they should all be created/deleted at the same time anyways; I guess I'll just test to see if one of the events is non-NULL, and if it is, then free all 4 of the objects at the same time and set that event to NULL. It seems to work fine from the (very) limited testing I've done, but it'd be great if you could tell me if you spot any problem.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It sounds like you have a race condition with your current method.

    The best bet is to initialise sync objects in your main thread before you create worker threads. However, if that is not possible there is a simple, fast and cheap way to do it.


    Code:
    static volatile LONG fStartInit    = -1;
    static volatile LONG fEndInit      = -1;
    static volatile LONG fStartDestroy = -1;
    
    void CreateSyncObjects( void )
    {
    	if (InterlockedIncrement(&fStartInit) == 0)
    	{
    		// Initialise resources...
    
    		fEndInit = 0;
    	}
    	else
    	{
    		// Wait for resources to be finished initialising...
    		while(fEndInit != 0) Sleep(1);
    	}
    }
    
    
    void DestroySyncObjects( void )
    {
    	if (InterlockedIncrement(&fStartDestroy) == 0)
    	{
    		// Cleanup resources...
    	}
    }
    As the InterlockedIncrement will only return 0 once, this guarantees that the code in the block will only be executed the first time it is reached. It also guarantees that the resources will not be used before they are created.

    [edit]
    Of course, after you call DestroySyncObjects, you must make sure the objects are no longer used by any thread. If you really need to call DestroySyncObjects from a worker thread then you need to implement a reference counting system.
    Code:
    static volatile LONG fStartInit    = -1;
    static volatile LONG fEndInit      = -1;
    static volatile LONG nRefCount     = 0;
    
    void CreateSyncObjects( void )
    {
    	InterlockedIncrement(&nRefCount);
    
    	if (InterlockedIncrement(&fStartInit) == 0)
    	{
    		// Initialise resources...
    
    		fEndInit = 0;
    	}
    	else
    	{
    		// Wait for resources to be finished initialising...
    
    		while(fEndInit != 0) Sleep(0);
    	}
    }
    
    
    void DestroySyncObjects( void )
    {
    	if (InterlockedDecrement(&nRefCount) == 0)
    	{
    		// Cleanup resources...
    	}
    }
    [/edit]

    [edit2]
    Still not perfect. If you call Create, Destroy, Create you will run into trouble. This sync stuff is mind destroying.
    [/edit2]

    I learnt this method from someone on the board.

    Another option that may be helpful is spin locks. Here is an example.
    Last edited by anonytmouse; 03-19-2004 at 07:49 AM.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>It sounds like you have a race condition with your current method.
    Come again? What's a race condition?

    Well, my sync. stuff is for my async. event-notified Winsock wrapper. I have a class, with a static startup() and cleanup() function, which should be called only at program start and end, in which I initialize the sync objects and spawn a thread to wait on events (startup()), and kill the thread and delete the sync objects (cleanup()). I just figured, in my cleanup() i'd prefer if i could test each sync object individually to see if they've been deleted already, or aren't initialized or whatever, to prevent accidentally deleting something that shouldn't be deleted.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    A race condition is where, under certain conditions, multi threaded code instructions execute in the wrong order. Search for more information.

    From your description I don't see why you have a sync issue at all. Are startup() and cleanup() not called from the same thread?

    I seriously doubt there is any problem calling DeleteCriticalSection() on a CRITICAL_SECTION that is zeroed out. So you could just:

    Code:
    // declare:
    static CRITICAL_SECTION myCs = { 0 };
    
    // and delete:
    DeleteCriticalSection(&myCs);
    memset(&myCs, 0, sizeof(myCs));
    This is not thread safe, but neither is testing and setting to NULL.

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>A race condition is where, under certain conditions, multi threaded code instructions execute in the wrong order.
    So basically, it's a 'race' between 2 threads: there's no guarantee of them not being side by side?

    >>I don't see why you have a sync issue at all.
    There must've been a misunderstanding I'm not worrying about more than one thread trying to delete the critical section, I'm thinking of what happens if the user calls cleanup() twice in a row (or, for that matter, just once without calling startup()). One of those code-level idiotproofing things I just wanted to ensure that if anything that should get destroyed in cleanup() is already gone, it doesn't get deleted again.

    Code:
    // declare:
    static CRITICAL_SECTION myCs = { 0 };
    
    // and delete:
    DeleteCriticalSection(&myCs);
    memset(&myCs, 0, sizeof(myCs));
    You mean deleting a 'dead' critical section won't get you runtime errors? Or is that only a zeroed out critical section?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >>So basically, it's a 'race' between 2 threads: there's no guarantee of them not being side by side?<<

    Example race condition.

    >>I'm thinking of what happens if the user calls cleanup() twice in a row (or, for that matter, just once without calling startup()). <<

    So we are back to the beginning, you can just use a flag variable. static BOOL bInitialized - set it in startup() and cleanup().

    >>You mean deleting a 'dead' critical section won't get you runtime errors? Or is that only a zeroed out critical section?<<

    I don't really know. I'm just guessing that a zeroed out one wouldn't cause problems. I'd try to avoid either if possible.

  9. #9
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, thanks. If that's the case, then what I have will suffice for a flag variable (check if the WSAEVENT is initialized).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. writing text over a deleted button
    By algi in forum Windows Programming
    Replies: 4
    Last Post: 05-02-2005, 11:32 AM
  2. Someone deleted my post
    By DarkViper in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 11-27-2002, 06:05 PM
  3. Deleted instance
    By Boksha in forum C++ Programming
    Replies: 3
    Last Post: 05-28-2002, 11:15 AM
  4. What actually happens when a file is deleted ?
    By pritesh in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 02-06-2002, 02:05 PM