mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-20 16:01:10 +08:00
* 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>
|
||||
|
||||
* 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.
|
||||
|
@ -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
|
||||
|
@ -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() \
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ details. */
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "winsup.h"
|
||||
#include "sync.h"
|
||||
|
||||
extern BOOL allow_ntsec;
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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; \
|
||||
})
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user