Prevent WaitForSingleObject from hanging on a named semaphore when other process is terminated? - winapi

When using a globally named mutex to synchronize across two processes, and one of the two processes are killed (say in Task Manager, or due to a fault), the other process returns from WaitForSingleObject() with the appropriate error code and can continue.
When using a globally name semaphore, it does not release the waiting process if the other process is killed / terminated. WaitForSingleObject() will wait until it times out (which may be INFINITE or hours).
How do I stop WaitForSingleObject() from waiting when the other process is killed or terminated?
In this case, there is a single count on the semaphore used to control read/write requests of a shared buffer. The Requester signals the Provider to provide certain data, the Provider updates the buffer and signals back to the Requester that it can now read the buffer.

I suggest that you switch to using WaitForMultipleObjects and wait for the handle of the process that might get terminated (or thread if you want to do this within a single process) in addition to your semaphore handle. That way you can continue to use INFINITE timeouts. Just have to check the return value to see which object was signalled.
Also, I would consider a process terminating while holding a semaphore somewhat of a bug, particularly a semaphore used for actual inter-process communication.

Adding to the accepted answer.
I added logic if the waitms was going to be longer than some value maxwaitms then the requester/provider exchange the providers process id (GetCurrentProcessId()) before the long process. The requester opens a handle (OpenHandle()) to the provider process and waits on both the semaphore and the process handle to know when writing is done (or process terminated).

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.

How does windows terminate processes?

I am developing an application in windows which should run a code just before the process terminates. i am okay writing a kernel module to achieve this. but what are the functions that i should hook into ?
To get the notification about the termination of process i am doing this.
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1234);
DWORD wait = WaitForSingleObject(handle, INFINITE);
// Some block of code here that does the business logic.
handleProcessTermination();
My problem is the target process exits before my function handleProcessTermination() completes. i want a way to stop the exit of process and run my logic.
You should be able to create a kernel driver that calls PsSetCreateProcessNotifyRoutineEx to create a callback routine for when processes start/end. Your callback will be called "just before the last thread to exit the process is destroyed."
This won't allow you to "stop" the process termination permanently, but does allow you to inject some code just prior to the process ending.
I think there is no way to postpone the termination of a process. Even stopping all threads of that process will not help since the killing of the process is done by the kernel.
Due to my own experience I assume that windows does the following on process termination:
Mark the process to be terminated
Terminate all threads of the process
Clean up (free memory, release handles, ...)
Terminate process
Once step 1. is done the process is doomed since the scheduler will not activate any of the threads of that process. Activating one of the threads may cause them to go berserk since the process is in a partly destroyed state (e.g. memory may be freed, handles destroyed, ...) which may cause serious trouble!
I don't think that there is a possibility to change that behavior without chaning parts of the kernel.
Side note: It would be an interresting thing to test if WaitForSingleObject(thread, ...) is signalled before WaitForSingleObject(process, ...).

Inter-process communication in C

I have a scenario, where one process should wait for a signal from another process, and this wait should be blocking wait, and as soon as it gets a signal, it should wake up.
However, with mechanisms like kill() or raise(), the first process goes to wait state, but periodically checks after a specified amount of time, whether the even/signal occurred or not, and decides to wait or go on.
My requirement is a bit stringent, I want that process should wake up at the same instant as signal is received.
Please suggest something.
This can be achieved using semaphore,mutex or conditional variable. Or You can write wait and signal function by your own and you can control the behavior of these as per need. For reference see here: IPC examples
IPC concept and Examples Mutex and Conditional Variables

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 it possible to advance a deadlocked thread? stuck at WaitForSingleObject

If I have an app that is creating threads which do their work and then exit, and one or more threads get themselves into a deadlock (possibly through no fault of my own!), is there a way of programmatically forcing one of the threads to advance past the WaitForSingleObject it might be stuck at, and thus resolving the deadlock?
I don't necessarily want to terminate the thread, I just want to have it move on (and thus allow the threads to exit "gracefully".
(yes, I know this sounds like a duplicate of my earlier question Delphi 2006 - What's the best way to gracefully kill a thread and still have the OnTerminate handler fire?, but the situation is slightly different - what I'm asking here is whether it is possible to make a WaitForSingleObject (Handle, INFINTE) behave like a WaitForSingleObject (Handle, ItCantPossiblyBeWorkingProperlyAfterThisLong)).
Please be gentle with me.
* MORE INFO *
The problem is not necessarily in code I have the source to. The actual situation is a serial COM port library (AsyncFree) that is thread based. When the port is USB-based, the library seems to have a deadlock between two of the threads it creates on closing the port. I've already discussed this at length in this forum. I did recode one of the WaitForSingleObject calls to not be infinite, and that cured that deadlock, but then another one appeared later in the thread shutdown sequence, this time in the Delphi TThread.Destroy routine.
So my rationale for this is simple: when my threads deadlock, I fix the code if I can. If I can't, or one appears that I don't know about, I just want the thread to finish. I doesn't have to be pretty. I can't afford to have my app choke.
You can make a handle used in WaitForSingleObject invalid by closing it (from some other thread). In this case WaitForSingleObject should return WAIT_FAILED and your thread will be 'moved on'
If you don't use INFINITE but just set a given timeout time, you can check if the call returned because the time out time expired or because the handle you were waiting for got into the signalled state. Then your code can decide what to do next. Enter another waiting cycle, or simply exit anyway maybe showing somewhere 'hey, I was waiting but it was too long and I terminated anyway).
Another options is to use WaitForMultipleObjects and use something alike an event to have the wait terminate if needed. The advantage it doesn't need the timeout to expire.
Of course one the thread is awaken it must be able to handle the "exceptional" condition of continuing even if the "main" handle it was waiting for didn't return in time.

Resources