-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't access retrievedStdout/retrievedStderr #29
Comments
Hi @martinmcclure Is it clear? If not, show me how you had to subclass OSSUnixSubprocess so that I understand better. |
Well, Which is the subject of this bug report. My current subclass just adds accessors like this one: |
OK, I understand now. I guess the main reason is because its most used sender is OK, I agree with your change but i would do a normal accessor that answers the stream and not the |
What I'd originally done was use So I then switched to forking a new Smalltalk Process to do the And now that I'm using that kind of approach, I think that You could add on the accessors as I've done (or straight accessors for the streams, as you suggest) but I no longer think that's the best solution. |
In the end, I get the method below. Does this look like correct/best usage of OSSUnixSubprocess? Thanks for your patience with the OSSubprocess newbie. :-)
|
That looks good. I am not sure why the need of the fork and semaphore.
Can't you run, then write to stdin, then poll and wait retrieving until the
end? I can give a try later.. From my phone now
…On Feb 24, 2018 4:16 PM, "martinmcclure" ***@***.***> wrote:
In the end, I get the method below. Does this look like correct/best usage
of OSSUnixSubprocess? Thanks for your patience with the OSSubprocess
newbie. :-)
run: executablePath
withArguments: argArray
stdin: inputString
expectingStdout: expectedStdOut
expectingStderr: expectedStdErr
expectingExitStatus: expectedExitStatus
"Does not change the current working directory, or the environment."
| process exitedSemaphore actualStdout actualStderr |
exitedSemaphore := Semaphore new.
process := OSSUnixSubprocess new
command: executablePath;
arguments: argArray;
redirectStdin;
redirectStdout;
redirectStderr;
yourself.
[ process
runAndWaitPollingEvery: (Delay forMilliseconds: 50)
retrievingStreams: true
onExitDo: [ :p :stdout :stderr |
actualStdout := stdout.
actualStderr := stderr.
exitedSemaphore signal ] ] forkAt: Processor activeProcess priority + 1.
process stdinStream
nextPutAll: inputString;
close.
exitedSemaphore wait.
self
assert: actualStdout equals: expectedStdOut;
assert: actualStderr equals: expectedStdErr;
assert: process exitStatusInterpreter exitStatus equals: expectedExitStatus
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#29 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AA_Cgiko6iu0S99z5rTu8D24QSAVM8haks5tYGAggaJpZM4SRtux>
.
|
The fork is an attempt to avoid deadlock. It is necessary with large strings (>1MB or so) but, it turns out, not sufficient. If I invoke my test method with this kind of simple but large test:
Then it deadlocks because I'm attempting to dump all of the characters into cat's stdin all at once, and the pipe is blocking, so each character I send is sent back from cat, but I only poll every 50ms, and if cat's write pipe blocks because I haven't read from it yet, and I keep sending characters and cat isn't reading them because it's blocked on write, then the VM blocks on write: Deadlock. So what I have to do is to send a little, read a little, send a little, read a little... until done. The code below (getting complicated) seems to work. I don't immediately see a simpler way to do it (maybe after you have threaded FFI callouts...).
|
...actually, this solution works for cat, where the number of characters on stdin and stdout is the same, but what if you had a program "cat5000" that output 5000 characters for every character on stdin? My code would still lock up the VM. One good answer would be to use a non-blocking pipe for the stdin, and when you get an EWOULDBLOCK stop writing but block the Smalltalk Process that is trying to do the write on a Smalltalk semaphore. Then add the file descriptor to the VM's list of descriptors being monitored via poll() or select() so it can signal the semaphore when it's ready to accept more characters. And a similar strategy for stdout and stderr -- you can have a Smalltalk Process for each, and you don't have to poll at the Smalltalk level. I don't know whether the VM offers support for such a thing, but it would be useful if it did. |
Nice experiment from you. As you realized, I do have support for " that output 5000 characters for every character on stdin? My code would still lock up the VM" Its not clear to me it would lock the VM. In that case maybe putting a smaller timeout for retrieving from the out streams would help? About EWOULDBLOCK, I do have support for putting a semaphore for a given signal. I am using a OSProcess (yes, OSProcess) primitive for this, but it's ok for now. See implementors and senders of BTW, @guillep may also have some ideas as he has been doing a lot of stress tests recently... Let me know what do you think, |
Hi @marianopeck With this kind of approach, there would be a separate semaphore for each non-blocking pipe. You'd read (or write, depending on which end of the pipe you had) through a primitive that basically calls the OS read() or write() function. If the result was EWOULDBLOCK, you'd wait on the semaphore for that pipe. The VM would then signal the semaphore when data could once again be read (or written). |
Hi @martinmcclure |
Could you please take a look to this conversation? pharo-project/pharo-vm#142 (comment) Do you see any relation with what @zecke is saying? Cheers, |
@marianopeck |
#waitForExitPollingEvery: aDelay retrievingStreams: true
seems less useful than it could be due to having no way (that I can see) to access the retrieved output and error streams' contents.
The use case is for testing -- to fork a subprocess, write something to its stdin, wait for it to exit, then check its outputs and exit status for expected values.
For now I've subclassed OSSUnixSubprocess to give myself access. Please let me know if there's a better way to do this.
The text was updated successfully, but these errors were encountered: