octave-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Octave-bug-tracker] [bug #52084] pause() fails after an async system ca


From: Dan Sebald
Subject: [Octave-bug-tracker] [bug #52084] pause() fails after an async system call
Date: Fri, 22 Sep 2017 00:20:57 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0

Follow-up Comment #1, bug #52084 (project octave):

** There's a zombie-like process bug which I will point out at the end of this
post.

Interesting find.  A little simpler way of illustrating is to do


system('ls',0,'async');
% Carriage return
pause(1);


as individual lines and as selecting the two and pasting--or use a function as
follows:


function myfunc1()
  system('ls',0,'async');
  pause(1);
end
% No pause
myfunc1();


versus


function myfunc()
  system('ls');
  pause(1);
end
% Pause
myfunc2();


Perhaps this isn't as strange as it first appears.  The two routines, system()
and pause(), both ultimately go back to system functions.

system() with the 'async' option calls this functin:

pid_t
octave_async_system_wrapper (const char *cmd)
{
  int retval = -1;

  if (! cmd)
    return retval;

#if defined (OCTAVE_USE_WINDOWS_API)

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  ZeroMemory (&si, sizeof (si));
  ZeroMemory (&pi, sizeof (pi));

  char *xcmd = (char *) malloc (strlen (cmd) + 1);

  strcpy (xcmd, cmd);

  if (! CreateProcess (0, xcmd, 0, 0, FALSE, 0, 0, 0, &si, &pi))
    retval = -1;
  else
    {
      retval = pi.dwProcessId;

      CloseHandle (pi.hProcess);
      CloseHandle (pi.hThread);
    }

  free (xcmd);

#else

  pid_t pid = fork ();

  if (pid == 0)
    execl (SHELL_PATH, "sh", "-c", cmd, (char *) (0));
  else
    retval = pid;

#endif

  return retval;
}


pause() calls this function:

int
octave_nanosleep_wrapper (const struct timespec *requested,
                          struct timespec *remaining)
{
  return nanosleep (requested, remaining);
}


where nanosleep() is in <time.h>.

There are a couple plausible routes of investigations.  I'm imagining somehow
the end of the asynchronous process is triggering an end to the nanosleep.  Is
there something that is being sent back to Octave when the system() command
completes that would wake the Octave process from sleep?  Doesn't seem like it
because the async system route forks a process to do the system command, and
the execl() command would only know the forked process ID not the original
Octave process ID.  Is it possible that the pause() is getting placed in the
forked process rather than in the Octave process?

Looking at the octave_async_system_wrapper() construct after the fork,
something seems strange.  There is a "retval = pid" in the case of the
original Octave process, i.e., pid != 0.  In the case of the forked process
(pid = 0), there is a return value of -1 sent back.  But where that is going
to, I don't know, because the calling function just returns the return value
of octave_async_system_wrapper().  It seems to me that the forked process
should execute the system command and then simply quit.  
Otherwise, it's a zombie process.  Call


myfunc1()
myfunc1()
myfunc1()
...
myfunc1()


twenty or thirty times then look at the list of system processes and one will
see a list of twenty "sh" processes.  Well, technically they aren't zombie
processes because if I exit Octave, all the "sh" processes terminate along
with it rather than hanging around.  But still, I'm wondering if something
should be fixed there as well.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?52084>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]