Add a New Comment (Rich Markup)
Comment Type & Canned Response: None None > Multiple Canned Responses Fixed in development Crash with no stack trace Already fixed in newer version Fixed in stable Bad description Bad description and crash Bad stack trace Obsolete version Duplicate and not fixed Duplicate and needs more info Duplicate and fixed Need info and old
I find that some of the stuff with Windows' API is so maddening that, rather than seek understanding, I just try and get working code.
If the number of code variants is small (use WaitForInputIdle / don't use WaitForInputIdle), I'd just test them one-by-one and see if it works.
It also seems strange to me that the octave_popen2 function for Windows calls CloseHandle on the process handle and then returns. Is it really OK to do that before the child process exits?
Looking at the documentation for CreateProcess:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx
it seems like maybe we should be calling WaitForInputIdle on the created process, but the documentation for that function:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687022%28v=vs.85%29.aspx
says "If this process is a console application or does not have a message queue, WaitForInputIdle returns immediately."
Hmm.
If I don't write anything to the input side of the pipe, but instead read from the output, then it returns -1. This seems to set the EOF on the pipe because if I then write to the input side the output always returns -1.
It seems that this sequence is required
1) popen2() 2) write to input 3) flush input or close input 4) pause 5) read from output
If you never write to the input side of the pipe, does the output descriptor ever return EAGAIN (with sufficient pausing)? In other words, is it possible we could insert a delay inside popen2 to ensure that the output descriptor is "valid" after calling CreateProcess but before returning control to the caller?
There is example code in the docstring for popen2. The code is
[in, out, pid] = popen2 ("sort", "-r"); fputs (in, "these\nare\nsome\nstrings\n"); fclose (in); EAGAIN = errno ("EAGAIN"); done = false; do s = fgets (out); if (ischar (s)) fputs (stdout, s); elseif (errno () == EAGAIN) pause (0.1); fclear (out); else done = true; endif until (done) fclose (out); waitpid (pid);
This works correctly on Linux, but fails on Windows. The problem is that the initial call to fgets (out) returns -1 (EOF) immediately. I can get the code to work by adding a small delay before starting the do loop.
This works
[in, out, pid] = popen2 ("sort", "-r"); fputs (in, "these\nare\nsome\nstrings\n"); fclose (in); EAGAIN = errno ("EAGAIN"); done = false; pause (0.05); # 50 millisecond pause do s = fgets (out); if (ischar (s)) fputs (stdout, s); elseif (errno () == EAGAIN) pause (0.1); fclear (out); else done = true; endif until (done) fclose (out); waitpid (pid);
I tried using fflush (in) before fclose, but that didn't help. The problem is either in the popen2 call, which is Windows specific and located in liboctave/system/lo-sysdep.cc. Or Windows itself has problems with concurrency.
I've attached the test code to this bug report.
(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)
Attach Files: Comment:
Depends on the following items: None found
Items that depend on this one: None found
There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.
Only project members can vote.
Please enter the title of George Orwell's famous dystopian book (it's a date):
Follow 3 latest changes.
Copyright © 2023 Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. The Levitating, Meditating, Flute-playing Gnu logo is a GNU GPL'ed image provided by the Nevrax Design Team. Source Code
Powered by Savane 3.9