ChildProcess on Windows problem, possible fix


#1

I was baffled for hours trying to fix a bug where running a program with ChildProcess did not succeed. I think I finally traced the problem to :

if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0)

in juce_win32_Threads.cpp. Changing that line to :


if (CreatePipe (&readPipe, &writePipe, &securityAtts, 65536)

allows the certain problematic program to run until its end. So, it looks like the 0 for a "system preferred" buffer size will not in all cases succeed. Obviously putting in such a magic number (65536) raises questions whether even that is enough for all cases or what if it needlessly wastes system resources when a buffer that large isn't required etc...

edit : I didn't yet check if doing readProcessOutput() several times during the program run would help when the pipe buffer size is at creation is 0, but even if it did, that would be slightly inconvenient as I am not interested in the output when the program does a succesful run. (And it is in that case it does the very verbose output.) Only if there's an error, I do a readAllProcessOutput() call.


#2

Interesting. But what exactly was the problem that you were hitting? Was it just that you were writing more data than the size of the pipe's buffer, causing the process to block until the other end read the data? If so, then this wouldn't actually fix that problem, it'd just make it less likely to happen - no matter how big your buffer is you'd run the risk of overflowing it if the receiver is unresponsive.


#3

The problem was that the program to be run would just block. The actual problem is of course with the external program spitting so much verbose output(*) while it's doing a succesful run, but that is kind of out my control at the moment. (The set of programs I run are now open source, but getting their source code to build and fixing any bugs/quirks is kind of an external concern at the moment that I wouldn't want to go into.)

So what I am doing in the code for simplicity and clarity at the moment is just (together with the change in the Juce ChildProcess code) :

proc.start(procargs);
proc.waitForProcessToFinish(15000);
if (proc.getExitCode()==0)
{
  ...finishing up stuff...
} else 
{
  ... use proc.readAllProcessOutput() to display error message
}

Luckily at least the time out value works, so if the external process blocks, my Juce code will eventually get back running again. (I know, I know, I shouldn't block the GUI thread like that, but the external programs usually run so quickly it isn't generally a major issue at the moment.)

(*) The actual desired output of the program is an audio file, not what it puts into the standard output as text.