summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/sigproc.h
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-03-16 20:20:29 +0000
committerChristopher Faylor <me@cgf.cx>2012-03-16 20:20:29 +0000
commit4aeaedf961029e38cd9c97ac1e32ba91406c9e23 (patch)
tree88371461329ddcd2c9eac8659dd5d2763da82330 /winsup/cygwin/sigproc.h
parentd3f6480e44081964526de50792c6d28ca2d24580 (diff)
downloadcygnal-4aeaedf961029e38cd9c97ac1e32ba91406c9e23.tar.gz
cygnal-4aeaedf961029e38cd9c97ac1e32ba91406c9e23.tar.bz2
cygnal-4aeaedf961029e38cd9c97ac1e32ba91406c9e23.zip
* fork.cc (lock_signals): Move to sigproc.h.
(lock_pthread): Ditto. (hold_everything): Ditto. (frok::parent): Call myself.prefork() just before calling CreateProcess. Call myself.postfork () on function exit. * pinfo.cc (pinfo::pending_rd_proc_pipe): Define. (pinfo::pending_wr_proc_pipe): Ditto. (_pinfo::dup_proc_pipe): Delete. (pinfo::wait): Move pipe creation into pinfo::prefork. Set pipe variables from pending_*. (_pinfo::sync_proc_pipe): Delete. (_pinfo::proc_pipe_owner): Ditto. (pinfo::prefork): Define new function. (pinfo::postfork): Ditto. (pinfo::postexec): Ditto. (_pinfo::alert_parent): Remove obsolete call to sync_proc_pipe. (_pinfo::dup_proc_pipe): Delete declaration. (_pinfo::sync_proc_pipe): Ditto. (pinfo::pending_rd_proc_pipe): Declare. (pinfo::pending_wr_proc_pipe): Ditto. (pinfo::prefork): Declare new function. (pinfo::postfork): Ditto. (pinfo::postexec): Ditto. (pinfo::wr_proc_pipe): Define new wrapper function. * sigproc.h: Include "sync.h". Move locking functions from fork to here. * spawn.cc (child_info_spawn::worker): Delete now-unneeded requirement to record orig_wr_proc_pipe. Call hold_everything prior to doing anything. Call myself.prefork() if spawning. Replace wr_proc_pipe synchronization with call to myself.postexec(). Call myself.postfork() if not execing. * sync.h: Replace #ifdef wrapper with "#pragma once".
Diffstat (limited to 'winsup/cygwin/sigproc.h')
-rw-r--r--winsup/cygwin/sigproc.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 2900da4cc..ffe75a8d3 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -11,6 +11,7 @@ details. */
#pragma once
#include <signal.h>
+#include "sync.h"
#ifdef NSIG
enum
@@ -121,4 +122,81 @@ extern char myself_nowait_dummy[];
extern struct sigaction *global_sigs;
+class lock_signals
+{
+ bool worked;
+public:
+ lock_signals ()
+ {
+ worked = sig_send (NULL, __SIGHOLD) == 0;
+ }
+ operator int () const
+ {
+ return worked;
+ }
+ void dont_bother ()
+ {
+ worked = false;
+ }
+ ~lock_signals ()
+ {
+ if (worked)
+ sig_send (NULL, __SIGNOHOLD);
+ }
+};
+
+class lock_pthread
+{
+ bool bother;
+public:
+ lock_pthread (): bother (1)
+ {
+ pthread::atforkprepare ();
+ }
+ void dont_bother ()
+ {
+ bother = false;
+ }
+ ~lock_pthread ()
+ {
+ if (bother)
+ pthread::atforkparent ();
+ }
+};
+
+class hold_everything
+{
+public: /* DELETEME*/
+ bool ischild;
+ /* Note the order of the locks below. It is important,
+ to avoid races, that the lock order be preserved.
+
+ pthread is first because it serves as a master lock
+ against other forks being attempted while this one is active.
+
+ signals is next to stop signal processing for the duration
+ of the fork.
+
+ process is last. If it is put before signals, then a deadlock
+ could be introduced if the process attempts to exit due to a signal. */
+ lock_pthread pthread;
+ lock_signals signals;
+ lock_process process;
+
+public:
+ hold_everything (bool x = false): ischild (x) {}
+ operator int () const {return signals;}
+
+ ~hold_everything()
+ {
+ if (ischild)
+ {
+ pthread.dont_bother ();
+ process.dont_bother ();
+ signals.dont_bother ();
+ }
+ }
+
+};
+
#define myself_nowait ((_pinfo *) myself_nowait_dummy)