Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/debug.cc11
-rw-r--r--winsup/cygwin/debug.h1
-rw-r--r--winsup/cygwin/exceptions.cc30
-rw-r--r--winsup/cygwin/fhandler_console.cc3
-rw-r--r--winsup/cygwin/sigproc.cc23
-rw-r--r--winsup/cygwin/sigproc.h3
-rw-r--r--winsup/cygwin/sync.cc2
-rw-r--r--winsup/cygwin/sync.h1
9 files changed, 65 insertions, 26 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 03e7ccccc..bfa930b21 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,6 +1,17 @@
-Wed Feb 23 22:51:27 2000 Christopher Faylor <cgf@cygnus.com>
+Thu Feb 24 00:59:15 2000 Christopher Faylor <cgf@cygnus.com>
Fix final round of gcc warnings relating to unused parameters.
+ * debug.cc (iscygthread): New function.
+ * debug.h: Declare it.
+ * exceptions.cc (set_process_mask): Flush pending signals.
+ (handle_sigsuspend): No need to flush pending signals.
+ (call_handler): Refine previous tests of muto ownership. Only clear
+ wait()'s when we have definitely responded to a signal.
+ * fhandler_console.cc (fhandler_console::read): Don't set EINTR if
+ executing in a "cygwin" thread.
+ * sigproc.cc (proc_subproc): Use second argument to control whether
+ CLEARWAIT actually sets "signalled" flag.
+ * sync.h (muto): Add 'unstable' method.
Wed Feb 23 21:59:44 2000 Christopher Faylor <cgf@cygnus.com>
@@ -10,7 +21,7 @@ Wed Feb 23 21:34:58 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (interruptible): Change method for determining if
something is interruptible.
- (call_handler): Avoid suspending a thread if it owns a mutex. Only set
+ (call_handler): Avoid suspending a thread if it owns a muto. Only set
signal_arrived if the thread was actually interrupted.
(events_init): Initialize module information needed by interruptible().
(sigdelayed): Don't call sig_dispatch_pending since it could screw up
@@ -20,8 +31,6 @@ Wed Feb 23 21:34:58 2000 Christopher Faylor <cgf@cygnus.com>
bulk of the processing comes from the signal thread.
(wait_sig): Force processing of waiting threads if SIGCHLD is not
processed.
- * sync.cc (muto::release): Set tid == 0 after lock is released or
- signal processor will be confused.
Tue Feb 22 23:06:01 2000 Christopher Faylor <cgf@cygnus.com>
diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc
index 077ccf088..6218312fe 100644
--- a/winsup/cygwin/debug.cc
+++ b/winsup/cygwin/debug.cc
@@ -47,6 +47,17 @@ regthread (const char *name, DWORD tid)
unlock_threadname ();
}
+int __stdcall
+iscygthread()
+{
+ DWORD tid = GetCurrentThreadId ();
+ if (tid != maintid)
+ for (DWORD i = 0; i < NTHREADS && threads[i].name != NULL; i++)
+ if (threads[i].id == tid)
+ return 1;
+ return 0;
+}
+
struct thread_start
{
LONG notavail;
diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h
index c8e28ba64..d57ea4d0e 100644
--- a/winsup/cygwin/debug.h
+++ b/winsup/cygwin/debug.h
@@ -30,6 +30,7 @@ void threadname_init ();
HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *);
const char * __stdcall threadname (DWORD, int lockit = TRUE);
void __stdcall regthread (const char *, DWORD);
+int __stdcall iscygthread ();
#ifndef DEBUGGING
# define ForceCloseHandle CloseHandle
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 4f2aa15c3..4176f66cc 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -598,7 +598,6 @@ handle_sigsuspend (sigset_t tempmask)
// interested in through.
sigproc_printf ("old mask %x, new mask %x", oldmask, tempmask);
- sig_dispatch_pending (0);
WaitForSingleObject (signal_arrived, INFINITE);
set_sig_errno (EINTR); // Per POSIX
@@ -705,6 +704,7 @@ set_sig_errno (int e)
{
set_errno (e);
sigsave.saved_errno = e;
+ debug_printf ("errno %d", e);
}
static int
@@ -738,21 +738,21 @@ call_handler (int sig, struct sigaction& siga, void *handler)
for (;;)
{
res = SuspendThread (hth);
- /* FIXME: Make multi-thread aware */
- if (sync_proc_subproc->owner () != maintid && mask_sync->owner () != maintid)
- break;
if (res)
goto set_pending;
+
+ /* FIXME: Make multi-thread aware */
+ if (!sync_proc_subproc->unstable () && sync_proc_subproc->owner () != maintid &&
+ !mask_sync->unstable () && mask_sync->owner () != maintid)
+ break;
+
ResumeThread (hth);
Sleep (0);
}
sigproc_printf ("suspend said %d, %E", res);
- /* Clear any waiting threads prior to dispatching to handler function */
- proc_subproc(PROC_CLEARWAIT, 0);
-
if (sigsave.cx)
{
cx = sigsave.cx;
@@ -782,8 +782,15 @@ call_handler (int sig, struct sigaction& siga, void *handler)
}
(void) ResumeThread (hth);
+
if (interrupted)
- (void) SetEvent (signal_arrived); // For an EINTR case
+ {
+ /* Clear any waiting threads prior to dispatching to handler function */
+ proc_subproc(PROC_CLEARWAIT, 1);
+ /* Apparently we have to set signal_arrived after resuming the thread or it
+ is possible that the event will be ignored. */
+ (void) SetEvent (signal_arrived); // For an EINTR case
+ }
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
out:
@@ -840,11 +847,16 @@ ctrl_c_handler (DWORD type)
extern "C" void __stdcall
set_process_mask (sigset_t newmask)
{
+ extern DWORD sigtid;
+
mask_sync->acquire (INFINITE);
+ sigset_t oldmask = myself->getsigmask ();
newmask &= ~SIG_NONMASKABLE;
sigproc_printf ("old mask = %x, new mask = %x", myself->getsigmask (), newmask);
myself->setsigmask (newmask); // Set a new mask
mask_sync->release ();
+ if (oldmask != newmask && GetCurrentThreadId () != sigtid)
+ sig_dispatch_pending ();
return;
}
@@ -1076,7 +1088,7 @@ _sigreturn:
addl $4,%%esp
call _set_process_mask@4
popl %%eax # saved errno
- testl %%eax,%%eax # lt 0
+ testl %%eax,%%eax # Is it < 0
jl 1f # yup. ignore it
movl %1,%%ebx
movl %%eax,(%%ebx)
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 40e2954ee..67732ba1c 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -151,7 +151,8 @@ fhandler_console::read (void *pv, size_t buflen)
case WAIT_OBJECT_0:
break;
case WAIT_OBJECT_0 + 1:
- set_sig_errno (EINTR);
+ if (!iscygthread ())
+ set_sig_errno (EINTR);
return -1;
default:
__seterrno ();
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 5efd067d6..7c1f449ed 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -102,7 +102,7 @@ muto NO_COPY *sync_proc_subproc = NULL; // Control access to
// subproc stuff
DWORD NO_COPY maintid = 0; // ID of the main thread
-Static DWORD sigtid = 0; // ID of the signal thread
+DWORD NO_COPY sigtid = 0; // ID of the signal thread
int NO_COPY pending_signals = 0; // TRUE if signals pending
@@ -245,7 +245,7 @@ proc_subproc (DWORD what, DWORD val)
int potential_match;
DWORD exitcode;
pinfo *child;
- int clearing = 0;
+ int clearing;
waitq *w;
#define wval ((waitq *) val)
@@ -316,7 +316,7 @@ proc_subproc (DWORD what, DWORD val)
/* Send a SIGCHLD to myself. */
rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
- break; // Don't try to unlock. We don't have a lock.
+ break;
/* A child is in the stopped state. Scan wait() queue to see if anyone
* should be notified. (Called from wait_sig thread)
@@ -324,6 +324,7 @@ proc_subproc (DWORD what, DWORD val)
case PROC_CHILDSTOPPED:
child = myself; // Just to avoid accidental NULL dereference
sip_printf ("Received stopped notification");
+ clearing = 0;
goto scan_wait;
/* Clear all waiting threads. Called from exceptions.cc prior to
@@ -333,9 +334,8 @@ proc_subproc (DWORD what, DWORD val)
case PROC_CLEARWAIT:
/* Clear all "wait"ing threads. */
sip_printf ("clear waiting threads");
- clearing = 1;
+ clearing = val;
- case PROC_SIGCHLD:
scan_wait:
/* Scan the linked list of wait()ing threads. If a wait's parameters
* match this pid, then activate it.
@@ -476,7 +476,7 @@ proc_terminate (void)
ForceCloseHandle1 (h, hwait_subproc);
sync_proc_subproc->acquire(WPSP);
- (void) proc_subproc (PROC_CLEARWAIT, 0);
+ (void) proc_subproc (PROC_CLEARWAIT, 1);
lock_pinfo_for_update (INFINITE);
/* Clean out zombie processes from the pid list. */
@@ -1205,6 +1205,8 @@ wait_sig (VOID *)
* array looking for any unprocessed signals.
*/
pending_signals = 0;
+ int saw_sigchld = 0;
+ int dispatched_sigchld = 0;
for (int sig = -__SIGOFFSET; sig < NSIG; sig++)
{
#ifdef NOSIGQUEUE
@@ -1213,6 +1215,8 @@ wait_sig (VOID *)
while (InterlockedDecrement (myself->getsigtodo(sig)) >= 0)
#endif
{
+ if (sig == SIGCHLD)
+ saw_sigchld = 1;
if (sig > 0 && sig != SIGCONT && sig != SIGKILL && sig != SIGSTOP &&
(sigismember (& myself->getsigmask (), sig) ||
myself->process_state & PID_STOPPED))
@@ -1247,9 +1251,8 @@ wait_sig (VOID *)
sip_printf ("Got signal %d", sig);
int wasdispatched = sig_handle (sig);
dispatched |= wasdispatched;
- if (sig == SIGCHLD && !wasdispatched)
- proc_subproc (PROC_SIGCHLD, 0);
- dispatched |= sig_handle (sig);
+ if (sig == SIGCHLD && wasdispatched)
+ dispatched_sigchld = 1;
goto nextsig;
}
}
@@ -1262,6 +1265,8 @@ wait_sig (VOID *)
continue;
}
+ if (saw_sigchld && !dispatched_sigchld)
+ proc_subproc (PROC_CLEARWAIT, 0);
/* Signal completion of signal handling depending on which semaphore
* woke up the WaitForMultipleObjects above.
*/
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 7f237a925..b1b4eafc0 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -18,8 +18,7 @@ enum procstuff
PROC_CHILDSTOPPED = 2, // a child stopped
PROC_CHILDTERMINATED = 3, // a child died
PROC_CLEARWAIT = 4, // clear all waits - signal arrived
- PROC_WAIT = 5, // setup for wait() for subproc
- PROC_SIGCHLD = 6 // saw a non-trapped SIGCHLD
+ PROC_WAIT = 5 // setup for wait() for subproc
};
typedef struct struct_waitq
diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc
index 96102828b..f9edb9935 100644
--- a/winsup/cygwin/sync.cc
+++ b/winsup/cygwin/sync.cc
@@ -103,11 +103,11 @@ muto::release ()
/* FIXME: Need to check that other thread has not exited, too. */
if (!--visits)
{
+ tid = 0; /* We were the last unlocker. */
InterlockedExchange (&sync, 0); /* Reset trigger. */
/* This thread had incremented waiters but had never decremented it.
Decrement it now. If it is >= 0 then there are possibly other
threads waiting for the lock, so trigger bruteforce. */
- tid = 0; /* We were the last unlocker. */
if (InterlockedDecrement (&waiters) >= 0)
(void) SetEvent (bruteforce); /* Wake up one of the waiting threads */
}
diff --git a/winsup/cygwin/sync.h b/winsup/cygwin/sync.h
index 7189ae936..3dcc915da 100644
--- a/winsup/cygwin/sync.h
+++ b/winsup/cygwin/sync.h
@@ -37,6 +37,7 @@ public:
/* Return true if caller thread owns the lock. */
int ismine () {return tid == GetCurrentThreadId ();}
DWORD owner () {return tid;}
+ int unstable () {return !tid && (sync || waiters >= 0);}
};
/* Use a statically allocated buffer as the storage for a muto */