I have a question about Windows IPC. I implemented IPC with mutex on Windows, but there is a problem when I made the connection with another thread;when the thread terminated, the connection is closed.
- The connection thread(A) makes connection to the server
- Main thread(B) uses the connection handle(global variable) returned by A
- A terminates
- B cannot refer the handle any more – because connection is closed
It is natural that mutex is released when the process terminated. However, in the case of thread, I need the way to hold mutex to maintain connection even though the thread terminated, if the process is alive.
Semaphore can be the alternative on Linux, however, on Windows, it is impossible to use semaphor because it cannot sense the abnormal disconnection.
Does someone have any idea?
There is no way to prevent the ownership of a mutex from being released when the thread that owns it exits.
There are a number of other ways you might be able to fix the problem, depending on the circumstances.
1) Can you change any of the code on the client? For example, if the client executable is using a DLL that you have provided to establish and maintain the connection, you could change the DLL so that it uses a more appropriate object (such as a named pipe) rather than a mutex, or you could get the DLL to start its own thread to own the mutex.
2) Is there more than one client? Presumably, since you are using a mutex, you are only expecting one client to connect at a time. If you can safely assume that only one client will be connected at a time, then when the server detects that the mutex has been abandoned, it could close its own handle to the mutex. When the client process exits, the mutex will automatically be deleted, so the server could periodically check to see whether it still exists or not.
3) How is the client communicating with the server? The server is presumably doing something useful for the client, so there must be another communications channel as well as the mutex. For example, if the client is opening a named pipe to the server, you could use that connection instead of the mutex to detect when the client process exits. Or, if the communications channel allows you to determine the process ID of the client, you could open a handle to the process and use that to detect when the client process exits.
4) If no other solution will work, and you are forced to rewrite the client as well as the server, consider using a more appropriate form of IPC, such as a named pipe.
Additional
5) It is common practice to use a process handle to wait for (or test for) process termination. Most often, these handles are the ones generated for the parent when a process is created, but there is no reason not to use a handle generated by OpenProcess. As far as precedent goes, I assure you there is at least as much precedent for using a handle generated by OpenProcess to monitor a client process as there is for using a mutex; it is entirely possible that you are the first person to ever try to use a Windows mutex to detect that a process has exited. 🙂
6) Presumably the SQLDisconnect() function is calling ReleaseMutex in order to disconnect from the server. Since it is doing so from a thread that doesn’t own the mutex, that won’t do anything except return an error code, so there’s no reasonable way for your server to detect that happening. Does the function also call CloseHandle on the mutex? If so, you could use the approach in (2) to detect when this happens. This would work both for calls to SQLDisconnect() and when the process exits. It shouldn’t matter that there are multiple clients, since they are using different mutexes.
6a) I say “no reasonable way” because you could conceivably use hooking to change the behaviour of ReleaseMutex. This would not be a good option.
7) You should examine carefully what the SQLDisconnect() function does apart from calling ReleaseMutex and/or CloseHandle. It is entirely possible that you can detect the disconnection by some means other than the mutex.