Deadlock on closing a pipe while another thread reads this pipe? - macos

I'm having a deadlock on closing a pipe:
close(myPipeFD);
Another thread, the reading thread, is in a blocking read state from this exact same pipe:
ssize_t sizeRead = read(myPipeFD, buffer, bufferSize);
Could it be the cause of such deadlock? I thought that read would have immediately returned sizeRead == 0? Should I emit an interruption in this reading thread?

It is not safe to close a file descriptor when another thread may be using it, for several reasons.
As you've discovered, some system calls which can block waiting on the file descriptor may behave in unexpected ways if that file descriptor is closed.
But there are other problems. Let's suppose that the first thread closes a file descriptor just before a second thread enters a read() call on it. Let's also suppose that a third thread happens to be opening a file or a socket at the same time. The new file descriptor will get the same number as the one that was just closed. The second thread will read from the wrong file descriptor!
In general, you need to make sure that only one thread is operating on a file descriptor at a time. Threads should "own" file descriptors. You can pass ownership from one thread to another, but only one should own each at a time.
If you need to cancel operations, you need to use non-blocking I/O and things like select() for when you need to block waiting for data. Furthermore, you need to include a cross-thread communication channel (e.g. pipe) in the select() call which will be the mechanism by which one thread submits a request to the other to close one of its file descriptors.
You should also look into Dispatch I/O or asynchronous mechanisms like run-loop driven NSFileHandle.

Related

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

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).

Ruby - logging in time-critical multithreading application

I have to log activity of application that runs in many threads. What would be best approach to do that? Probably it is not possible that all threads log into one file, because they will lock each other? Is it best to use separate file for each thread then?
I use this within a method that is called by threads at the moment:
f=File.open(...)
f.puts "log message"
f.close
All threads are calling this method. I will append thread number to file name so that every thread creates its own file. This method is called when thread calls it and gives it new information to log. Then method opens file, writes information and closes it again. However is this opening and closing of file time-consuming in time-critical application? Or is this not something to be concerned of?

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.

Unblocking accept()

I have a blocking call to accept(). From another thread I close the socket, hoping that it'll unblock the accept() call, which it does but I have a case when it doesn't: e.g. thread A enters accept(), thread B closes the socket, thread A doesn't return from accept().
Question: what could cause closing a socket to not unblock an accept()?
One hacky trick to unblock accept(2) is to actually connect(2) to the listening end from your other thread. Flip some flag indicating it's time to stop the loop, connect(2), close(2) the connecting socket. That way the accept(2)-ing thread would know to close the socket and shut itself down.
You must not ever free a resource in one thread while another thread is or might be using it. You will never get this to work reliably. For one thing, you can never be 100% sure the thread is actually blocked in accept, as opposed to about to block in it. So there will always be race conditions.
And, of course, shutdown won't work because the socket is not connected.
There are a couple of ways to handle this problem. For example, you can set a flag that the thread checks when it returns from accept and then make a connection yourself. That will cause the thread to return from accept and then it will see the flag and terminate.
You can also switch to non-blocking sockets. Have the thread call select or poll with a timeout and check if the thread should terminate when it returns from select or poll. You can also select or poll on both the socket and a pipe. Then just send a byte on the pipe to unblock the thread. pthread_kill is another possibility, as is pthread_cancel.
Not knowing the details of your problem, my guess would be the best solution is to rearchitect so you don't have a thread whose sole job is to wait forever in accept. That way, you won't even have a thread you need to kill. If you don't want to keep accepting connections, just rig things so that your threads stop doing that, but let the threads keep going doing other things. (The number of running threads you have should be dependent on the number of things you can usefully do at once, not the total number of things you have to do.)
Try calling shutdown() followed by close() from thread B. You should be checking the return codes on these calls too as they may help you figure out what is going wrong when thread A fails to become unblocked.

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