As I work with juce’s InterprocessConnection class more, I think I’ve started to understand when the connectionMade method gets called. On the “master” side of the pipe (the one that calls createPipe), it seems to mean “ready to receive.” On the slave side (the one that calls connectToPipe), I think it actually means both sides of the pipe are connected…so it means both ready to receive and ready to send.
I’ve been poking around trying to see if there’s a reasonable change that would make connectionMade mean the same thing for both master and slave, and probably even more important than consistency, be more interesting for the master side. Here’s what I came up with.
In NamedPipeInternal::connect, where connected is set to true (because WaitForMultipleObjects returns WAIT_OBJECT_0), that’s the spot where the master is really connected. I suppose we learn about a connection where GetLastError() from ConnectNamedPipe() is ERROR_PIPE_CONNECTED too. Communicating that back up to the InterprocessConnection is a bit of a struggle, but it’s interesting enough that it seems worth doing.
I think this means either adding a virtual function to NamedPipe called isConnected or potentially an argument to the NamedPipe constructor with a function pointer (or callback object) to call back. I’m leaning to a callback object. Some clarification that isOpen just means one side is open but not necessarily connected would help here too.
Assuming a callback object implemented as a virtual base class, InterprocessConnection inherits from it, and implements it to call connectionMadeInt.
That only gets us half way though. InterprocessConnection::createPipe calls initialiseWithPipe, and initialiseWithPipe calls connectionMadeInt as well. So when the NamedPipe connects, the InterprocessConnection already considers itself connected so nothing higher up learns about it.
The remaining work is therefore to remove connectionMadeInt from initialiseWithPipe, but only for the master side. The slave calls initialiseWithPipe, but only after openExisting succeeds…and openExisting only succeeds if the master’s CreateNamedPipe calls has succeeded. A new argument to initialiseWithPipe could cover this.
A more direct (and likely more correct) way might be to remove connectionMadeInt from initialiseWithPipe altogether and call NamedPipe::isConnected when the slave connects too. That happens in the NamedPipeInternal constructor when CreateFile succeeds.
There’s probably another bit of work as well to notify users of the NamedPipe that the connection has disappeared. I need to do some more homework to figure that out. And then there’s the implementation on mac/linux…so not a small amount of work overall but I think it would really help.
I suppose something similar may be needed for the socket part of InterprocessConnection. I sort of hope not, or that someone besides me can pull it off. I haven’t worked with the socket stuff at all and don’t really need to for my current project.
Thanks for your help.