* 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:
parent
52aaab48f4
commit
8656ee07ef
@ -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>
|
2000-02-25 DJ Delorie <dj@cygnus.com>
|
||||||
|
|
||||||
* Makefile.in: fix "make check" support and cygrun.
|
* Makefile.in: fix "make check" support and cygrun.
|
||||||
|
@ -302,7 +302,7 @@ ioctl.o: $(WINSUP_H)
|
|||||||
libccrt0.o: $(WINSUP_H)
|
libccrt0.o: $(WINSUP_H)
|
||||||
libcmain.o: $(WINSUP_H)
|
libcmain.o: $(WINSUP_H)
|
||||||
localtime.o: tz_posixrules.h
|
localtime.o: tz_posixrules.h
|
||||||
malloc.o: $(WINSUP_H)
|
malloc.o: $(WINSUP_H) sync.h
|
||||||
mcount.o: gmon.h
|
mcount.o: gmon.h
|
||||||
mmap.o: $(WINSUP_H)
|
mmap.o: $(WINSUP_H)
|
||||||
net.o: $(WINSUP_H) autoload.h
|
net.o: $(WINSUP_H) autoload.h
|
||||||
|
@ -9,6 +9,7 @@ details. */
|
|||||||
#define NO_DEBUG_DEFINES
|
#define NO_DEBUG_DEFINES
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
static muto NO_COPY *threadname_lock = NULL;
|
static muto NO_COPY *threadname_lock = NULL;
|
||||||
#define lock_threadname() \
|
#define lock_threadname() \
|
||||||
|
@ -18,6 +18,7 @@ details. */
|
|||||||
#define DECLSPEC_IMPORT
|
#define DECLSPEC_IMPORT
|
||||||
#include <imagehlp.h>
|
#include <imagehlp.h>
|
||||||
#include "autoload.h"
|
#include "autoload.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
char debugger_command[2 * MAX_PATH + 20];
|
char debugger_command[2 * MAX_PATH + 20];
|
||||||
|
|
||||||
@ -621,21 +622,28 @@ interruptible (DWORD pc)
|
|||||||
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
|
#else
|
||||||
|
int res = 1;
|
||||||
if ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast))
|
if ((pc >= (DWORD) &__sigfirst) && (pc <= (DWORD) &__siglast))
|
||||||
return 1;
|
res = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
MEMORY_BASIC_INFORMATION m;
|
MEMORY_BASIC_INFORMATION m;
|
||||||
memset (&m, 0, sizeof m);
|
memset (&m, 0, sizeof m);
|
||||||
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
|
if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
|
||||||
sigproc_printf ("couldn't get memory info, %E");
|
sigproc_printf ("couldn't get memory info, %E");
|
||||||
|
|
||||||
|
char *checkdir = (char *) alloca (windows_system_directory_length);
|
||||||
# define h ((HMODULE) m.AllocationBase)
|
# define h ((HMODULE) m.AllocationBase)
|
||||||
if (h == cygwin_hmodule)
|
if (h == cygwin_hmodule)
|
||||||
return 0;
|
res = 0;
|
||||||
char *checkdir = (char *) alloca (windows_system_directory_length);
|
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length))
|
||||||
if (!GetModuleFileName (h, checkdir, windows_system_directory_length))
|
res = 0;
|
||||||
return 0;
|
else
|
||||||
return !strncasematch (windows_system_directory, checkdir, windows_system_directory_length);
|
res = !strncasematch (windows_system_directory, checkdir,
|
||||||
|
windows_system_directory_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
# undef h
|
# undef h
|
||||||
#endif
|
#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
|
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. */
|
this thread doesn't return, you won't ever get another exception. */
|
||||||
|
|
||||||
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
|
/* 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
|
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. */
|
already suspended (which should never occur) then just queue the signal. */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
sigproc_printf ("suspending mainthread");
|
||||||
res = SuspendThread (hth);
|
res = SuspendThread (hth);
|
||||||
|
|
||||||
if (res)
|
|
||||||
goto set_pending;
|
|
||||||
|
|
||||||
/* FIXME: Make multi-thread aware */
|
/* FIXME: Make multi-thread aware */
|
||||||
for (muto *m = muto_start.next; m != NULL; m = m->next)
|
for (muto *m = muto_start.next; m != NULL; m = m->next)
|
||||||
if (m->unstable () || m->owner () == maintid)
|
if (m->unstable () || m->owner () == maintid)
|
||||||
@ -749,6 +754,10 @@ call_handler (int sig, struct sigaction& siga, void *handler)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
keep_looping:
|
keep_looping:
|
||||||
|
sigproc_printf ("suspended thread owns a muto");
|
||||||
|
if (res)
|
||||||
|
goto set_pending;
|
||||||
|
|
||||||
ResumeThread (hth);
|
ResumeThread (hth);
|
||||||
Sleep (0);
|
Sleep (0);
|
||||||
}
|
}
|
||||||
@ -783,12 +792,6 @@ call_handler (int sig, struct sigaction& siga, void *handler)
|
|||||||
interrupted = 0;
|
interrupted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupted)
|
|
||||||
{
|
|
||||||
/* Clear any waiting threads prior to dispatching to handler function */
|
|
||||||
proc_subproc(PROC_CLEARWAIT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) ResumeThread (hth);
|
(void) ResumeThread (hth);
|
||||||
|
|
||||||
if (interrupted)
|
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
|
/* Apparently we have to set signal_arrived after resuming the thread or it
|
||||||
is possible that the event will be ignored. */
|
is possible that the event will be ignored. */
|
||||||
(void) SetEvent (signal_arrived); // For an EINTR case
|
(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);
|
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)
|
#define pid_offset (unsigned)(((pinfo *)NULL)->pid)
|
||||||
extern "C" {
|
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()
|
void unused_sig_wrapper()
|
||||||
{
|
{
|
||||||
/* Signal cleanup stuff. Cleans up stack (too bad that we didn't
|
/* 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. */
|
and returns to orignal caller. */
|
||||||
__asm__ volatile ("
|
__asm__ volatile ("
|
||||||
.text
|
.text
|
||||||
___sigfirst:
|
|
||||||
.globl __raise
|
.globl __raise
|
||||||
__raise:
|
__raise:
|
||||||
pushl %%ebp
|
pushl %%ebp
|
||||||
@ -1120,19 +1133,21 @@ _sigdelayed:
|
|||||||
pushl %3 # oldmask
|
pushl %3 # oldmask
|
||||||
pushl %4 # signal argument
|
pushl %4 # signal argument
|
||||||
pushl $_sigreturn
|
pushl $_sigreturn
|
||||||
movl $0,%0
|
|
||||||
|
|
||||||
pushl _signal_arrived # Everybody waiting for this should
|
call _reset_signal_arrived@0
|
||||||
call _ResetEvent@4 # have woken up by now.
|
# pushl _signal_arrived # Everybody waiting for this should
|
||||||
|
# call _ResetEvent@4 # have woken up by now.
|
||||||
|
movl $0,%0
|
||||||
|
|
||||||
cmpl $0,_pending_signals
|
cmpl $0,_pending_signals
|
||||||
je 2f
|
je 2f
|
||||||
|
___sigfirst:
|
||||||
pushl $0
|
pushl $0
|
||||||
call _sig_dispatch_pending@4
|
call _sig_dispatch_pending@4
|
||||||
|
___siglast:
|
||||||
|
|
||||||
2: jmp *%5
|
2: jmp *%5
|
||||||
|
|
||||||
___siglast:
|
|
||||||
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
||||||
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
||||||
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno)
|
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno)
|
||||||
|
@ -13,6 +13,7 @@ details. */
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
|
||||||
|
|
||||||
|
@ -178,7 +178,6 @@ fhandler_console::read (void *pv, size_t buflen)
|
|||||||
kill_pgrp (tc->getpgid (), SIGWINCH);
|
kill_pgrp (tc->getpgid (), SIGWINCH);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
debug_printf ("ich %d, keydown %d, type %d", ich, input_rec.Event.KeyEvent.bKeyDown, input_rec.EventType);
|
|
||||||
if (input_rec.EventType != KEY_EVENT ||
|
if (input_rec.EventType != KEY_EVENT ||
|
||||||
!input_rec.Event.KeyEvent.bKeyDown)
|
!input_rec.Event.KeyEvent.bKeyDown)
|
||||||
continue;
|
continue;
|
||||||
|
@ -13,6 +13,7 @@ details. */
|
|||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
/* we provide these stubs to call into a user's
|
/* we provide these stubs to call into a user's
|
||||||
provided malloc if there is one - otherwise
|
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
|
newlib will call __malloc_lock and __malloc_unlock at appropriate
|
||||||
times. */
|
times. */
|
||||||
|
|
||||||
static NO_COPY CRITICAL_SECTION malloc_critical_section;
|
static NO_COPY muto *mprotect = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
malloc_init ()
|
malloc_init ()
|
||||||
{
|
{
|
||||||
InitializeCriticalSection (&malloc_critical_section);
|
mprotect = new_muto (FALSE, NULL);
|
||||||
/* Check if mallock is provided by application. If so, redirect all
|
/* Check if mallock is provided by application. If so, redirect all
|
||||||
calls to export_malloc/free/realloc to application provided. This may
|
calls to export_malloc/free/realloc to application provided. This may
|
||||||
happen if some other dll calls cygwin's malloc, but main code provides
|
happen if some other dll calls cygwin's malloc, but main code provides
|
||||||
@ -226,12 +227,12 @@ extern "C"
|
|||||||
void
|
void
|
||||||
__malloc_lock (struct _reent *)
|
__malloc_lock (struct _reent *)
|
||||||
{
|
{
|
||||||
SetResourceLock(LOCK_MEMORY_LIST,WRITE_LOCK|READ_LOCK," __malloc_lock");
|
mprotect->acquire ();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void
|
void
|
||||||
__malloc_unlock (struct _reent *)
|
__malloc_unlock (struct _reent *)
|
||||||
{
|
{
|
||||||
ReleaseResourceLock(LOCK_MEMORY_LIST,WRITE_LOCK|READ_LOCK," __malloc_unlock");
|
mprotect->release ();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ details. */
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
extern BOOL allow_ntsec;
|
extern BOOL allow_ntsec;
|
||||||
|
|
||||||
|
@ -20,11 +20,12 @@ details. */
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
|
#include "sync.h"
|
||||||
|
|
||||||
muto muto_start (0, 0);
|
muto NO_COPY muto_start;
|
||||||
|
|
||||||
/* Constructor */
|
/* 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 */
|
/* 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)))
|
if (!(bruteforce = CreateEvent (inh ? &sec_all_nih : &sec_none_nih, FALSE, FALSE, name)))
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
|
|
||||||
/* This simple constructor is used for cases where no bruteforce
|
/* This simple constructor is used for cases where no bruteforce
|
||||||
event handling is required. */
|
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. */
|
/* A more complicated constructor. */
|
||||||
muto(int inh, const char *name);
|
muto(int inh, const char *name);
|
||||||
~muto ();
|
~muto ();
|
||||||
@ -46,9 +46,9 @@ extern muto muto_start;
|
|||||||
/* Use a statically allocated buffer as the storage for a muto */
|
/* Use a statically allocated buffer as the storage for a muto */
|
||||||
#define new_muto(__inh, __name) \
|
#define new_muto(__inh, __name) \
|
||||||
({ \
|
({ \
|
||||||
static NO_COPY char __mbuf[sizeof(class muto) + 100] = {0}; \
|
static NO_COPY muto __mbuf; \
|
||||||
muto *m = muto_start.next; \
|
(void) new ((char *) &__mbuf) muto (__inh, __name); \
|
||||||
muto_start.next = new (__mbuf) muto ((__inh), (__name)); \
|
__mbuf.next = muto_start.next; \
|
||||||
muto_start.next->next = m; \
|
muto_start.next = &__mbuf; \
|
||||||
muto_start.next; \
|
&__mbuf; \
|
||||||
})
|
})
|
||||||
|
@ -82,8 +82,6 @@ extern int dynamically_loaded;
|
|||||||
extern HANDLE hMainThread;
|
extern HANDLE hMainThread;
|
||||||
extern HANDLE hMainProc;
|
extern HANDLE hMainProc;
|
||||||
|
|
||||||
#include "sync.h"
|
|
||||||
|
|
||||||
/* Now that pinfo has been defined, include... */
|
/* Now that pinfo has been defined, include... */
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user