ChildProcessMaster bug


#1

In launchSlaveProcess the current code is

 

bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID, int timeoutMs, int streamFlags)
{
    connection = nullptr;
    jassert (childProcess.kill());
    const String pipeName ("p" + String::toHexString (Random().nextInt64()));
    StringArray args;
    args.add (executable.getFullPathName());
    args.add (getCommandLinePrefix (commandLineUniqueID) + pipeName);
    if (childProcess.start (args, streamFlags))
    {
        connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs);
        if (connection->isConnected())
        {
            sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize));
            return true;
        }
        connection = nullptr;
    }
    return false;
}

 

I reckon It should be

 

  if (connection->isConnected())
        {

            return sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize));

        }

 

Here's my scenario, I started a child process, this child process has copy protection on it that stops it from even initializing if it fails, the sendMessageToSlave was always returning true.  Which meant all the sendMessageToSlave were blocking.

 

I reckon you could simulate this by launchSlaveProcess any binary file(it doesn't need to initialize a ChildProcessSlave

 

Actually... this is better... so it can fall through and kill the connection

 

    if (childProcess.start (args))
    {
        connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs);
        if (connection->isConnected())
        {
            if (sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize)))
            {
                return true;

            }
        }

        connection = nullptr;
    }
    return false;

 

Actually, nope.. none of this works well at all... it ends up blocking somewhere, even after killing threads by force... I guess the lesson is... make sure the child process you launch initializes properly! (MacOSX)

 


#2

That change actually seems pretty sensible to me - do you mean that it's somehow more problematic than the original version?

(I guess the original one is fine, in the sense that although it won't detect an immediate problem, it'll still fail later when the slave doesn't return any pings)


#3

Hi Jules, yea its still problematic... it fails which is great, but still blocks when trying to clean up(stuck waiting on the read).  So it'll need a better workaround... Not sure its worth it, i've worked out a different solution, and I suppose it could be considered a programming error if you try to launch an invalid child process. (Assumming that's the only time it'd fail!)