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

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.

Related

How to force GetQueuedCompletionStatus() to return immediately?

I have hand-made thread pool. Threads read from completion port and do some other stuff. One particular thread has to be ended. How to interrupt it's waiting if it hangs on GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx()?
Finite timeout (100-1000 ms) and exiting variable are far from elegant, cause delays and left as last resort.
CancelIo(completionPortHandle) within APC in target thread causes ERROR_INVALID_HANDLE.
CancelSynchronousIo(completionPortHandle) causes ERROR_NOT_FOUND.
PostQueuedCompletionStatus() with termination packet doesn't allow to choose thread.
Rough TerminateThread() with mutex should work. (I haven't tested it.) But is it ideologically good?
I tried to wait on special event and completion port. WaitForMultipleObjects() returned immediately as if completion port was signalled. GetQueuedCompletionStatus() shows didn't return anything.
I read Overlapped I/O: How to wake a thread on a completion port event or a normal event? and googled a lot.
Probably, the problem itself – ending thread's work – is sign of bad design and all my threads should be equal and compounded into normal thread pool. In this case, PostQueuedCompletionStatus() approach should work. (Although I have doubts that this approach is beautiful and laconic especially if threads use GetQueuedCompletionStatusEx() to get multiple packets at once.)
If you just want to reduce the size of the thread pool it doesn't matter which thread exits.
However if for some reason you need to signal to an particular thread that it needs to exit, rather than allowing any thread to exit, you can use this method.
If you use GetQueuedCompletionStatusEx you can do an alertable wait, by passing TRUE for fAlertable. You can then use QueueUserAPC to queue an APC to the thread you want to quit.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684954(v=vs.85).aspx
If the thread is busy then you will still have to wait for the current work item to be completed.
Certainly don't call TerminateThread.
Unfortunately, I/O completion port handles are always in a signaled state and as such cannot really be used in WaitFor* functions.
GetQueuedCompletionStatus[Ex] is the only way to block on the completion port. With an empty queue, the function will return only if the thread becomes alerted. As mentioned by #Ben, the QueueUserAPC will make the the thread alerted and cause GetQueuedCompletionStatus to return.
However, QueueUserAPC allocates memory and thus can fail in low-memory conditions or when memory quotas are in effect. The same holds for PostQueuedCompletionStatus. As such, using any of these functions on an exit path is not a good idea.
Unfortunately, the only robust way seems to be calling the undocumented NtAlertThread exported by ntdll.dll.
extern "C" NTSTATUS __stdcall NtAlertThread(HANDLE hThread);
Link with ntdll.lib. This function will put the target thread into an alerted state without queuing anything.

Who is the calling thread of the callback function set by CreateTimerQueueTimer()?

I guess it's the thread, say A, on which the timer was created. But I can't figure out how exactly the callback function is called. Assume the timer expires, and then what happens? Does this happen when this thread gets its time slice? And if this is the case, I think the function should be called by the scheduler or what before the context is finally switched to A, then can I say A is the caller?
Thanks.
The timer callback can also be called by a pool thread, a thread that specifically manages timers or in the context of the creating thread, (the creating thread is designed to accept and process an 'Asynchronous Procedure Call'). The flag paramters in CTQT() control the action upon timer expiry.
If the timer event is called by a pool thread or timer-manager thread, that thread will become ready upon expiry and, when there is a core available to run it, it will make the callback 'immediately' within its own context. The thread that created the timer could, if it wished, wait on a synchro object, (event or semaphore), that could be signaled by the timer callback, (ie. normal inter-thread comms).
The timer callback can only be executed in the context of the thread that created it if that thread is in a position to execute the callback when it receives some sort of signal. In the case of these timers, an APC is QUEUED to the creating thread and, if that thread is blocked on one of the 'alertable' wait calls, it will become ready immediately, will run when there is a core available to run it. After the APC has run, the wait call will return. If the wait call is not SleepEx(), it will return WAIT_IO_COMPLETION - a result that is usually ignored. If the thread is not waiting when the APC is queued up, it will not be executed until the thread makes the next wait call, (obviously - since the thread must be off doing something else:).
'And if this is the case, I think the function should be called by the scheduler or what before the context is finally switched to A, then can I say A is the caller?' NO!

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.

Does a thread waiting on Windows Events need to get scheduled on CPU to wake up from sleeping?

It is best to describe my question in an example:
We create a Windows Event handle by CreateEvent, with manualReset as FALSE.
We create 4 threads. Ensure that they all start running and waiting on the above event by WaitForSingleObject.
In the main thread, in a for loop, we signal this event 4 times, by SetEvent. such as:
for (int i = 0; i < 4; ++i) ::SetEvent(event);
My question is, can we say that all these 4 threads will certainly be waken up from waiting on this event?
According to my understanding of Windows Event, the answer is YES. Because when the event is set, there is always a thread waiting for it.
However, I read on MSDN that "Setting an event that is already set has no effect". Since the waiting threads probably do not get a chance to run while main thread setting event in the loop. Can they still be notified and reset the event to nonsignaled? If the event is not reset, the following SetEvent in the loop is obviously useless.
Or the OS kernel knows which thread should be notified when an event is set, and reset this event immediately if there is a waiting thread. So the waiting thread does not need to be schedule to reset the event to nonsignaled?
Any clarification or references are welcome. Thanks.
Because when the event is set, there is always a thread waiting for it.
No, you don't know that. A thread may indefinitely suspended for some reason just before the NtWaitForSingleObject system call.
Since the waiting threads probably do not get a chance to run while main thread setting event in the loop.
If a thread is waiting for an object, it doesn't run at all - that's the whole point of being able to block on a synchronization object.
Can they still be notified and reset the event to nonsignaled? If the event is not reset, the following SetEvent in the loop is obviously useless.
The thread that sets the event is the one that resets the signal state back to 0, not the thread that gets woken up. Of course, if there's no thread waiting the signal state won't be reset.
Or the OS kernel knows which thread should be notified when an event is set, and reset this event immediately if there is a waiting thread.
Yes, the kernel does know. Every dispatcher object has a wait list, and when a thread waits on an object it pushes a wait block onto that list.
In a word? No.
There's no guarantee that each and every call to Set() will signal a waiting thread. MSDN describes this behavior as follows:
There is no guarantee that every call
to the Set method will release a
thread from an EventWaitHandle whose
reset mode is
EventResetMode::AutoReset. If two
calls are too close together, so that
the second call occurs before a thread
has been released, only one thread is
released. It is as if the second call
did not happen. Also, if Set is called
when there are no threads waiting and
the EventWaitHandle is already
signaled, the call has no effect.
(Source)
If you want to ensure that a specific number of threads will be signaled, you should use a more suitable kind of synchronization primitive, such as a Semaphore.
When you do SetEvent(event), since your manual reset is set as false for the event, any thread (windows doesnt specify any preferences) from one of the four would get passed the waitforsingleobject() and on the subsequent calls the other 3 threads would randomly be selected since your event is autoreset after releasing every thread.
If you're trying to imply the threads are re-entrant, the threads getting released every time would again be one out of four randomly by OSes choice.

Why use ReadDirectoryChangesW asynchronously?

I've read the documentation for ReadDirectoryChangesW() and also seen the CDirectoryChangeWatcher project, but neither say why one would want to call it asynchronously. I understand that the current thread will not block, but, at least for the CDirectoryChangeWatcher code that uses a completion port, when it calls GetQueuedCompletionStatus(), that thread blocks anyway (if there are no changes).
So if I call ReadDirectoryChangesW() synchronously in a separate thread in the first place that I don't care if it blocks, why would I ever want to call ReadDirectoryChangesW() asynchronously?
When you call it asynchronously, you have more control over which thread does the waiting. It also allows you to have a single thread wait for multiple things, such as a directory change, an event, and a message. Finally, even if you're doing the waiting in the same thread that set up the watch in the first place, it gives you control over how long you're willing to wait. GetQueuedCompletionStatus has a timeout parameter that ReadDirectoryChangesW doesn't offer by itself.
You would call ReadDirectoryChangesW such that it returns its results asynchronously if you ever needed the calling thread to not block. A tautology, but the truth.
Candidates for such threads: the UI thread & any thread that is solely responsible for servicing a number of resources (Sockets, any sort of IPC, independent files, etc.).
Not being familiar with the project, I'd guess the CDirectoryChangeWatcher doesn't care if its worker thread blocks. Generally, that's the nature of worker threads.
I tried using ReadDirectoryChanges in a worker thread synchronously, and guess what, it blocked so that the thread wouldn't exit by itself at the program exit.
So if you don't want to use evil things like TerminateThread, you should use asynchronous calls.

Resources