4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 03:27:46 +08:00

* exceptions.cc (interruptible): Change method for determining if something is

interruptible.
(call_handler): Avoid suspending a thread if it owns a mutex.  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
* init.cc (dll_entry): Record module handle of main for use by interruptible().
(proc_subproc): Reorganize handling of terminated child so that the 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.
This commit is contained in:
Christopher Faylor 2000-02-24 02:49:44 +00:00
parent 58dabf5040
commit f02f1f1444
17 changed files with 164 additions and 96 deletions

View File

@ -1,3 +1,20 @@
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
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
* init.cc (dll_entry): Record module handle of main for use by
interruptible().
(proc_subproc): Reorganize handling of terminated child so that the
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> Tue Feb 22 23:06:01 2000 Christopher Faylor <cgf@cygnus.com>
Respond to more g++ warnings relating to initializing structures. Respond to more g++ warnings relating to initializing structures.

View File

@ -1,6 +1,6 @@
/* autoload.h: Define functions for auto-loading symbols from a DLL. /* autoload.h: Define functions for auto-loading symbols from a DLL.
Copyright 1999 Cygnus Solutions. Copyright 1999, 2000 Cygnus Solutions.
Written by Christopher Faylor <cgf@cygnus.com> Written by Christopher Faylor <cgf@cygnus.com>

View File

@ -1,6 +1,6 @@
/* errno.cc: errno-related functions /* errno.cc: errno-related functions
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -31,12 +31,15 @@ extern DWORD __sigfirst, __siglast;
static BOOL WINAPI ctrl_c_handler (DWORD); static BOOL WINAPI ctrl_c_handler (DWORD);
static void really_exit (int); static void really_exit (int);
static char windows_system_directory[1024];
static size_t windows_system_directory_length;
/* This is set to indicate that we have already exited. */ /* This is set to indicate that we have already exited. */
static NO_COPY int exit_already = 0; static NO_COPY int exit_already = 0;
static NO_COPY muto *mask_sync = NULL; static NO_COPY muto *mask_sync = NULL;
HMODULE cygwin_hmodule;
HANDLE NO_COPY console_handler_thread_waiter = NULL; HANDLE NO_COPY console_handler_thread_waiter = NULL;
static const struct static const struct
@ -611,12 +614,31 @@ handle_sigsuspend (sigset_t tempmask)
extern DWORD exec_exit; // Possible exit value for exec extern DWORD exec_exit; // Possible exit value for exec
extern int pending_signals; extern int pending_signals;
extern __inline int int
interruptible (DWORD pc) interruptible (DWORD pc)
{ {
#if 0
DWORD pchigh = pc & 0xf0000000; DWORD pchigh = pc & 0xf0000000;
return ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast)) || return ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast)) ||
!(pchigh == 0xb0000000 || pchigh == 0x70000000 || pchigh == 0x60000000); !(pchigh == 0xb0000000 || pchigh == 0x70000000 || pchigh == 0x60000000);
#else
if ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast))
return 1;
MEMORY_BASIC_INFORMATION m;
memset (&m, 0, sizeof m);
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
sigproc_printf ("couldn't get memory info, %E");
# define h ((HMODULE) m.AllocationBase)
if (h == cygwin_hmodule)
return 0;
char *checkdir = (char *) alloca (windows_system_directory_length);
if (!GetModuleFileName (h, checkdir, windows_system_directory_length))
return 0;
return !strncasematch (windows_system_directory, checkdir, windows_system_directory_length);
# undef h
#endif
} }
void void
@ -689,7 +711,9 @@ static int
call_handler (int sig, struct sigaction& siga, void *handler) call_handler (int sig, struct sigaction& siga, void *handler)
{ {
CONTEXT *cx, orig; CONTEXT *cx, orig;
int interrupted = 1;
int res; int res;
extern muto *sync_proc_subproc;
if (hExeced != NULL && hExeced != INVALID_HANDLE_VALUE) if (hExeced != NULL && hExeced != INVALID_HANDLE_VALUE)
{ {
@ -706,7 +730,24 @@ call_handler (int sig, struct sigaction& siga, void *handler)
sigproc_printf ("Suspending %p (mainthread)", myself->getthread2signal()); sigproc_printf ("Suspending %p (mainthread)", myself->getthread2signal());
HANDLE hth = myself->getthread2signal (); HANDLE hth = myself->getthread2signal ();
/* Suspend the thread which will receive the signal. But first ensure that
this thread doesn't have the sync_proc_subproc and mask_sync mutos, since
we need those (hack alert). If the thread-to-be-suspended has either of
these mutos, enter a busy loop until it is released. If the thread is
already suspended (which should never occur) then just queue the signal. */
for (;;)
{
res = SuspendThread (hth); res = SuspendThread (hth);
/* FIXME: Make multi-thread aware */
if (sync_proc_subproc->owner () != maintid && mask_sync->owner () != maintid)
break;
if (res)
goto set_pending;
ResumeThread (hth);
Sleep (0);
}
sigproc_printf ("suspend said %d, %E", res); sigproc_printf ("suspend said %d, %E", res);
/* Clear any waiting threads prior to dispatching to handler function */ /* Clear any waiting threads prior to dispatching to handler function */
@ -734,17 +775,20 @@ call_handler (int sig, struct sigaction& siga, void *handler)
interrupt_now (cx, sig, siga, handler); interrupt_now (cx, sig, siga, handler);
else if (!interrupt_on_return (cx, sig, siga, handler)) else if (!interrupt_on_return (cx, sig, siga, handler))
{ {
set_pending:
pending_signals = 1; /* FIXME: Probably need to be more tricky here */ pending_signals = 1; /* FIXME: Probably need to be more tricky here */
sig_set_pending (sig); sig_set_pending (sig);
interrupted = 0;
} }
(void) ResumeThread (hth); (void) ResumeThread (hth);
if (interrupted)
(void) SetEvent (signal_arrived); // For an EINTR case (void) SetEvent (signal_arrived); // For an EINTR case
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
out: out:
sigproc_printf ("returning"); sigproc_printf ("returning");
return 1; return interrupted;
} }
#endif /* i386 */ #endif /* i386 */
@ -983,6 +1027,17 @@ events_init (void)
ProtectHandle (title_mutex); ProtectHandle (title_mutex);
mask_sync = new_muto (FALSE, NULL); mask_sync = new_muto (FALSE, NULL);
windows_system_directory[0] = '\0';
(void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
char *end = strchr (windows_system_directory, '\0');
if (end == windows_system_directory)
api_fatal ("can't find windows system directory");
if (end[-1] != '\\')
{
*end++ = '\\';
*end = '\0';
}
windows_system_directory_length = end - windows_system_directory;
} }
void void
@ -1035,12 +1090,7 @@ _sigreturn:
ret ret
_sigdelayed: _sigdelayed:
# addl 4,%%esp pushl %2 # original return address
cmpl $0,_pending_signals
je 2f
pushl $0
call _sig_dispatch_pending@4
2: pushl %2 # original return address
pushf pushf
pushl %%esi pushl %%esi
pushl %%edi pushl %%edi
@ -1053,9 +1103,16 @@ _sigdelayed:
pushl %4 # signal argument pushl %4 # signal argument
pushl $_sigreturn pushl $_sigreturn
movl $0,%0 movl $0,%0
pushl $_signal_arrived
call _ResetEvent@4 pushl _signal_arrived # Everybody waiting for this should
jmp *%5 call _ResetEvent@4 # have woken up by now.
cmpl $0,_pending_signals
je 2f
pushl $0
call _sig_dispatch_pending@4
2: jmp *%5
___siglast: ___siglast:
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno), " : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),

View File

@ -1,6 +1,6 @@
/* external.cc: Interface to Cygwin internals from external programs. /* external.cc: Interface to Cygwin internals from external programs.
Copyright 1997, 1998, 1999 Cygnus Solutions. Copyright 1997, 1998, 1999, 2000 Cygnus Solutions.
Written by Christopher Faylor <cgf@cygnus.com> Written by Christopher Faylor <cgf@cygnus.com>

View File

@ -1,7 +1,7 @@
/* fhandler_floppy.cc. See fhandler.h for a description of the /* fhandler_floppy.cc. See fhandler.h for a description of the
fhandler classes. fhandler classes.
Copyright 1999 Cygnus Solutions. Copyright 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -1,6 +1,6 @@
/* fork.cc /* fork.cc
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -1,6 +1,6 @@
/* heap.cc: Cygwin heap manager. /* heap.cc: Cygwin heap manager.
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -1,6 +1,6 @@
/* init.cc for WIN32. /* init.cc for WIN32.
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.
@ -12,26 +12,17 @@ details. */
#include <ctype.h> #include <ctype.h>
#include "winsup.h" #include "winsup.h"
extern "C" extern HMODULE cygwin_hmodule;
{
int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr);
};
extern "C" void *export_malloc (unsigned int);
extern "C" void *export_realloc (void *,unsigned int);
extern "C" void *export_calloc (unsigned int,unsigned int);
extern "C" void export_free (void *);
extern void do_global_ctors (void (**in_pfunc)(), int force);
int NO_COPY dynamically_loaded; int NO_COPY dynamically_loaded;
int extern "C" int
WINAPI dll_entry (HANDLE, DWORD reason, void *static_load) WINAPI dll_entry (HANDLE h, DWORD reason, void *static_load)
{ {
switch (reason) switch (reason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
cygwin_hmodule = (HMODULE) h;
dynamically_loaded = (static_load == NULL); dynamically_loaded = (static_load == NULL);
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:

View File

@ -1,6 +1,6 @@
/* pipe.cc: pipe for WIN32. /* pipe.cc: pipe for Cygwin.
Copyright 1996, 1998, 1999 Cygnus Solutions. Copyright 1996, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -1,6 +1,6 @@
/* registry.cc: registry interface /* registry.cc: registry interface
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.

View File

@ -85,8 +85,6 @@ Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread
Static HANDLE wait_sig_inited = NULL; // Control synchronization of Static HANDLE wait_sig_inited = NULL; // Control synchronization of
// message queue startup // message queue startup
Static muto *sync_proc_subproc = NULL; // Control access to
// subproc stuff
/* Used by WaitForMultipleObjects. These are handles to child processes. /* Used by WaitForMultipleObjects. These are handles to child processes.
*/ */
@ -100,6 +98,9 @@ Static int nzombies = 0; // Number of deceased children
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
Static waitq waitq_main; // Storage for main thread Static waitq waitq_main; // Storage for main thread
muto NO_COPY *sync_proc_subproc = NULL; // Control access to
// subproc stuff
DWORD NO_COPY maintid = 0; // ID of the main thread DWORD NO_COPY maintid = 0; // ID of the main thread
Static DWORD sigtid = 0; // ID of the signal thread Static DWORD sigtid = 0; // ID of the signal thread
@ -244,7 +245,7 @@ proc_subproc (DWORD what, DWORD val)
int potential_match; int potential_match;
DWORD exitcode; DWORD exitcode;
pinfo *child; pinfo *child;
int send_sigchld = 0; int clearing = 0;
waitq *w; waitq *w;
#define wval ((waitq *) val) #define wval ((waitq *) val)
@ -284,14 +285,6 @@ proc_subproc (DWORD what, DWORD val)
wake_wait_subproc (); wake_wait_subproc ();
break; break;
/* A child is in the stopped state. Scan wait() queue to see if anyone
* should be notified. (Called from wait_sig thread)
*/
case PROC_CHILDSTOPPED:
child = myself; // Just to avoid accidental NULL dereference
sip_printf ("Received stopped notification");
goto scan_wait;
/* A child process had terminated. /* A child process had terminated.
* Possibly this is just due to an exec(). Cygwin implements an exec() * Possibly this is just due to an exec(). Cygwin implements an exec()
* as a "handoff" from one windows process to another. If child->hProcess * as a "handoff" from one windows process to another. If child->hProcess
@ -310,7 +303,6 @@ proc_subproc (DWORD what, DWORD val)
ForceCloseHandle1 (hchildren[val], childhProc); ForceCloseHandle1 (hchildren[val], childhProc);
hchildren[val] = child->hProcess; /* Filled out by child */ hchildren[val] = child->hProcess; /* Filled out by child */
ProtectHandle1 (child->hProcess, childhProc); ProtectHandle1 (child->hProcess, childhProc);
wake_wait_subproc ();
break; // This was an exec() break; // This was an exec()
} }
@ -318,46 +310,21 @@ proc_subproc (DWORD what, DWORD val)
child->pid, val, hchildren[val], nchildren, nzombies); child->pid, val, hchildren[val], nchildren, nzombies);
remove_child (val); // Remove from children arrays remove_child (val); // Remove from children arrays
zombies[nzombies++] = child; // Add to zombie array zombies[nzombies++] = child; // Add to zombie array
wake_wait_subproc (); // Notify wait_subproc thread that
// nchildren has changed.
child->process_state = PID_ZOMBIE;// Walking dead child->process_state = PID_ZOMBIE;// Walking dead
if (!proc_loop_wait) // Don't bother if wait_subproc is if (!proc_loop_wait) // Don't bother if wait_subproc is
break; // exiting break; // exiting
send_sigchld = 1;
scan_wait:
/* Scan the linked list of wait()ing threads. If a wait's parameters
* match this pid, then activate it.
*/
for (w = &waitq_head; w->next != NULL; w = w->next)
{
if ((potential_match = checkstate (w)) > 0)
sip_printf ("released waiting thread");
else if (potential_match < 0)
sip_printf ("only found non-terminated children");
else if (potential_match == 0) // nothing matched
{
sip_printf ("waiting thread found no children");
HANDLE oldw = w->next->ev;
w->next->ev = NULL;
if (!SetEvent (oldw))
system_printf ("couldn't wake up wait event %p, %E", oldw);
w->next = w->next->next;
}
if (w->next == NULL)
break;
}
sip_printf ("finished processing terminated/stopped child");
if (!send_sigchld)
break; // No need to send a SIGCHLD
/* Send a SIGCHLD to myself. */ /* Send a SIGCHLD to myself. */
sync_proc_subproc->release (); // Avoid a potential deadlock rc = sig_send (myself_nowait, SIGCHLD); // Send a SIGCHLD
rc = sig_send (NULL, SIGCHLD); // Send a SIGCHLD break; // Don't try to unlock. We don't have a lock.
goto out1; // Don't try to unlock. We don't have a lock.
/* A child is in the stopped state. Scan wait() queue to see if anyone
* should be notified. (Called from wait_sig thread)
*/
case PROC_CHILDSTOPPED:
child = myself; // Just to avoid accidental NULL dereference
sip_printf ("Received stopped notification");
goto scan_wait;
/* Clear all waiting threads. Called from exceptions.cc prior to /* Clear all waiting threads. Called from exceptions.cc prior to
* the main thread's dispatch to a signal handler function. * the main thread's dispatch to a signal handler function.
@ -366,15 +333,41 @@ proc_subproc (DWORD what, DWORD val)
case PROC_CLEARWAIT: case PROC_CLEARWAIT:
/* Clear all "wait"ing threads. */ /* Clear all "wait"ing threads. */
sip_printf ("clear waiting threads"); sip_printf ("clear waiting threads");
clearing = 1;
case PROC_SIGCHLD:
scan_wait:
/* Scan the linked list of wait()ing threads. If a wait's parameters
* match this pid, then activate it.
*/
for (w = &waitq_head; w->next != NULL; w = w->next) for (w = &waitq_head; w->next != NULL; w = w->next)
{ {
sip_printf ("clearing waiting thread, pid %d", w->next->pid); if ((potential_match = checkstate (w)) > 0)
sip_printf ("released waiting thread");
else if (!clearing && potential_match < 0)
sip_printf ("only found non-terminated children");
else if (potential_match <= 0) // nothing matched
{
sip_printf ("waiting thread found no children");
HANDLE oldw = w->next->ev;
w->next->ev = NULL;
if (clearing)
w->next->status = -1; /* flag that a signal was received */ w->next->status = -1; /* flag that a signal was received */
if (!SetEvent (w->next->ev)) if (!SetEvent (oldw))
system_printf ("Couldn't wake up wait event, %E"); system_printf ("couldn't wake up wait event %p, %E", oldw);
w->next = w->next->next;
} }
if (w->next == NULL)
break;
}
if (!clearing)
sip_printf ("finished processing terminated/stopped child");
else
{
waitq_head.next = NULL; waitq_head.next = NULL;
sip_printf ("finished clearing"); sip_printf ("finished clearing");
}
break; break;
/* Handle a wait4() operation. Allocates an event for the calling /* Handle a wait4() operation. Allocates an event for the calling
@ -1252,6 +1245,10 @@ wait_sig (VOID *)
/* A normal UNIX signal */ /* A normal UNIX signal */
default: default:
sip_printf ("Got signal %d", sig); 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); dispatched |= sig_handle (sig);
goto nextsig; goto nextsig;
} }

View File

@ -18,7 +18,8 @@ enum procstuff
PROC_CHILDSTOPPED = 2, // a child stopped PROC_CHILDSTOPPED = 2, // a child stopped
PROC_CHILDTERMINATED = 3, // a child died PROC_CHILDTERMINATED = 3, // a child died
PROC_CLEARWAIT = 4, // clear all waits - signal arrived PROC_CLEARWAIT = 4, // clear all waits - signal arrived
PROC_WAIT = 5 // setup for wait() for subproc PROC_WAIT = 5, // setup for wait() for subproc
PROC_SIGCHLD = 6 // saw a non-trapped SIGCHLD
}; };
typedef struct struct_waitq typedef struct struct_waitq

View File

@ -4,7 +4,7 @@
which is intended to operate similarly to a mutex but attempts to which is intended to operate similarly to a mutex but attempts to
avoid making expensive calls to the kernel. avoid making expensive calls to the kernel.
Copyright 1999 Cygnus Solutions. Copyright 2000 Cygnus Solutions.
Written by Christopher Faylor <cgf@cygnus.com> Written by Christopher Faylor <cgf@cygnus.com>
@ -43,7 +43,11 @@ muto::~muto ()
/* Acquire the lock. Argument is the number of milliseconds to wait for /* Acquire the lock. Argument is the number of milliseconds to wait for
the lock. Multiple visits from the same thread are allowed and should the lock. Multiple visits from the same thread are allowed and should
be handled correctly. */ be handled correctly.
Note: The goal here is to minimize, as much as possible, calls to the
OS. Hence the use of InterlockedIncrement, etc., rather than (much) more
expensive OS mutexes. */
int int
muto::acquire (DWORD ms) muto::acquire (DWORD ms)
{ {
@ -59,7 +63,7 @@ muto::acquire (DWORD ms)
lock the same muto to succeed without attempting to manipulate sync. lock the same muto to succeed without attempting to manipulate sync.
If the muto is already locked then this thread will wait for ms until If the muto is already locked then this thread will wait for ms until
it is signalled by muto::release. Then it will attempt to grab the it is signalled by muto::release. Then it will attempt to grab the
sync field. If it succeeds, then this thread owns the mutex. sync field. If it succeeds, then this thread owns the muto.
There is a pathological condition where a thread times out waiting for There is a pathological condition where a thread times out waiting for
bruteforce but the release code triggers the bruteforce event. In this bruteforce but the release code triggers the bruteforce event. In this
@ -99,11 +103,11 @@ muto::release ()
/* FIXME: Need to check that other thread has not exited, too. */ /* FIXME: Need to check that other thread has not exited, too. */
if (!--visits) if (!--visits)
{ {
tid = 0; /* We were the last unlocker. */
InterlockedExchange (&sync, 0); /* Reset trigger. */ InterlockedExchange (&sync, 0); /* Reset trigger. */
/* This thread had incremented waiters but had never decremented it. /* This thread had incremented waiters but had never decremented it.
Decrement it now. If it is >= 0 then there are possibly other Decrement it now. If it is >= 0 then there are possibly other
threads waiting for the lock, so trigger bruteforce. */ threads waiting for the lock, so trigger bruteforce. */
tid = 0; /* We were the last unlocker. */
if (InterlockedDecrement (&waiters) >= 0) if (InterlockedDecrement (&waiters) >= 0)
(void) SetEvent (bruteforce); /* Wake up one of the waiting threads */ (void) SetEvent (bruteforce); /* Wake up one of the waiting threads */
} }

View File

@ -1,6 +1,6 @@
/* sync.h: Header file for cygwin synchronization primitives. /* sync.h: Header file for cygwin synchronization primitives.
Copyright 1999 Cygnus Solutions. Copyright 1999, 2000 Cygnus Solutions.
Written by Christopher Faylor <cgf@cygnus.com> Written by Christopher Faylor <cgf@cygnus.com>
@ -36,6 +36,7 @@ public:
/* Return true if caller thread owns the lock. */ /* Return true if caller thread owns the lock. */
int ismine () {return tid == GetCurrentThreadId ();} int ismine () {return tid == GetCurrentThreadId ();}
DWORD owner () {return tid;}
}; };
/* Use a statically allocated buffer as the storage for a muto */ /* Use a statically allocated buffer as the storage for a muto */

View File

@ -1,6 +1,6 @@
/* thread.h: Locking and threading module definitions /* thread.h: Locking and threading module definitions
Copyright 1998, 1999 Cygnus Solutions. Copyright 1998, 1999, 2000 Cygnus Solutions.
Written by Marco Fuykschot <marco@ddi.nl> Written by Marco Fuykschot <marco@ddi.nl>

View File

@ -1,6 +1,6 @@
/* wait.cc: Posix wait routines. /* wait.cc: Posix wait routines.
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
This file is part of Cygwin. This file is part of Cygwin.