Why does WaitForSingleObject(INVALID_HANDLE_VALUE, INFINITE) block? - windows

Why does
HANDLE mutexHandle = INVALID_HANDLE_VALUE;
WaitForSingleObject(mutexHandle, INFINITE);
block? It does not return with an error message. Checking the handle for INVALID_HANDLE would be stupid for a mutex as I would need a mutex for accessing the mutex handle...
BTW: It does return with WAIT_FAILED if the handle was closed.

From http://blogs.msdn.com/oldnewthing/archive/2004/03/02/82639.aspx:
Fourth, you have to be particularly careful with the INVALID_HANDLE_VALUE value: By coincidence, the value INVALID_HANDLE_VALUE happens to be numerically equal to the pseudohandle returned by GetCurrentProcess(). Many kernel functions accept pseudohandles, so if if you mess up and accidentally call, say, WaitForSingleObject on a failed INVALID_HANDLE_VALUE handle, you will actually end up waiting on your own process. This wait will, of course, never complete, because a process is signalled when it exits, so you ended up waiting for yourself.

Related

What is "a wait on a notification handle" in the Windows API?

I'm trying to figure out how to use FindFirstChangeNotification in order to do some file monitoring (in this case, for hot-reloading settings). I'm a bit a confused about what this function returns. From the docs, it creates a "change notification handle". Ok, sure. But then "A wait on a notification handle succeeds when...". In this context, what is a "wait"?
In this context, the "wait" refers to wait for the "change notification handle", which is a kind of HANDLE that you can wait until it is in signaled state by using Wait Functions.
A minimal example would be like this:
static void MyNotifyDirChange(HWND hwnd, LPCWSTR szPath)
{
HANDLE hWaitNotify = ::FindFirstChangeNotificationW(
szPath, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE |
FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_LAST_ACCESS |
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY);
if (hWaitNotify == INVALID_HANDLE_VALUE)
{
::MessageBoxW(hwnd,
L"FindFirstChangeNotificationW failed.",
nullptr, MB_ICONERROR);
return;
}
::WaitForSingleObject(hWaitNotify, INFINITE);
::MessageBoxW(hwnd, L"Dir change notify.",
L"Notify", MB_ICONINFORMATION);
}
WaitForSingleObject waits until the specified object is in the signaled state or the time-out interval elapses. Since I've specified INFINITE, it will stay at there forever until the handle became signaled. And when the handle became signaled, it means something has happened; the files in the directory have changed or whatnot.
From Wait Functions on MSDN:
Wait functions allow a thread to block its own execution. The wait functions do not return until the specified criteria have been met.
Most of the wait functions (the notable exception being WaitOnAddress) accept one or more handles that determine the criteria for returning from the wait. To wait on a handle means to pass the handle to one of these wait functions. It is also common to refer to waiting on an object, which has the same meaning as waiting on a handle to that object.
Synchronization Objects lists the various kinds of objects you can wait on: events, mutexes, semaphore and waitable timers; change and memory resource notifications; jobs, processes and threads; and (subject to some caveats) I/O handles.

How to use setevent to stop process handler

I'm trying to createProcess then inherit process handle to event handle
HANDLE app_event;
TCHAR* path = L"C:\\My.exe";
STARTUPINFO info;
PROCESS_INFORMATION processInfo;
ZeroMemory(&info, sizeof(info));
info.cb = sizeof(info);
ZeroMemory(&processInfo, sizeof(processInfo));
CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
ThreadId = processInfo.dwThreadId;
app_event = CreateEventW(nullptr, TRUE, FALSE, nullptr);
DuplicateHandle(GetCurrentProcess(), processInfo.hProcess,
GetCurrentProcess(),
&app_event,
0, FALSE,
DUPLICATE_SAME_ACCESS);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
and I'm creating thread for event
But when I call setEvent to stop process
The process don't stop and i got stuck at WaitForSingleObject
SetEvent(app_event);
WaitForSingleObject(app_thread, INFINITE);
Am I doing something wrong?
Sorry I'm new to C++.
DuplicateHandle doesn't do what you think it does. It makes a new handle to an existing object. You seem to think it can be used to turn an object of one type into an object of another type. It cannot. A process handle cannot become an event handle.
This mis-understanding is compounded by your code's lack of error checking. The Win32 API won't raise exceptions. Errors are signaled by way of the API function return values. Which you ignore, unfortunately.
What you seem to be doing is trying to terminate a process in a co-operative manner. Signal an event to indicate termination is required. Then wait for the process to stop. That only works if the other process co-operates. There's no indication that is the case for you. You certainly cannot inject a termination event into the other process.
If the other process doesn't have a documented way to be signaled for termination then the best you can do is call TerminateProcess. If you are in control of the other process then you can agree on a co-operative procedure for termination. Use a named event that both process can gain access to.
I would like to repeat my main advice one more time. Always check for errors when calling Win32 functions. There's no one single way to do that, you must read the documentation carefully for each and every function that you call.

IOCP loop termination may cause memory leaks? How to close IOCP loop gracefully

I have the classic IOCP callback that dequeues i/o pending requests, process them, and deallocate them, in this way:
struct MyIoRequest { OVERLAPPED o; /* ... other params ... */ };
bool is_iocp_active = true;
DWORD WINAPI WorkerProc(LPVOID lpParam)
{
ULONG_PTR dwKey;
DWORD dwTrans;
LPOVERLAPPED io_req;
while(is_iocp_active)
{
GetQueuedCompletionStatus((HANDLE)lpParam, &dwTrans, &dwKey, (LPOVERLAPPED*)&io_req, WSA_INFINITE);
// NOTE, i could use GetQueuedCompletionStatusEx() here ^ and set it in the
// alertable state TRUE, so i can wake up the thread with an ACP request from another thread!
printf("dequeued an i/o request\n");
// [ process i/o request ]
...
// [ destroy request ]
destroy_request(io_req);
}
// [ clean up some stuff ]
return 0;
}
Then, in the code I will have somewhere:
MyIoRequest * io_req = allocate_request(...params...);
ReadFile(..., (OVERLAPPED*)io_req);
and this just works perfectly.
Now my question is: What about I want to immediately close the IOCP queue without causing leaks? (e.g. application must exit)
I mean: if i set is_iocp_active to 'false', the next time GetQueuedCompletionStatus() will dequeue a new i/o request, that will be the last i/o request: it will return, causing thread to exit and when a thread exits all of its pending i/o requests are simply canceled by the system, according to MSDN.
But the structures of type 'MyIoRequest' that I have instanced when calling ReadFile() won't be destroyed at all: the system has canceled pending i/o request, but I have to manually destroy those structures I have
created, or I will leak all pending i/o requests when I stop the loop!
So, how I could do this? Am I wrong to stop the IOCP loop with just setting that variable to false? Note that is would happen even if i use APC requests to stop an alertable thread.
The solution that come to my mind is to add every 'MyIoRequest' structures to a queue/list, and then dequeue them when GetQueuedCompletionStatusEx returns, but shouldn't that make some bottleneck, since the enqueue/dequeue process of such MyIoRequest structures must be interlocked? Maybe I've misunderstood how to use the IOCP loop. Can someone bring some light on this topic?
The way I normally shut down an IOCP thread is to post my own 'shut down now please' completion. That way you can cleanly shut down and process all of the pending completions and then shut the threads down.
The way to do this is to call PostQueuedCompletionStatus() with 0 for num bytes, completion key and pOverlapped. This will mean that the completion key is a unique value (you wont have a valid file or socket with a zero handle/completion key).
Step one is to close the sources of completions, so close or abort your socket connections, close files, etc. Once all of those are closed you can't be generating any more completion packets so you then post your special '0' completion; post one for each thread you have servicing your IOCP. Once the thread gets a '0' completion key it exits.
If you are terminating the app, and there's no overriding reason to not do so, (eg. close DB connections, interprocess shared memory issues), call ExitProcess(0).
Failing that, call CancelIO() for all socket handles and process all the cancelled completions as they come in.
Try ExitProcess() first!

Make parent thread wait till child thread finishes in VC

According to MSDN:
The WaitForSingleObject function can wait for the following objects:
Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer
Then we can use WaitForSingleObject to make the parent-thread wait for child ones.
int main()
{
HANDLE h_child_thread = CreateThread(0,0, child, 0,0,0); //create a thread in VC
WaitForSingleObject(h_child_thread, INFINITE); //So, parent-thread will wait
return 0;
}
Question
Is there any other way to make parent-thread wait for child ones in VC or Windows?
I don't quite understand the usage of WaitForSingleObject here, does it mean that the thread's handle will be available when the thread terminates?
You can establish communication between threads in multiple ways and the terminating thread may somehow signal its waiting thread. It could be as simple as writing some special value to a shared memory location that the waiting thread can check. But this won't guarantee that the terminating thread has terminated when the waiting thread sees the special value (ordering/race conditions) or that the terminating thread terminates shortly after that (it can just hang or block on something) and it won't guarantee that the special value gets ever set before the terminating thread actually terminates (the thread can crash). WaitForSingleObject (and its companion WaitForMultipleObjects) is a sure way to know of a thread termination when it occurs. Just use it.
The handle will still be available in the sense that its value won't be gone. But it is practically useless after the thread has terminated, except you need this handle to get the thread exit code. And you still need to close the handle in the end. That is unless you're OK with handle/memory leaks.
for the first queation - yes. The method commonly used here is "Join". the usage is language dependant.
In .NET C++ you can use the Thread's Join method. this is from the msdn:
Thread* newThread = new Thread(new ThreadStart(0, Test::Work));
newThread->Start();
if(newThread->Join(waitTime + waitTime))
{
Console::WriteLine(S"New thread terminated.");
}
else
{
Console::WriteLine(S"Join timed out.");
}
Secondly, the thread is terminated when when you are signaled with "WaitForSingleObject" but the handle is still valid (for a terminated thread). So you still need to explicitly close the handle with CloseHandle.

CreateProcess with WaitForSingleObject performance degradation

Everyone probably knows the code to run a program and wait for it to end:
CreateProcess(...
WaitForSingleObject(Process.hProcess, INFINITE
It was used several times by myself. But recently I found that this call when it launches a program with a multimedia playback has worse performance than the same process being executed from a general file manager (Windows XP). That's ok with CPU consumption of my (parent) process, but while playing the fragment there are unexpected little stops.
I made a little change to something like:
CreateProcess ...
do {
Sleep(100);
Res = WaitForSingleObject(Process.hProcess, 10);
} while (Res == WAIT_TIMEOUT);
And it helped. Now the child process plays the fragment without problems.
So what's wrong with the first fragment and is it documented somewhere? As I see from the tests the second "wait" is more "relaxed" than the first one, but the first one doesn't eat CPU at least formally
If this code is running on a UI thread, you will cause performance problems with other processes that (directly or indirectly) send messages to your window(s), since you do not run the message loop while you are waiting for the child process. Neither Sleep() nor WaitForSingleObject() will process messages.
Windows Explorer (the file manager) will not suffer this problem because it:
Does not keep an open handle to processes it launches at the user's request (I think this is more likely, since Explorer needs neither to know when the process exits or its exit code), or
Does not wait on any open process handles it may keep from its children, and importantly
Always makes sure to run a message loop while it waits on handles. This is very important in any process that makes use of COM, which Explorer uses heavily.
Instead of calling WaitForSingleObject(), you can call MsgWaitForMultipleObjects(). If you specifiy QS_ALLINPUT for the dwWaitMask parameter, MsgWaitForMultipleObjects will return either when your event is signaled or when there is input in the thread's message queue. If MsgWaitForMultipleObjects() returned because a message is available, you can process it and resume waiting:
MSG msg;
DWORD reason = WAIT_TIMEOUT;
while (WAIT_OBJECT_0 != reason) {
reason = MsgWaitForMultipleObjects(1, &hChildProcess, FALSE, INFINITE, QS_ALLINPUT);
switch (reason) {
case WAIT_OBJECT_0:
// Your child process is finished.
break;
case (WAIT_OBJECT_0 + 1):
// A message is available in the message queue.
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
// Note that if your main message loop does additional processing
// (such as calling IsDialogMessage() for modeless dialogs)
// you will want to do those things here, too.
}
break;
}
}

Resources