Skip to content

Commit

Permalink
close and reset Python subprocess state on clear
Browse files Browse the repository at this point in the history
Move popen2 reset logic to a new helper function, and call it using a
persistent onCleanup object.

Fixes #1015.
  • Loading branch information
mtmiller committed Apr 1, 2020
1 parent aa76bba commit dfe236d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 19 deletions.
27 changes: 8 additions & 19 deletions inst/private/python_ipc_popen2.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

function [A, info] = python_ipc_popen2(what, cmd, varargin)

persistent fin fout pid
persistent cleanup fin fout pid

py_startup_timeout = 30; % seconds

Expand All @@ -43,24 +43,11 @@
info = [];

if (strcmp(what, 'reset'))
if (~isempty(pid))
if (verbose)
disp ('Closing the Python communications link.')
end
end
if (~isempty(fin))
% produces a single newline char: not sure why
t = fclose(fin); fin = [];
waitpid(pid);
pid = [];
A = (t == 0);
else
A = true;
end
if (~isempty(fout))
t = fclose(fout); fout = [];
A = A && (t == 0);
end
cleanup = [];
fin = [];
fout = [];
pid = [];
A = true;
return
end

Expand All @@ -87,6 +74,8 @@
error('popen2() failed');
end

cleanup = onCleanup (@() python_ipc_popen2_reset (fin, fout, pid));

headers = python_header();
fputs (fin, headers);
fprintf (fin, '\n\n');
Expand Down
51 changes: 51 additions & 0 deletions inst/private/python_ipc_popen2_reset.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
%% Copyright (C) 2020 Mike Miller
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published
%% by the Free Software Foundation; either version 3 of the License,
%% or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
%% the GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.
%% If not, see <http://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @deftypefun {@var{A} =} python_ipc_popen2_reset (@var{fin}, @var{fout}, @var{pid})
%% Private helper function for Python IPC.
%%
%% @var{A} is the resulting object, which might be an error code.
%% @end deftypefun

function A = python_ipc_popen2_reset (fin, fout, pid)

verbose = ~ sympref ('quiet');

if (~ isempty (pid))
if (verbose)
disp ('Closing the Python communications link.')
end
end

if (~ isempty (fin))
% produces a single newline char: not sure why
t = fclose (fin); fin = [];
waitpid (pid);
pid = [];
A = (t == 0);
else
A = true;
end

if (~ isempty (fout))
t = fclose (fout); fout = [];
A = A && (t == 0);
end

end

0 comments on commit dfe236d

Please sign in to comment.