9

One can use a CRITICAL_SECTION variable to get mutual exclusion.

My question is: does CRITICAL_SECTION support copying? If I pass one by value to another thread, can I know for sure that mutual exclusion will work?

I wouldn't be surprised if the answer is "you cannot do that", but it'd be nice to have some sort of official confirmation. I wasn't able to find a statement either way in the documentation.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
redtuna
  • 4,586
  • 21
  • 35

2 Answers2

13

No. A CRITICAL_SECTION cannot be copied. MSDN states this explicitly:

A critical section object cannot be moved or copied.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
1

A quick search through the headers reveals that the structure is defined in winnt.h, and this definition clearly seems to indicate that copying the structure wouldn't work.

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //

    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

That said, I have no idea why these internal counters are stored in a user-space structure, i.e. what will happen if a program modifies these?

casablanca
  • 69,683
  • 7
  • 133
  • 150
  • 1
    The documentation clearly states that you cannot modify the contents of a `CRITICAL_SECTION`: "The process must also not modify the object, but must treat it as logically opaque." – James McNellis Jul 16 '10 at 22:39
  • Which is why I raised this question. What does "cannot" mean? It's uncommon for anything beyond a handle to be manipulable by user programs. – casablanca Jul 16 '10 at 23:31
  • If an API says that a consumer of the API _must_ not do something, that means "if you do this, all bets are off." – James McNellis Jul 16 '10 at 23:48
  • 3
    And a critical section is intended to be *FAST*. That means that it can't spend the time entering the kernel and leaving to enter. If you want a synchronization object that provides similar semantics to a critical section, use a mutex object. Then you don't have to worry about all those internal details being exposed ot the application. Of course your application will be a lot slower than the critical section but that's the price you pay for architectural purity. – Larry Osterman Jul 17 '10 at 02:12