-
Notifications
You must be signed in to change notification settings - Fork 36
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
Relegate the on-close for emergencies #1175
Conversation
This warning --8<---------------cut here---------------start------------->8--- warning: onCleanup: error caught while executing cleanup function: 'python_ipc_popen2_reset' undefined near line 78, column 30 "'python_ipc_popen2_reset' undefined" --8<---------------cut here---------------end--------------->8--- is caused by "pkg unload symbolic". We fix it by closing file descriptors and waitpid directly in the cleanup function instead of using private/python_ipc_popen2_reset. Fixes #1160. * inst/private/python_ipc_popen2.m: Close file descriptors and waitpid directly in the cleanup function. * inst/private/python_ipc_popen2_reset.m: Remove file.
inst/private/python_ipc_popen2.m
Outdated
then (@(varagin) ... | ||
[is_valid_file_id(fin) && fclose(fin), ... | ||
is_valid_file_id(fout) && fclose(fout)], ... | ||
@(varargin) waitpid(pid))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how big a crime is closing here without calling waitpid
? Then we would not need the then
...
Note: in the explicit reset case (and a glorious future where pkg unload
has a hook), we will have waited on pid
earlier and all of these variables will be empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't waitpid
, we'll be left with a zombie process python3 <defunct>
, because fclose (fin)
will terminate the child process (i.e. python3
). On the other hand, if we waitpid
before fclose (fin)
, it will block, because waitpid
will wait for the child process (i.e. python3
) to terminate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM!
inst/private/python_ipc_popen2.m
Outdated
fout = []; | ||
A = A && (t == 0); | ||
end | ||
emergency_cleanup = []; % note: triggers emergency file-close |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused about this line. Why do we need to "trigger emergency file-close"? IIUC we've just cleaned things up above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its going to get triggered eventually. Might as well trigger it now, when I know it is an no-op.
I guess I'm vague uncomfortable with this split: here on line 63 we close fout
, let's say its 24. My understanding of how anonymous functions work is that the onCleanup still has "24" hardcoded in it (it has no idea fout
has been replaces with []
).
Some other fopen
call later reuses 24.
Now our ticking timebomb onCleanup goes off and closes that 24. I don't know if that can really happen but the idea that it might means I don't like that onCleanup lying around. Let it go off right now while its harmless.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe I should have a comment that gives that idea: % trigger while we know it is a no-op
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, this should make things clearer
Just in case the onCleanup triggers early and they have been closed or something.
Not sure what exactly you need. But the As a side note (and I don't know if that matters here): Persistent variables are cleared whenever a function gets reparsed. There are no guarantees when that is happening (unless you |
Thanks @mmuetzel. As long as the onCleanup triggers, then I think that's fine and how we want it. The onCleanup closes the file handles. And then next symbolic command would rebuild the pipe. |
@alexvong1995 how about this?
We do the waiting and verbosity etc in the explicit reset case. Then the
onClose
stuff becomes kind of an emergency catch-all for situations (like "pkg unload"). To me, this makes it clear, that itspkg unload
's fault for not giving us a hook ;-)