pthread_mutex_lock() and EnterCriticalSection - winapi

may be I misunderstood something but...
When I call pthread_mutex_lock() and then call pthread_mutex_lock() out of the same thread again without calling pthread_mutex_unlock(), the second call of pthread_mutex_lock() will block.
But: when I call EnterCriticalSection() and call EnterCriticalSection() out of the same thread again without calling LeaveCriticalSection(), the second call of EnterCriticalSection() will NOT block since it is called out of the same thread (what is a very weird behaviour for me).
So my question is there a WinAPI function available that behaves like pthread_mutex_lock() and locks independent from the thread context?
I'm aware of libpthread for Windows but I prefer to have a WinAPI function here.

You could use a Semaphore with the maximum count set to one.
See Semaphore Objects
When you successfully acquire the semaphore, its count is decremented: going to zero in our case.
No other thread can acquire it, including the current one.

pthread_mutex_lock documentation:
If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex maintains the concept of a lock count. When a thread successfully acquires a mutex for the first time, the lock count is set to one. Every time a thread relocks this mutex, the lock count is incremented by one. Each time the thread unlocks the mutex, the lock count is decremented by one. When the lock count reaches zero, the mutex becomes available for other threads to acquire. If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, an error will be returned.
MSDN ReleaseMutex states:
A thread can specify a mutex that it already owns in a call to one of the wait functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).
The wait functions are the equivalent to pthread_mutex_lock.
See Mutex Objects (Windows) to get more details about this API.
And this stackoverflow entry to see what the CRITICAL_SECTION object contains. This will disclose
that the CRITICAL_SECTION object holds - among others - a value LockCount to allow recursive use. See the EnterCriticalSection function to learn about this feature.

Related

Why WaitForMultipleObjectsEx acquires mutex during APC?

I have 5 threads (on a multicore system) that simultaneously wait for:
A mutex M to be acquired
An event E to be signaled
I'm using WaitForMultipleObjectsEx(..., TRUE, INFINITE, TRUE) since the threads use APCs.
Note that the APCs do not use/touch/alter/observe the mutex or the event in any way.
I'm using Visual Studio along with Process Hacker to debug, and I'm witnessing a strange phenomenon:
Frequently, the thread that is supposed to run (call it thread A) is still waiting on the two objects.
I say "supposed to run" because:
I have verified many times (including via Process Hacker) that the E is indeed in a signaled state
No other thread has acquired ownership of M. In fact, 3 other threads are also waiting to acquire M.
Nevertheless, according to Process Hacker (which uses NtQueryMutant to retrieve the count), during such scenarios, M has an absurdly low "Count" value, such as -618.
Of course, I'm not forgetting to call ReleaseMutex (yes, I'm checking the return value too); indeed, once someone later acquires the mutex, the Count increases back up.
So this begs the question: if 3 of the 4 other threads are sleeping, what is the last thread (B) doing?
The answer is that B is executing an APC inside the WaitForMultipleObjectsEx call.
No matter how far I "step" through B in Visual Studio (even all the way back up RtlDispatchAPC), none of the other threads wake up.
It is only after that APC has finished executing that any thread wakes up!
I find this quite bizarre, WaitForMultipleObjectEx's documentation says:
When bWaitAll is TRUE, the function's wait operation is completed only when the states of all objects have been set to signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects are also set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled.
Is the documentation wrong, or is this a mistake on my part?
Why does WaitForMultipleObjectsEx acquire the mutex during the execution of an APC, even though it knows it will never acquire the mutex anyway (because executing an APC implies it will return WAIT_IO_COMPLETE, never acquiring the mutex)?
I cannot comment so I use answer...
You don't show any code but shouldn't the APC trigger the WaitForMultipleObjectsEx return with WAIT_IO_COMPLETION code in the thread that is running??

When a thread that calls SetWaitableTimer exits while another thread is waiting on the timer, is the timer cancelled?

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx
According to msdn, in the remarks sections, it states:
"If the thread that set the timer terminates and there is an associated completion routine, the timer is canceled. However, the state of the timer remains unchanged. If there is no completion routine, then terminating the thread has no effect on the timer."
Then further down, it states:
"If the thread that called SetWaitableTimer exits, the timer is canceled. This stops the timer before it can be set to the signaled state and cancels outstanding APCs; it does not change the signaled state of the timer."
Hence my question,
if I have one thread calling SetWaitableTimer without an associated completion routine and another thread calling WaitOnMultipleObjects(passing in the timer object handle) and the thread that calls SetWaitiableTmer exits shortly thereafter, would the timer object be cancelled or would it still become signaled when the period expires?
To give more information directly from the implementation of waitable timers: if you use a CompletionRoutine, the timer is placed on a linked list chained off the thread which called SetWaitableTimer. When the thread is terminated, the kernel walks the dying thread's linked list and cancels are timers which are still queued.
If you're not using a completion routine, the timer is never added to any thread's linked list and thus isn't cancelled when any particular thread dies.
The documentation is somewhat unclear. I think the best you can do is test it yourself. I believe however that the timer cancels automatically only if the I/O completion routine is used.
I can give some "theoretical" background about windows APCs, to justify my (educated) guess.
APC = "asynchronous procedure call". In windows every user-mode thread is equipped with a so-called APC queue, a system-managed queue of procedures that must be called on this thread. A thread may enter a so-called "alertable wait" state (on purpose), during which it may execute one or more of the procedures in this queue. You may either put the procedure call in the APC queue manually, or issue an I/O, which on completion will "put" the procedure call there.
In simple words the scenario is the following: you issue several I/Os, and then you wait for either of them to complete (or fail), and, perhaps, some other events. You then call one of the alertable-waiting functions: SleepEx, WaitForMultipleObjectsEx or similar.
Important note: this mechanism is designed to support a single-threaded concurrency. That is, the same thread issues several I/Os, waits for something to happen, and responds appropriately. All the APC routines are guaranteed to be called in the same thread. Hence - if this thread exits - there's no way to call them. Hence - all the outstanding I/Os are also cancelled.
There are several Windows API functions that deal with asynchronous I/O, whereas they allow a choice of several completion mechanisms (such as ReadFileEx): APC, setting an event, or putting a completion in the I/O completion port. If those functions are used with APC - they automatically cancel the I/O if the issuing thread exits.
Hence, I guess that waitable timer auto-cancels only if used with APC.

Is Win32 Event object recursive mutexes?

I searched MSDN, Mutex could be locked twice, but there isn't any word on recursive acquire the same event object twice in the same thread.
can we lock the win32 events twice in the same thread?
Edit: what is the meaning of Lock events? here I assume event is auto-reset.
Lock: a thread is waken up from WaitForXXX (e.g. , WaitForSingleObject)
Un-Lock: a thread is calling SetEvent or PluseEvent.
A mutex is fundamentally different to an event. Whereas a mutex is used to provide MUTual EXclusion, so that only one thread may access a resource at a time, an event is just a notification mechanism. An auto-reset event provides single-wakeup notifications, whereas a manual-reset event provides multiple-wakeup notifications.
If you signal an auto-reset event, only one thread will receive that signal, and that thread only once; any other threads --- or any other calls to a wait function for that event from the same thread --- will wait until there is a second call to SetEvent.
If you signal a manual-reset event then it stays signalled until you reset it, so multiple threads can wake, and multiple calls to a wait function for that event from the same thread will succeed until some thread calls ResetEvent.
An event doesn't have an "owner" either way: just because thread A was woken from its call to a wait function last time by another thread setting the event, there is nothing that prevents it waiting again, and nothing that specifies whether thread A or B will be woken if both wait on the same auto-reset event. There is also nothing that requires any particular thread to call SetEvent: any thread in the system may do so, whether or not that thread ever calls a wait function for that event. Indeed, a common use case has one thread calling SetEvent, and one or more other threads waiting.
So: yes, you can wait for an event from a thread that just waited for that event, but this is not a lock, and other threads may also wait for the event, and may also wake if the event is signalled.
Update for edited question:
You can use an event to provide a lock, but that is not part of the inherent semantics. You may call WaitForSingleObject twice in succession using the same auto-reset event handle. This is not an error as far as Windows is concerned: you just need to ensure that some other thread or threads calls SetEvent twice, in such a way that the waiting thread wakes from the first call to WaitForSingleObject before the second call to SetEvent happens, in order to avoid "lost" wakeups: SetEvent doesn't count the calls, it just sets the flag.
Also: do not use PulseEvent. It does not guarantee that a thread will wake, even if there is one currently waiting.
I agree with Anthony Williams.
One note that I'd like to add is that many people (not just you) don't quite understand the difference between a mutex and an auto-reset event. They actually behave similarly and may (from the technical perspective) be used for resource locking.
The major difference between them is that mutex "knows" which thread holds it. That is, when WaitForSingleObject (or similar) acquires a mutex - it's automatically "assigned" to the calling thread. This has two consequences:
Mutex may be acquired recursively by the same thread. This won't work with an auto-reset event of course.
If the thread owning a mutex exits - the mutex is automatically "freed". The appropriate WaitXXXX function will return with WAIT_ABANDONED.
Events OTOH may be seen as particular cases of semaphores. Auto-reset event is equivalent to a semaphore charged by (at most) 1, and manual-reset event - equivalent to an infinitely-charged semaphore.

Mutex vs Event in Windows

can somebody please explain what is the difference if I do
mutex = createMutex
waitForSingleObject
Release(mutex)
and
event = createEvent
waitForSingleObject
Release(event)
I'm so confused, can I use both versions for the synchronization? thanks in advance for any help
You use a mutex to ensure that only one thread of execution can be accessing something. For example, if you want to update a list that can potentially be used by multiple threads, you'd use a mutex:
acquire mutex
update list
release mutex
With a mutex, only one thread at a time can be executing the "update list".
You use a manual reset event if you want multiple threads to wait for something to happen before continuing. For example, you started multiple threads, but they're all paused waiting for some other event before they can continue. Once that event happens, all of the threads can start running.
The main thread would look like this:
create event, initial value false (not signaled)
start threads
do some other initialization
signal event
Each thread's code would be:
do thread initialization
wait for event to be signaled
do thread processing
Yes, both can be used for synchronization but in different ways.
Mutex is a mutual exclusion object and can be acquired only by a single instance at a time. It is used to avoid the simultaneous use of a common resource, such as a global variable, by pieces of computer code
Event is an objet that can be explicitly set to a state by use of the SetEvent function.

Recycle-safe thread ID's and when thread stack gets freed?

Does the stack reserved/commited for a thread get freed when
the thread terminates
the thread object is destroyed
(i.e. the thread is terminated and all handles to the thread are closed)
?
More broadly, are there significant resources associated with a thread that has terminated, but still exists since there are valid handles to it?
Reason: I need to modify a kind of "scoped singleton", so it doesn't return a single object, but a per-thread object. I cannot rely on thread creation/termination notices, much less on process-wide ones.
At the moment, I store the objects in a map<ThreadID, Object>, with a cache cleanup policy that's suitable for my application. To protect myself from the OS "recycling" thread ID's, I keep an handle to the thread open. (Rec
A side effect would be holding open handles to long-terminated threads in some corner cases.
According to "Windows VIA C/C++" by Richter and Nasarre (A must-have book for any C++ Windwos programmer) p.154:
Terminating a Thread
A thread can be terminated in four
ways:
The thread function returns. (This is highly recommended.)
The thread kills itself by calling the ExitThread function. (Avoid this
method.)
A thread in the same process or in another one calls the TerminateThread
function. (Avoid this method.)
The process containing the thread terminates. (Avoid this method.)
The Thread Function Returns
You should always design your thread
functions so that they return when you
want the thread to terminate. This is
the only way to guarantee that all
your thread's resources are cleaned up
properly.
Having your thread function return
ensures the following:
All C++ objects created in your thread function will be destroyed
properly via their destructors.
The operating system will properly free the memory used by the thread's
stack.
The system will set the thread's exit code (maintained in the thread's
kernel object) to your thread
function's return value.
The system will decrement the usage count of the thread's kernel object.
The ExitThread Function
You can force your thread to terminate by having it call ExitThread:
VOID ExitThread(DWORD dwExitCode);
This function terminates the thread
and causes the operating system to
clean up all the operating system
resources that were used by the
thread. However, your C/C++ resources
(such as C++ class objects) will not
be destroyed. For this reason, it is
much better to simply return from your
thread function instead of calling
ExitThread yourself.
Of course, you use ExitThread's
dwExitCode parameter to tell the
system what to set the thread's exit
code to. The ExitThread function does
not return a value because the thread
has terminated and cannot execute any
more code.
Note The recommended way to have a
thread terminate is by having its
thread function simply return (as
described in the previous section).
However, if you use the method
described in this section, be aware
that the ExitThread function is the
Windows function that kills a thread.
If you are writing C/C++ code, you
should never call ExitThread. Instead,
you should use the C++ run-time
library function _endthreadex. If you
do not use Microsoft's C++ compiler,
your compiler vendor will have its own
alternative to ExitThread. Whatever
this alternative is, you must use it.
The TerminateThread Function
A call to
TerminateThread also kills a thread:
BOOL TerminateThread( HANDLE
hThread, DWORD dwExitCode);
Unlike ExitThread, which always kills
the calling thread, TerminateThread
can kill any thread. The hThread
parameter identifies the handle of the
thread to be terminated. When the
thread terminates, its exit code
becomes the value you passed as the
dwExitCode parameter. Also, the
thread's kernel object has its usage
count decremented.
Note The TerminateThread function is
asynchronous. That is, it tells the
system that you want the thread to
terminate but the thread is not
guaranteed to be killed by the time
the function returns. If you need to
know for sure that the thread has
terminated, you might want to call
WaitForSingleObject or a similar function,
passing the handle of the thread.
A well-designed application never uses
this function because the thread being
terminated receives no notification
that it is dying. The thread cannot
clean up properly, and it cannot
prevent itself from being killed.
Note When a thread dies by returning
or calling ExitThread, the stack for
the thread is destroyed. However, if
TerminateThread is used, the system
does not destroy the thread's stack
until the process that owned the
thread terminates. Microsoft purposely
implemented TerminateThread in this
way. If other still-executing threads
were to reference values on the
forcibly killed thread's stack, these
other threads would raise access
violations. By leaving the killed
thread's stack in memory, other
threads can continue to execute just
fine.
In addition, dynamic-link libraries
(DLLs) usually receive notifications
when a thread is terminating. If a
thread is forcibly killed with
TerminateThread, however, the DLLs do
not receive this notification, which
can prevent proper cleanup.
When a Thread Terminates
The following actions occur when a
thread terminates:
All User object handles owned by the
thread are freed. In Windows, most
objects are owned by the process
containing the thread that creates the
objects. However, a thread owns two
User objects: windows and hooks. When
a thread dies, the system
automatically destroys any windows and
uninstalls any hooks that were created
or installed by the thread. Other
objects are destroyed only when the
owning process terminates.
The thread's exit code changes from
STILL_ACTIVE to the code passed to
ExitThread or TerminateThread.
The state of the thread kernel object
becomes signaled.
If the thread is the last active
thread in the process, the system
considers the process terminated as
well.
The thread kernel object's usage count
is decremented by 1.
When a thread terminates, its
associated thread kernel object
doesn't automatically become freed
until all the outstanding references
to the object are closed.
Once a thread is no longer running,
there isn't much any other thread in
the system can do with the thread's
handle. However, these other threads
can call GetExitCodeThread to check
whether the thread identified by
hThread has terminated and, if it has,
determine its exit code:
BOOL GetExitCodeThread( HANDLE
hThread, PDWORD pdwExitCode);
The exit code value is returned in the
DWORD pointed to by pdwExitCode. If
the thread hasn't terminated when
GetExitCodeThread is called, the
function fills the DWORD with the
STILL_ACTIVE identifier (defined as
0x103). If the function is successful,
TRUE is returned.
Maybe you should use pthread_getspecific, pthread_setspecific and pthread_key_create to manage your per thread singleton.

Resources