Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Why is TCriticalSection not locking?


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jan 17, 2018 4:08 AM Last Post By: Richard Simon Threads: [ Previous | Next ]
Richard Simon

Posts: 54
Registered: 10/7/07
Why is TCriticalSection not locking?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 8:17 AM
I was suspicious that my TCriticalSection was not preventing access to global variables, so I wrote a little test code.
I use a visual component's OnClick event to execute the following code in my UI thread. In this instance I am compiling to win32.

SaveThreadLock.Acquire;
SaveThreadLock.Acquire;
ShowMessage('got here');


I ran in debug mode expecting the ShowMessage line to never be executed... since the CriticalSection can not be Acquired twice. But I was wrong... the code sailed through just fine! I see that the parameter In the TCritcalSection. RecursionCount increments each time I execute the Acquire method, but it would appear that is all that happens.

In my application I have declared a global TCriticalSection ("SaveThreadLock"). I execute the Acquire method in the secondary Thread (and I Release it after the Execute procedure). I also wrap an Acquire and Release around any potential variable changes in my UI thread to protect them if it clashes with the save operation in the secondary thread. Obviously this is not actually happening.

Can someone explain what I am missing here please?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Why is TCriticalSection not locking?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2018 8:43 AM   in response to: Richard Simon in response to: Richard Simon
Richard simon wrote:

I ran in debug mode expecting the ShowMessage line to never be
executed... since the CriticalSection can not be Acquired twice.

Yes, it can, because a critical section is a reentrant type of lock.
Once a thread has acquired the lock, it can re-acquire the same lock as
many times as it wants to without blocking itself. For instance, think
of a function that locks the critical section, then calls another
function that needs to lock the same critical section. The lock has a
reference count on it, so each successful acquire must be matched with
a corresponding release. The number of acquires and releases must be
balanced in order to unlock the critical section so another thread can
then acquire its lock.

But I was wrong... the code sailed through just fine!

As it should be.

I see that the parameter In the TCritcalSection. RecursionCount
increments each time I execute the Acquire method, but it would appear
that is all that happens.

That is a private iplementation detail. But yes, it is tracking how
many times the calling thread has acquired the lock.

In my application I have declared a global TCriticalSection
("SaveThreadLock"). I execute the Acquire method in the secondary
Thread (and I Release it after the Execute procedure).

That is not the correct way to use a critical section. Its purpose is
to protect concurrent access to a shared resource. Acquire the lock
before accessing the resource, then release the lock after using the
resource. Keep the duration of a lock short, don't hold a lock for a
long period of time. Acquire, set the variable, release. Acquire,
read the variable, release. And so on.

I also wrap an Acquire and Release around any potential variable
changes in my UI thread to protect them if it clashes with the save
operation in the secondary thread.

That is not the correct way to work with the UI from a worker thread.

Can someone explain what I am missing here please?

A lack of fundamental understanding of how critical sections actually
operate. Read Microsoft's documentation on the subject:

Critical Section Objects
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682530.aspx

--
Remy Lebeau (TeamB)
Richard Simon

Posts: 54
Registered: 10/7/07
Re: Why is TCriticalSection not locking?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 17, 2018 4:08 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Richard simon wrote:

I ran in debug mode expecting the ShowMessage line to never be
executed... since the CriticalSection can not be Acquired twice.

Yes, it can, because a critical section is a reentrant type of lock.
Once a thread has acquired the lock, it can re-acquire the same lock as
many times as it wants to without blocking itself. For instance, think
of a function that locks the critical section, then calls another
function that needs to lock the same critical section. The lock has a
reference count on it, so each successful acquire must be matched with
a corresponding release. The number of acquires and releases must be
balanced in order to unlock the critical section so another thread can
then acquire its lock.

But I was wrong... the code sailed through just fine!

As it should be.

I see that the parameter In the TCritcalSection. RecursionCount
increments each time I execute the Acquire method, but it would appear
that is all that happens.

That is a private iplementation detail. But yes, it is tracking how
many times the calling thread has acquired the lock.

In my application I have declared a global TCriticalSection
("SaveThreadLock"). I execute the Acquire method in the secondary
Thread (and I Release it after the Execute procedure).

That is not the correct way to use a critical section. Its purpose is
to protect concurrent access to a shared resource. Acquire the lock
before accessing the resource, then release the lock after using the
resource. Keep the duration of a lock short, don't hold a lock for a
long period of time. Acquire, set the variable, release. Acquire,
read the variable, release. And so on.

I also wrap an Acquire and Release around any potential variable
changes in my UI thread to protect them if it clashes with the save
operation in the secondary thread.

That is not the correct way to work with the UI from a worker thread.

Can someone explain what I am missing here please?

A lack of fundamental understanding of how critical sections actually
operate. Read Microsoft's documentation on the subject:

Critical Section Objects
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682530.aspx

--
Remy Lebeau (TeamB)

Okay Remy... thanks for explaining that. I think I understand better now.
Kind Regards
Rick
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02