Mercurial > octave
changeset 22049:ccf50f029999
move octave_child_list to separate file and define inside namespace
* liboctave/system/child-list.cc, liboctave/system/child-list.h:
New files.
* liboctave/system/module.mk: Update.
* sighandlers.h, sighandlers.cc: Move octave_child and
octave_child_list classes to separate files in liboctave and defined
inside the octave namespace. Change all uses.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Jul 2016 14:57:54 -0400 |
parents | 1a8e2a0251c3 |
children | eb751495ba43 |
files | libinterp/corefcn/pager.cc libinterp/corefcn/sighandlers.cc libinterp/corefcn/sighandlers.h libinterp/corefcn/toplev.cc libinterp/octave.cc liboctave/system/child-list.cc liboctave/system/child-list.h liboctave/system/module.mk |
diffstat | 8 files changed, 312 insertions(+), 230 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/pager.cc Wed Jul 06 03:29:33 2016 -0500 +++ b/libinterp/corefcn/pager.cc Wed Jul 06 14:57:54 2016 -0400 @@ -95,7 +95,7 @@ { if (external_pager) { - octave_child_list::remove (external_pager->pid ()); + octave::child_list::remove (external_pager->pid ()); delete external_pager; external_pager = 0; @@ -161,8 +161,8 @@ external_pager = new oprocstream (pgr.c_str ()); if (external_pager) - octave_child_list::insert (external_pager->pid (), - pager_event_handler); + octave::child_list::insert (external_pager->pid (), + pager_event_handler); } }
--- a/libinterp/corefcn/sighandlers.cc Wed Jul 06 03:29:33 2016 -0500 +++ b/libinterp/corefcn/sighandlers.cc Wed Jul 06 14:57:54 2016 -0400 @@ -247,13 +247,13 @@ void *context = octave_block_child (); - octave_child_list::wait (); + octave::child_list::wait (); octave_set_interrupt_handler (saved_interrupt_handler); octave_unblock_child (context); - octave_child_list::reap (); + octave::child_list::reap (); } else if (have_sigfpe && i == sigfpe) std::cerr << "warning: floating point exception" << std::endl; @@ -644,136 +644,6 @@ return m; } -octave_child_list::octave_child_list_rep *octave_child_list::instance = 0; - -bool -octave_child_list::instance_ok (void) -{ - bool retval = true; - - if (! instance) - { - instance = new octave_child_list_rep (); - - if (instance) - singleton_cleanup_list::add (cleanup_instance); - } - - if (! instance) - error ("unable to create child list object!"); - - return retval; -} - -void -octave_child_list::insert (pid_t pid, octave_child::child_event_handler f) -{ - if (instance_ok ()) - instance->insert (pid, f); -} - -void -octave_child_list::reap (void) -{ - if (instance_ok ()) - instance->reap (); -} - -bool -octave_child_list::wait (void) -{ - return (instance_ok ()) ? instance->wait () : false; -} - -class pid_equal -{ -public: - - pid_equal (pid_t v) : val (v) { } - - bool operator () (const octave_child& oc) const { return oc.pid == val; } - -private: - - pid_t val; -}; - -void -octave_child_list::remove (pid_t pid) -{ - if (instance_ok ()) - instance->remove_if (pid_equal (pid)); -} - -#define OCL_REP octave_child_list::octave_child_list_rep - -void -OCL_REP::insert (pid_t pid, octave_child::child_event_handler f) -{ - append (octave_child (pid, f)); -} - -void -OCL_REP::reap (void) -{ - // Mark the record for PID invalid. - - for (iterator p = begin (); p != end (); p++) - { - // The call to the octave_child::child_event_handler might - // invalidate the iterator (for example, by calling - // octave_child_list::remove), so we increment the iterator - // here. - - octave_child& oc = *p; - - if (oc.have_status) - { - oc.have_status = 0; - - octave_child::child_event_handler f = oc.handler; - - if (f && f (oc.pid, oc.status)) - oc.pid = -1; - } - } - - remove_if (pid_equal (-1)); -} - -// Wait on our children and record any changes in their status. - -bool -OCL_REP::wait (void) -{ - bool retval = false; - - for (iterator p = begin (); p != end (); p++) - { - octave_child& oc = *p; - - pid_t pid = oc.pid; - - if (pid > 0) - { - int status; - - if (octave::sys::waitpid (pid, &status, octave::sys::wnohang ()) > 0) - { - oc.have_status = 1; - - oc.status = status; - - retval = true; - - break; - } - } - } - - return retval; -} - DEFUN (SIG, args, , doc: /* -*- texinfo -*- @deftypefn {} {} SIG ()
--- a/libinterp/corefcn/sighandlers.h Wed Jul 06 03:29:33 2016 -0500 +++ b/libinterp/corefcn/sighandlers.h Wed Jul 06 14:57:54 2016 -0400 @@ -35,12 +35,12 @@ #include "octave-config.h" -#include "signal-wrappers.h" - -#include "base-list.h" +#include "child-list.h" // FIXME: the data should probably be private... +typedef void octave_sig_handler (int); + struct octave_interrupt_handler { @@ -77,97 +77,6 @@ // extern void ignore_sigchld (void); -// Maybe this should be in a separate file? - -class -OCTINTERP_API -octave_child -{ -public: - - // Do whatever to handle event for child with PID (might not - // actually be dead, could just be stopped). Return true if - // the list element corresponding to PID should be removed from - // list. This function should not call any functions that modify - // the octave_child_list. - - typedef bool (*child_event_handler) (pid_t, int); - - octave_child (pid_t id = -1, child_event_handler f = 0) - : pid (id), handler (f), have_status (0), status (0) { } - - octave_child (const octave_child& oc) - : pid (oc.pid), handler (oc.handler), - have_status (oc.have_status), status (oc.status) { } - - octave_child& operator = (const octave_child& oc) - { - if (&oc != this) - { - pid = oc.pid; - handler = oc.handler; - have_status = oc.have_status; - status = oc.status; - } - return *this; - } - - ~octave_child (void) { } - - // The process id of this child. - pid_t pid; - - // The function we call if an event happens for this child. - child_event_handler handler; - - // Nonzero if this child has stopped or terminated. - sig_atomic_t have_status; - - // The status of this child; 0 if running, otherwise a status value - // from waitpid. - int status; -}; - -class -OCTINTERP_API -octave_child_list -{ -protected: - - octave_child_list (void) { } - - class octave_child_list_rep : public octave_base_list<octave_child> - { - public: - - void insert (pid_t pid, octave_child::child_event_handler f); - - void reap (void); - - bool wait (void); - }; - -public: - - ~octave_child_list (void) { } - - static void insert (pid_t pid, octave_child::child_event_handler f); - - static void reap (void); - - static bool wait (void); - - static void remove (pid_t pid); - -private: - - static bool instance_ok (void); - - static octave_child_list_rep *instance; - - static void cleanup_instance (void) { delete instance; instance = 0; } -}; - // TRUE means we should try to enter the debugger on SIGINT. extern OCTINTERP_API bool Vdebug_on_interrupt;
--- a/libinterp/corefcn/toplev.cc Wed Jul 06 03:29:33 2016 -0500 +++ b/libinterp/corefcn/toplev.cc Wed Jul 06 14:57:54 2016 -0400 @@ -50,6 +50,7 @@ #include "oct-locbuf.h" #include "oct-syscalls.h" #include "quit.h" +#include "signal-wrappers.h" #include "singleton-cleanup.h" #include "str-vec.h" #include "wait-for-input.h" @@ -1005,7 +1006,7 @@ iprocstream *cmd = new iprocstream (cmd_str.c_str ()); frame.add_delete (cmd); - frame.add_fcn (octave_child_list::remove, cmd->pid ()); + frame.add_fcn (octave::child_list::remove, cmd->pid ()); if (! *cmd) error ("system: unable to start subprocess for '%s'", cmd_str.c_str ());
--- a/libinterp/octave.cc Wed Jul 06 03:29:33 2016 -0500 +++ b/libinterp/octave.cc Wed Jul 06 14:57:54 2016 -0400 @@ -43,6 +43,7 @@ #include "lo-error.h" #include "oct-env.h" #include "str-vec.h" +#include "signal-wrappers.h" #include "unistd-wrappers.h" #include "build-env.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/system/child-list.cc Wed Jul 06 14:57:54 2016 -0400 @@ -0,0 +1,163 @@ +/* + +Copyright (C) 1993-2015 John W. Eaton + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include "child-list.h" +#include "lo-error.h" +#include "oct-syscalls.h" +#include "signal-wrappers.h" +#include "singleton-cleanup.h" + +namespace octave +{ + child_list::child_list_rep *child_list::instance = 0; + + bool + child_list::instance_ok (void) + { + bool retval = true; + + if (! instance) + { + instance = new child_list_rep (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); + } + + if (! instance) + (*current_liboctave_error_handler) + ("unable to create child list object!"); + + return retval; + } + + void + child_list::insert (pid_t pid, child::child_event_handler f) + { + if (instance_ok ()) + instance->insert (pid, f); + } + + void + child_list::reap (void) + { + if (instance_ok ()) + instance->reap (); + } + + bool + child_list::wait (void) + { + return (instance_ok ()) ? instance->wait () : false; + } + + class pid_equal + { + public: + + pid_equal (pid_t v) : val (v) { } + + bool operator () (const child& oc) const { return oc.pid == val; } + + private: + + pid_t val; + }; + + void + child_list::remove (pid_t pid) + { + if (instance_ok ()) + instance->remove_if (pid_equal (pid)); + } + + void + child_list::child_list_rep::insert (pid_t pid, child::child_event_handler f) + { + append (child (pid, f)); + } + + void + child_list::child_list_rep::reap (void) + { + // Mark the record for PID invalid. + + for (iterator p = begin (); p != end (); p++) + { + // The call to the child::child_event_handler might + // invalidate the iterator (for example, by calling + // child_list::remove), so we increment the iterator + // here. + + child& oc = *p; + + if (oc.have_status) + { + oc.have_status = 0; + + child::child_event_handler f = oc.handler; + + if (f && f (oc.pid, oc.status)) + oc.pid = -1; + } + } + + remove_if (pid_equal (-1)); + } + + // Wait on our children and record any changes in their status. + + bool + child_list::child_list_rep::wait (void) + { + bool retval = false; + + for (iterator p = begin (); p != end (); p++) + { + child& oc = *p; + + pid_t pid = oc.pid; + + if (pid > 0) + { + int status; + + if (octave::sys::waitpid (pid, &status, octave::sys::wnohang ()) > 0) + { + oc.have_status = 1; + + oc.status = status; + + retval = true; + + break; + } + } + } + + return retval; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/system/child-list.h Wed Jul 06 14:57:54 2016 -0400 @@ -0,0 +1,136 @@ +/* + +Copyright (C) 1993-2015 John W. Eaton + +This file is part of Octave. + +Octave 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. + +Octave 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 Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if ! defined (octave_child_list_h) +#define octave_child_list_h 1 + +#include "octave-config.h" + +#include <csignal> + +#include <sys/types.h> + +#include "base-list.h" + +namespace octave +{ + class + OCTAVE_API + child + { + public: + + // Do whatever to handle event for child with PID (might not + // actually be dead, could just be stopped). Return true if + // the list element corresponding to PID should be removed from + // list. This function should not call any functions that modify + // the child_list. + + typedef bool (*child_event_handler) (pid_t, int); + + child (pid_t id = -1, child_event_handler f = 0) + : pid (id), handler (f), have_status (0), status (0) { } + + child (const child& oc) + : pid (oc.pid), handler (oc.handler), + have_status (oc.have_status), status (oc.status) { } + + child& operator = (const child& oc) + { + if (&oc != this) + { + pid = oc.pid; + handler = oc.handler; + have_status = oc.have_status; + status = oc.status; + } + return *this; + } + + ~child (void) { } + + // The process id of this child. + pid_t pid; + + // The function we call if an event happens for this child. + child_event_handler handler; + + // Nonzero if this child has stopped or terminated. + sig_atomic_t have_status; + + // The status of this child; 0 if running, otherwise a status value + // from waitpid. + int status; + }; + + class + OCTAVE_API + child_list + { + protected: + + child_list (void) { } + + class child_list_rep : public octave_base_list<child> + { + public: + + void insert (pid_t pid, child::child_event_handler f); + + void reap (void); + + bool wait (void); + }; + + public: + + ~child_list (void) { } + + static void insert (pid_t pid, child::child_event_handler f); + + static void reap (void); + + static bool wait (void); + + static void remove (pid_t pid); + + private: + + static bool instance_ok (void); + + static child_list_rep *instance; + + static void cleanup_instance (void) { delete instance; instance = 0; } + }; +} + +#if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS) + +OCTAVE_DEPRECATED ("use 'octave::child' instead") +typedef octave::child octave_child; + +OCTAVE_DEPRECATED ("use 'octave::child_list' instead") +typedef octave::child_list octave_child_list; + +#endif + +#endif
--- a/liboctave/system/module.mk Wed Jul 06 03:29:33 2016 -0500 +++ b/liboctave/system/module.mk Wed Jul 06 14:57:54 2016 -0400 @@ -1,4 +1,5 @@ SYSTEM_INC = \ + liboctave/system/child-list.h \ liboctave/system/dir-ops.h \ liboctave/system/file-ops.h \ liboctave/system/file-stat.h \ @@ -12,6 +13,7 @@ liboctave/system/oct-uname.h SYSTEM_SRC = \ + liboctave/system/child-list.cc \ liboctave/system/dir-ops.cc \ liboctave/system/file-ops.cc \ liboctave/system/file-stat.cc \