I’ve got as simple a child of InterprocessConnection as I can think of, and my test program crashes on shutdown every time. I’m running on Windows 7.
This is what I do:
- construct my InterprocessConnection child
- call createPipe(foo,-1)
- call sendMessage(010203040506) (i.e. I build a MemoryBlock with 0x0102030405 and call sendMessage with that)
- sendMessage fails since there’s nothing on the other side of the pipe
- destroy my InterprocessConnection child
After the call to createPipe, the InterprocessConnection’s thread starts and waits inside NamedPipe::read (eventually at the WaitForMultipleObjects call in NamedPipeInternal::connect).
I’m pretty sure the NamedPipeInternal destructor runs when the InterprocessConnection thread is still using that object. The call stack in the thread that calls the destructor (the main thread) looks something like:
NamedPipe::cancelPendingReads sets an event that WaitForMultipleObjects is waiting on, but then cancelPendingReads immediately returns and NamedPipe::close calls ~NamedPipeInternal. The InterprocessConnection thread may have woken up from WaitForMultipleObjects, but there’s no telling that NamedPipeInternal::connect has finished, nor that the InterprocessConnection thread is really done with the NamedPipeInternal object…At least not as far as I can tell.
I’m not sure the proper way to fix this, but perhaps in InterprocessConnection::disconnect() if the stopThread() call moves in between the call to cancelPendingReads() and close(), that would cover it?
PS The windows implementation of NamedPipe::close also calls cancelPendingReads, so it gets called twice at the moment. Don’t think this is related, but in case it influences a solution…