* exceptions.cc (interruptible): Make a little more structured.

(call_handler): Allow signals to be sent even if signalled thread is stopped.
Change order of signal_arrived arming/waiting threads clearing to eliminate a
race.
(reset_signal_arrived): New helper function.
* malloc.cc (malloc_init): Use mutos so that signal handler can keep track of
who owns the lock.
(__malloc_lock): Ditto.
(__malloc_unlock): Ditto.
* sync.h (new_muto): Actually use a muto for the "buffer".
* Makefile.in: Fix a dependency.
This commit is contained in:
Christopher Faylor 2000-02-26 01:11:54 +00:00
parent 52aaab48f4
commit 8656ee07ef
11 changed files with 77 additions and 46 deletions

View File

@ -1,3 +1,17 @@
Fri Feb 25 19:26:42 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (interruptible): Make a little more structured.
(call_handler): Allow signals to be sent even if signalled thread is
stopped. Change order of signal_arrived arming/waiting threads
clearing to eliminate a race.
(reset_signal_arrived): New helper function.
* malloc.cc (malloc_init): Use mutos so that signal handler can keep
track of who owns the lock.
(__malloc_lock): Ditto.
(__malloc_unlock): Ditto.
* sync.h (new_muto): Actually use a muto for the "buffer".
* Makefile.in: Fix a dependency.
2000-02-25 DJ Delorie <dj@cygnus.com>
* Makefile.in: fix "make check" support and cygrun.
@ -17,7 +31,7 @@ Thu Feb 24 14:45:06 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.
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.

View File

@ -302,7 +302,7 @@ ioctl.o: $(WINSUP_H)
libccrt0.o: $(WINSUP_H)
libcmain.o: $(WINSUP_H)
localtime.o: tz_posixrules.h
malloc.o: $(WINSUP_H)
malloc.o: $(WINSUP_H) sync.h
mcount.o: gmon.h
mmap.o: $(WINSUP_H)
net.o: $(WINSUP_H) autoload.h

View File

@ -9,6 +9,7 @@ details. */
#define NO_DEBUG_DEFINES
#include "winsup.h"
#include "exceptions.h"
#include "sync.h"
static muto NO_COPY *threadname_lock = NULL;
#define lock_threadname() \

View File

@ -18,6 +18,7 @@ details. */
#define DECLSPEC_IMPORT
#include <imagehlp.h>
#include "autoload.h"
#include "sync.h"
char debugger_command[2 * MAX_PATH + 20];
@ -557,7 +558,7 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
bp -= 2;
break;
}
in->Ebp = (DWORD) bp;
sigsave.cx = in;
sig_send (NULL, sig); // Signal myself
@ -621,21 +622,28 @@ interruptible (DWORD pc)
return ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast)) ||
!(pchigh == 0xb0000000 || pchigh == 0x70000000 || pchigh == 0x60000000);
#else
int res = 1;
if ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast))
return 1;
res = 0;
else
{
MEMORY_BASIC_INFORMATION m;
memset (&m, 0, sizeof m);
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
sigproc_printf ("couldn't get memory info, %E");
MEMORY_BASIC_INFORMATION m;
memset (&m, 0, sizeof m);
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
sigproc_printf ("couldn't get memory info, %E");
char *checkdir = (char *) alloca (windows_system_directory_length);
# define h ((HMODULE) m.AllocationBase)
if (h == cygwin_hmodule)
res = 0;
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length))
res = 0;
else
res = !strncasematch (windows_system_directory, checkdir,
windows_system_directory_length);
}
# 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);
return res;
# undef h
#endif
}
@ -727,7 +735,6 @@ call_handler (int sig, struct sigaction& siga, void *handler)
we have to do that since sometimes they don't return - and if
this thread doesn't return, you won't ever get another exception. */
sigproc_printf ("Suspending %p (mainthread)", 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
@ -736,11 +743,9 @@ call_handler (int sig, struct sigaction& siga, void *handler)
already suspended (which should never occur) then just queue the signal. */
for (;;)
{
sigproc_printf ("suspending mainthread");
res = SuspendThread (hth);
if (res)
goto set_pending;
/* FIXME: Make multi-thread aware */
for (muto *m = muto_start.next; m != NULL; m = m->next)
if (m->unstable () || m->owner () == maintid)
@ -749,10 +754,14 @@ call_handler (int sig, struct sigaction& siga, void *handler)
break;
keep_looping:
sigproc_printf ("suspended thread owns a muto");
if (res)
goto set_pending;
ResumeThread (hth);
Sleep (0);
}
sigproc_printf ("suspend said %d, %E", res);
if (sigsave.cx)
@ -783,12 +792,6 @@ call_handler (int sig, struct sigaction& siga, void *handler)
interrupted = 0;
}
if (interrupted)
{
/* Clear any waiting threads prior to dispatching to handler function */
proc_subproc(PROC_CLEARWAIT, 1);
}
(void) ResumeThread (hth);
if (interrupted)
@ -796,6 +799,8 @@ call_handler (int sig, struct sigaction& siga, void *handler)
/* 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
/* Clear any waiting threads prior to dispatching to handler function */
proc_subproc(PROC_CLEARWAIT, 1);
}
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
@ -1068,6 +1073,15 @@ events_terminate (void)
#define pid_offset (unsigned)(((pinfo *)NULL)->pid)
extern "C" {
static void __stdcall
reset_signal_arrived () __attribute__ ((unused));
static void __stdcall
reset_signal_arrived ()
{
(void) ResetEvent (signal_arrived);
sigproc_printf ("reset signal_arrived");
}
void unused_sig_wrapper()
{
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
@ -1076,7 +1090,6 @@ void unused_sig_wrapper()
and returns to orignal caller. */
__asm__ volatile ("
.text
___sigfirst:
.globl __raise
__raise:
pushl %%ebp
@ -1120,19 +1133,21 @@ _sigdelayed:
pushl %3 # oldmask
pushl %4 # signal argument
pushl $_sigreturn
movl $0,%0
pushl _signal_arrived # Everybody waiting for this should
call _ResetEvent@4 # have woken up by now.
call _reset_signal_arrived@0
# pushl _signal_arrived # Everybody waiting for this should
# call _ResetEvent@4 # have woken up by now.
movl $0,%0
cmpl $0,_pending_signals
je 2f
___sigfirst:
pushl $0
call _sig_dispatch_pending@4
___siglast:
2: jmp *%5
___siglast:
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno)

View File

@ -13,6 +13,7 @@ details. */
#include <unistd.h>
#include <stdlib.h>
#include "winsup.h"
#include "sync.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */

View File

@ -178,7 +178,6 @@ fhandler_console::read (void *pv, size_t buflen)
kill_pgrp (tc->getpgid (), SIGWINCH);
continue;
}
debug_printf ("ich %d, keydown %d, type %d", ich, input_rec.Event.KeyEvent.bKeyDown, input_rec.EventType);
if (input_rec.EventType != KEY_EVENT ||
!input_rec.Event.KeyEvent.bKeyDown)
continue;

View File

@ -13,6 +13,7 @@ details. */
#include "winsup.h"
#include <stdlib.h>
#include "sync.h"
/* we provide these stubs to call into a user's
provided malloc if there is one - otherwise
@ -200,12 +201,12 @@ _strdup_r (struct _reent *, const char *s)
newlib will call __malloc_lock and __malloc_unlock at appropriate
times. */
static NO_COPY CRITICAL_SECTION malloc_critical_section;
static NO_COPY muto *mprotect = NULL;
void
malloc_init ()
{
InitializeCriticalSection (&malloc_critical_section);
mprotect = new_muto (FALSE, NULL);
/* Check if mallock is provided by application. If so, redirect all
calls to export_malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides
@ -226,12 +227,12 @@ extern "C"
void
__malloc_lock (struct _reent *)
{
SetResourceLock(LOCK_MEMORY_LIST,WRITE_LOCK|READ_LOCK," __malloc_lock");
mprotect->acquire ();
}
extern "C"
void
__malloc_unlock (struct _reent *)
{
ReleaseResourceLock(LOCK_MEMORY_LIST,WRITE_LOCK|READ_LOCK," __malloc_unlock");
mprotect->release ();
}

View File

@ -16,6 +16,7 @@ details. */
#include <errno.h>
#include <stdlib.h>
#include "winsup.h"
#include "sync.h"
extern BOOL allow_ntsec;

View File

@ -20,11 +20,12 @@ details. */
#include <errno.h>
#include <stdlib.h>
#include "winsup.h"
#include "sync.h"
muto muto_start (0, 0);
muto NO_COPY muto_start;
/* Constructor */
muto::muto(int inh, const char *name) : sync (0), visits(0), waiters(-1), tid (0), next (0)
muto::muto(int inh, const char *name) : sync (0), visits(0), waiters(-1), tid (0), next (NULL)
{
/* Create event which is used in the fallback case when blocking is necessary */
if (!(bruteforce = CreateEvent (inh ? &sec_all_nih : &sec_none_nih, FALSE, FALSE, name)))

View File

@ -28,7 +28,7 @@ public:
/* This simple constructor is used for cases where no bruteforce
event handling is required. */
muto(): sync(0), visits(0), waiters(-1), bruteforce(0), tid(0), next (0) {;}
muto(): sync(0), visits(0), waiters(-1), bruteforce(0), tid(0), next (NULL) {;}
/* A more complicated constructor. */
muto(int inh, const char *name);
~muto ();
@ -46,9 +46,9 @@ extern muto muto_start;
/* Use a statically allocated buffer as the storage for a muto */
#define new_muto(__inh, __name) \
({ \
static NO_COPY char __mbuf[sizeof(class muto) + 100] = {0}; \
muto *m = muto_start.next; \
muto_start.next = new (__mbuf) muto ((__inh), (__name)); \
muto_start.next->next = m; \
muto_start.next; \
static NO_COPY muto __mbuf; \
(void) new ((char *) &__mbuf) muto (__inh, __name); \
__mbuf.next = muto_start.next; \
muto_start.next = &__mbuf; \
&__mbuf; \
})

View File

@ -82,8 +82,6 @@ extern int dynamically_loaded;
extern HANDLE hMainThread;
extern HANDLE hMainProc;
#include "sync.h"
/* Now that pinfo has been defined, include... */
#include "debug.h"
#include "sigproc.h"