* cygtls.h (_threadinfo::call): Remove regparm declaration to work around

compiler bug.
* autoload.cc (TryEnterCriticalSection): Remove.
* dcrt0.cc (dll_crt0_0): Delete inappropriate setting of _my_tls.stackptr to
NULL since it has really bad consequences.  Make 'si' an automatic variable.
* cygtls.cc (_threadinfo::init_thread): Correct thinko which caused thread list
to be allocated every time.
* cygtls.h (CYGTLS_PADSIZE): Define as const int.
* sync.h: Make multiple inclusion safe.
(muto::next): Eliminate.
(muto::exiting_thread): New variable.
(muto::set_exiting_thread): New function.
(new_muto): Change to use different section for mutos since c++ give
inexplicable warning in some cases otherwise.
(new_muto1): Ditto.
* dcrt0.cc (do_exit): Call muto::set_exiting_thread here.
* sync.cc (muto_start): Eliminate.
(muto::acquire): Always give exiting thread a lock.  Never give thread a lock
if exiting.
(muto::release): Ditto for releasing.
* dtable.cc (dtable::init_lock): Unline function and define here.
* dtable.h (lock_cs): Define as a muto since critical sections seem to work
oddly on Windows Me.
(lock): Accommodate switch to muto.
(unlock): Ditto.
* exceptions.cc (setup_handler): Don't worry about acquiring mutos since that
hasn't mattered for a long time.
(signal_exit): Ditto: muto stuff will be handled automatically on exit now.
* Makefile.in (DLL_IMPORTS): Link advapi32 to ensure proper DLL initialization.
* autoload.cc (RegCloseKey): Arbitrarily choose this function as a "seed" to
pull the advapi32 link library in.  So, comment out the autoloading.
* cygtls.cc (_threadinfo::init_thread): Just clear CYGTLS_PADSIZE.
(_threadinfo::remove): Add debugging.
(_threadinfo::find_tls): Ditto.
* cygtls.h (_threadinfo::padding): Make zero length (for now?).
* dcrt0.cc (dll_crt0_0): Move more initialization here from dll_crt0_1.
(dll_crt0_1): See above.
* dtable.h (dtable::lock): Remove commented out critical section locking.
* dtable.h (dtable::init_lock): Remove commented out critical section locking.
* dtable.h (dtable::unlock): Remove commented out critical section locking.
* exceptions.cc (interruptible): bool'ize.
* init.cc (threadfunc_fe): Revert to storing threadfunc at stack bottom.
(munge_threadfunc): Ditto.  Avoid adding overhead to calibration_thread.
(prime_threads): Don't initialize tls stuff.
(dll_entry): Make minor change to initialization order.
* tlsoffsets.h: Regenerate.
* sigproc.cc (wait_sig): Add sanity check for end of process thread exit.
* select.h: Make minor formatting change.
* Makefile.in: Add still more -fomit-frame-pointer functions.
* dtable.h (dtable::lock): New function.
(dtable::unlock): New function.
(dtable::init_lock): New function.
* cygheap.h (HEAP_TLS): Declare new enum value.
(init_cygheap::threadlist): Declare new array.
(init_cygheap::sthreads): Declare new variable.
(cygheap_fdmanip::~cygheap_fdmanip): Use new dtable lock/unlock functions.
(cygheap_fdnew::cygheap_fdnew): Ditto.
(cygheap_fdget::cygheap_fdget): Ditto.
* dtable.cc (dtable_init): Initialize fdtab critical section.
(dtable::fixup_after_fork): Ditto.
(dtable::fixup_after_exec): Ditto.
(dtable::dup2): Use lock/unlock calls to protect access to fdtab.
(dtable::find_fifo): Ditto.
(dtable::fixup_before_fork): Ditto.
(dtable::fixup_before_exec): Ditto.
(dtable::set_file_pointers_for_exec): Ditto.
(dtable::vfork_child_dup): Ditto.
(dtable::vfork_parent_restore): Ditto.
* syscalls.cc (close_all_files): Ditto.
* sync.h (muto::acquired): Declare new function.
(new_muto1): Declare new macro used to specify name of muto storage.
* sync.cc (muto::acquired): Define new function.
* cygthread.cc (cygthread::stub): Remove signal chain removal call since it is
handled during initialization now.
* cygthread.cc (cygthread::simplestub): Remove signal chain removal call since
it is handled during initialization now.
* cygtls.cc (sentry): New class used for locking.  Use throughout.
(_threadinfo::reset_exception): Don't pop stack.
(_threadinfo::find_tls): Move from exceptions.cc.
(_threadinfo::init_thread): Initialize array of threads rather than linked
list.  Take second argument indicating thread function for this thread.
(_threadinfo::remove): Search thread array rather than linked list.  Use sentry
to lock.  Only unlock if we got the lock.
(_threadinfo::find_tls): Ditto for first two.
(handle_threadlist_exception): Handle exceptions when manipulating the thread
list in case of premature thread termination.
(_threadinfo::init_threadlist_exceptions): Ditto.
* cygtls.h (TLS_STACK_SIZE): Decrease size.
(_threadinfo::padding): Add element to avoid overwriting lower part of stack.
(_threadinfo::remove): Add a "wait" argument to control how long we wait for a
lock before removing.
* exceptions.cc (init_exception_handler): Make global.  Take argument to
control exception handler being set.
(ctrl_c_handler): Wait forever when removing self from signal chain.
(_threadinfo::find_tls): Move to cygtls.cc.
(sig_handle): Reorganize detection for thread-specific signals.
* heap.cc (heap_init): Rework slightly.  Make fatal error more verbose.  Remove
malloc initialization since it can't happen during dll attach.
* init.cc (search_for): Move address to search for on stack here.
(threadfunc_ix): Ditto for stack offset.  Make shared so that stack walk
potentially only has to be done once when cygwin processes are running.
(threadfunc_fe): Use standard tls to store thread function (may change back
later).
(calibration_thread): New function.  Potentially called to find threadfunc_ix.
(munge_threadfunc): Search for "search_for" value on stack.  Output warning
when thread func not found on stack.  Use standard tls to store thread
function.
(prime_threads): New function.  Called to prime thread front end.
(dll_entry): Call dll_crt0_0 here when DLL_PROCESS_ATTACH.  Call prime_threads
here.  Try to remove thread from signal list here.
* sigproc.cc (wait_sig): Initialize threadlist exception stuff here.
* thread.cc (pthread::exit): Pass argument to signal list remove function.
* thread.h: Remove obsolete *ResourceLock defines.
* tlsoffsets.h: Regenerate.
* winsup.h (spf): Define temporary debug macro to be deleted later.
* dcrt0.cc (dll_crt0_0): New function, called during DLL initialization.
Mainly consists of code pulled from dll_crt0_1.
(dll_crt0_1): See above.
(_dll_crt0): Wait for initial calibration thread to complete, if appropriate.
Move some stuff to dll_crt0_0.
(initialize_main_tls): Accommodate argument change to
_thread_info::init_thread.
* fork.cc (fork_child): Ditto.
(sync_with_child): Fix debug message.
* external.cc (cygwin_internal): Remove special considerations for
uninitialized dll since initialization happens during dll attach now.
* dlfcn.cc (dlopen): Remove obsolete *ResourceLock calls.
(dlclose): Ditto.
* cygheap.h (init_cygheap::close_ctty): Declare new function.
* cygheap.cc (init_cygheap::close_ctty): Define new function.
* syscalls.cc (close_all_files): Use close_ctty.
(setsid): Ditto.
* cygthread.cc (cygthread::stub): Remove exception initialization.
* cygthread.cc (cygthread::stub): Remove exception initialization.
(cygthread::simplestub): Ditto.
* thread.cc (pthread::thread_init_wrapper): Ditto.
* cygtls.cc (_last_thread): Make static.
(_threadinfo::call2): Initialize exception handler here.
(_threadinfo::find_tls): Move here.
* exceptions.cc (_threadinfo::find_tls): Move.
* dcrt0.cc (__api_fatal): Add prefix info to message here rather than including
it in every call to function.
* winsup.h (api_fatal): Accommodate above change.
* debug.cc (add_handle): Don't do anything if cygheap not around.
(mark_closed): Ditto.
* dll_init.cc (dll_list::detach): Fix debug output.
* fork.cc (sync_with_child): Ditto.
(vfork): Improve debug output.
* heap.cc (heap_init): Ditto.
* exceptions.cc (try_to_debug): Clarify message when debugger attaches.
This commit is contained in:
Christopher Faylor 2004-01-14 15:45:37 +00:00
parent d858958426
commit 2d1d1eb1e4
37 changed files with 757 additions and 428 deletions

View File

@ -1,3 +1,198 @@
2004-01-14 Christopher Faylor <cgf@redhat.com>
* cygtls.h (_threadinfo::call): Remove regparm declaration to work
around compiler bug.
2004-01-13 Christopher Faylor <cgf@redhat.com>
* autoload.cc (TryEnterCriticalSection): Remove.
* dcrt0.cc (dll_crt0_0): Delete inappropriate setting of
_my_tls.stackptr to NULL since it has really bad consequences. Make
'si' an automatic variable.
2004-01-13 Christopher Faylor <cgf@redhat.com>
* cygtls.cc (_threadinfo::init_thread): Correct thinko which caused
thread list to be allocated every time.
* cygtls.h (CYGTLS_PADSIZE): Define as const int.
* sync.h: Make multiple inclusion safe.
(muto::next): Eliminate.
(muto::exiting_thread): New variable.
(muto::set_exiting_thread): New function.
(new_muto): Change to use different section for mutos since c++ give
inexplicable warning in some cases otherwise.
(new_muto1): Ditto.
* dcrt0.cc (do_exit): Call muto::set_exiting_thread here.
* sync.cc (muto_start): Eliminate.
(muto::acquire): Always give exiting thread a lock. Never give thread
a lock if exiting.
(muto::release): Ditto for releasing.
* dtable.cc (dtable::init_lock): Unline function and define here.
* dtable.h (lock_cs): Define as a muto since critical sections seem to
work oddly on Windows Me.
(lock): Accommodate switch to muto.
(unlock): Ditto.
* exceptions.cc (setup_handler): Don't worry about acquiring mutos
since that hasn't mattered for a long time.
(signal_exit): Ditto: muto stuff will be handled automatically on exit
now.
2004-01-12 Christopher Faylor <cgf@redhat.com>
* Makefile.in (DLL_IMPORTS): Link advapi32 to ensure proper DLL
initialization.
* autoload.cc (RegCloseKey): Arbitrarily choose this function as a
"seed" to pull the advapi32 link library in. So, comment out the
autoloading.
* cygtls.cc (_threadinfo::init_thread): Just clear CYGTLS_PADSIZE.
(_threadinfo::remove): Add debugging.
(_threadinfo::find_tls): Ditto.
* cygtls.h (_threadinfo::padding): Make zero length (for now?).
* dcrt0.cc (dll_crt0_0): Move more initialization here from dll_crt0_1.
(dll_crt0_1): See above.
* dtable.h (dtable::lock): Remove commented out critical section
locking.
* dtable.h (dtable::init_lock): Remove commented out critical section
locking.
* dtable.h (dtable::unlock): Remove commented out critical section
locking.
* exceptions.cc (interruptible): bool'ize.
* init.cc (threadfunc_fe): Revert to storing threadfunc at stack
bottom.
(munge_threadfunc): Ditto. Avoid adding overhead to
calibration_thread.
(prime_threads): Don't initialize tls stuff.
(dll_entry): Make minor change to initialization order.
* tlsoffsets.h: Regenerate.
* sigproc.cc (wait_sig): Add sanity check for end of process thread
exit.
* select.h: Make minor formatting change.
2004-01-10 Christopher Faylor <cgf@redhat.com>
* Makefile.in: Add still more -fomit-frame-pointer functions.
* dtable.h (dtable::lock): New function.
(dtable::unlock): New function.
(dtable::init_lock): New function.
* cygheap.h (HEAP_TLS): Declare new enum value.
(init_cygheap::threadlist): Declare new array.
(init_cygheap::sthreads): Declare new variable.
(cygheap_fdmanip::~cygheap_fdmanip): Use new dtable lock/unlock
functions.
(cygheap_fdnew::cygheap_fdnew): Ditto.
(cygheap_fdget::cygheap_fdget): Ditto.
* dtable.cc (dtable_init): Initialize fdtab critical section.
(dtable::fixup_after_fork): Ditto.
(dtable::fixup_after_exec): Ditto.
(dtable::dup2): Use lock/unlock calls to protect access to fdtab.
(dtable::find_fifo): Ditto.
(dtable::fixup_before_fork): Ditto.
(dtable::fixup_before_exec): Ditto.
(dtable::set_file_pointers_for_exec): Ditto.
(dtable::vfork_child_dup): Ditto.
(dtable::vfork_parent_restore): Ditto.
* syscalls.cc (close_all_files): Ditto.
* sync.h (muto::acquired): Declare new function.
(new_muto1): Declare new macro used to specify name of muto storage.
* sync.cc (muto::acquired): Define new function.
* cygthread.cc (cygthread::stub): Remove signal chain removal call
since it is handled during initialization now.
* cygthread.cc (cygthread::simplestub): Remove signal chain removal
call since it is handled during initialization now.
* cygtls.cc (sentry): New class used for locking. Use throughout.
(_threadinfo::reset_exception): Don't pop stack.
(_threadinfo::find_tls): Move from exceptions.cc.
(_threadinfo::init_thread): Initialize array of threads rather than
linked list. Take second argument indicating thread function for this
thread.
(_threadinfo::remove): Search thread array rather than linked list.
Use sentry to lock. Only unlock if we got the lock.
(_threadinfo::find_tls): Ditto for first two.
(handle_threadlist_exception): Handle exceptions when manipulating the
thread list in case of premature thread termination.
(_threadinfo::init_threadlist_exceptions): Ditto.
* cygtls.h (TLS_STACK_SIZE): Decrease size.
(_threadinfo::padding): Add element to avoid overwriting lower part of
stack.
(_threadinfo::remove): Add a "wait" argument to control how long we
wait for a lock before removing.
* exceptions.cc (init_exception_handler): Make global. Take argument
to control exception handler being set.
(ctrl_c_handler): Wait forever when removing self from signal chain.
(_threadinfo::find_tls): Move to cygtls.cc.
(sig_handle): Reorganize detection for thread-specific signals.
* heap.cc (heap_init): Rework slightly. Make fatal error more verbose.
Remove malloc initialization since it can't happen during dll attach.
* init.cc (search_for): Move address to search for on stack here.
(threadfunc_ix): Ditto for stack offset. Make shared so that stack
walk potentially only has to be done once when cygwin processes are
running.
(threadfunc_fe): Use standard tls to store thread function (may change
back later).
(calibration_thread): New function. Potentially called to find
threadfunc_ix.
(munge_threadfunc): Search for "search_for" value on stack. Output
warning when thread func not found on stack. Use standard tls to store
thread function.
(prime_threads): New function. Called to prime thread front end.
(dll_entry): Call dll_crt0_0 here when DLL_PROCESS_ATTACH. Call
prime_threads here. Try to remove thread from signal list here.
* sigproc.cc (wait_sig): Initialize threadlist exception stuff here.
* thread.cc (pthread::exit): Pass argument to signal list remove
function.
* thread.h: Remove obsolete *ResourceLock defines.
* tlsoffsets.h: Regenerate.
* winsup.h (spf): Define temporary debug macro to be deleted later.
* dcrt0.cc (dll_crt0_0): New function, called during DLL
initialization. Mainly consists of code pulled from dll_crt0_1.
(dll_crt0_1): See above.
(_dll_crt0): Wait for initial calibration thread to complete, if
appropriate. Move some stuff to dll_crt0_0.
(initialize_main_tls): Accommodate argument change to
_thread_info::init_thread.
* fork.cc (fork_child): Ditto.
(sync_with_child): Fix debug message.
* external.cc (cygwin_internal): Remove special considerations for
uninitialized dll since initialization happens during dll attach now.
* dlfcn.cc (dlopen): Remove obsolete *ResourceLock calls.
(dlclose): Ditto.
2004-01-05 Christopher Faylor <cgf@redhat.com>
* cygheap.h (init_cygheap::close_ctty): Declare new function.
* cygheap.cc (init_cygheap::close_ctty): Define new function.
* syscalls.cc (close_all_files): Use close_ctty.
(setsid): Ditto.
* cygthread.cc (cygthread::stub): Remove exception initialization.
* cygthread.cc (cygthread::stub): Remove exception initialization.
(cygthread::simplestub): Ditto.
* thread.cc (pthread::thread_init_wrapper): Ditto.
* cygtls.cc (_last_thread): Make static.
(_threadinfo::call2): Initialize exception handler here.
(_threadinfo::find_tls): Move here.
* exceptions.cc (_threadinfo::find_tls): Move.
* dcrt0.cc (__api_fatal): Add prefix info to message here rather than
including it in every call to function.
* winsup.h (api_fatal): Accommodate above change.
* debug.cc (add_handle): Don't do anything if cygheap not around.
(mark_closed): Ditto.
* dll_init.cc (dll_list::detach): Fix debug output.
* fork.cc (sync_with_child): Ditto.
(vfork): Improve debug output.
* heap.cc (heap_init): Ditto.
* exceptions.cc (try_to_debug): Clarify message when debugger attaches.
2004-01-03 Christopher Faylor <cgf@redhat.com> 2004-01-03 Christopher Faylor <cgf@redhat.com>
* exceptions.cc (_threadinfo::interrupt_now): Avoid double call to * exceptions.cc (_threadinfo::interrupt_now): Avoid double call to

View File

@ -113,7 +113,7 @@ EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o
MALLOC_OFILES=@MALLOC_OFILES@ MALLOC_OFILES=@MALLOC_OFILES@
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
MT_SAFE_OBJECTS:= MT_SAFE_OBJECTS:=
# Please maintain this list in sorted order, with maximum files per 80 col line # Please maintain this list in sorted order, with maximum files per 80 col line
@ -254,6 +254,8 @@ regexec_CFLAGS=-fomit-frame-pointer
regfree_CFLAGS=-fomit-frame-pointer regfree_CFLAGS=-fomit-frame-pointer
shared_CFLAGS:=-fomit-frame-pointer shared_CFLAGS:=-fomit-frame-pointer
smallprint_CFLAGS:=-fomit-frame-pointer smallprint_CFLAGS:=-fomit-frame-pointer
sysconf_CFLAGS:=-fomit-frame-pointer
uinfo_CFLAGS:=-fomit-frame-pointer
endif endif
.PHONY: all force dll_ofiles install all_target install_target all_host install_host \ .PHONY: all force dll_ofiles install all_target install_target all_host install_host \

View File

@ -354,7 +354,7 @@ LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32)
LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32) LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32)
LoadDLLfunc (OpenProcessToken, 12, advapi32) LoadDLLfunc (OpenProcessToken, 12, advapi32)
LoadDLLfunc (OpenThreadToken, 16, advapi32) LoadDLLfunc (OpenThreadToken, 16, advapi32)
LoadDLLfunc (RegCloseKey, 4, advapi32) // LoadDLLfunc (RegCloseKey, 4, advapi32)
LoadDLLfunc (RegCreateKeyExA, 36, advapi32) LoadDLLfunc (RegCreateKeyExA, 36, advapi32)
LoadDLLfunc (RegDeleteKeyA, 8, advapi32) LoadDLLfunc (RegDeleteKeyA, 8, advapi32)
LoadDLLfunc (RegDeleteValueA, 8, advapi32) LoadDLLfunc (RegDeleteValueA, 8, advapi32)
@ -515,7 +515,6 @@ LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1) LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1) LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1) LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1)
LoadDLLfunc (TryEnterCriticalSection, 4, kernel32)
LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1) LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
LoadDLLfuncEx (waveOutOpen, 24, winmm, 1) LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)

View File

@ -172,6 +172,16 @@ cygheap_fixup_in_child (bool execed)
} }
} }
void
init_cygheap::close_ctty ()
{
debug_printf ("closing cygheap->ctty %p", cygheap->ctty);
cygheap->ctty->close ();
if (cygheap->ctty_on_hold == cygheap->ctty)
cygheap->ctty_on_hold = NULL;
cygheap->ctty = NULL;
}
#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1))) #define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
static void *__stdcall static void *__stdcall
@ -206,6 +216,7 @@ cygheap_init ()
cygheap->fdtab.init (); cygheap->fdtab.init ();
if (!cygheap->sigs) if (!cygheap->sigs)
sigalloc (); sigalloc ();
if (!cygheap->shared_prefix) if (!cygheap->shared_prefix)
cygheap->shared_prefix = cstrdup ( cygheap->shared_prefix = cstrdup (
wincap.has_terminal_services () wincap.has_terminal_services ()

View File

@ -19,6 +19,7 @@ enum cygheap_types
HEAP_MOUNT, HEAP_MOUNT,
HEAP_SIGS, HEAP_SIGS,
HEAP_ARCHETYPES, HEAP_ARCHETYPES,
HEAP_TLS,
HEAP_1_START, HEAP_1_START,
HEAP_1_STR, HEAP_1_STR,
HEAP_1_ARGV, HEAP_1_ARGV,
@ -263,7 +264,10 @@ struct init_cygheap
fhandler_tty_slave *ctty; /* Current tty */ fhandler_tty_slave *ctty; /* Current tty */
fhandler_tty_slave *ctty_on_hold; fhandler_tty_slave *ctty_on_hold;
struct _threadinfo **threadlist;
size_t sthreads;
int open_fhs; int open_fhs;
void close_ctty ();
}; };
#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536)) #define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536))
@ -282,7 +286,7 @@ class cygheap_fdmanip
virtual ~cygheap_fdmanip () virtual ~cygheap_fdmanip ()
{ {
if (locked) if (locked)
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip"); cygheap->fdtab.unlock ();
} }
void release () void release ()
{ {
@ -308,7 +312,7 @@ class cygheap_fdnew : public cygheap_fdmanip
cygheap_fdnew (int seed_fd = -1, bool lockit = true) cygheap_fdnew (int seed_fd = -1, bool lockit = true)
{ {
if (lockit) if (lockit)
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew"); cygheap->fdtab.lock ();
if (seed_fd < 0) if (seed_fd < 0)
fd = cygheap->fdtab.find_unused_handle (); fd = cygheap->fdtab.find_unused_handle ();
else else
@ -322,7 +326,7 @@ class cygheap_fdnew : public cygheap_fdmanip
{ {
set_errno (EMFILE); set_errno (EMFILE);
if (lockit) if (lockit)
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew"); cygheap->fdtab.unlock ();
locked = false; locked = false;
} }
} }
@ -335,7 +339,7 @@ class cygheap_fdget : public cygheap_fdmanip
cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true) cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
{ {
if (lockit) if (lockit)
SetResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget"); cygheap->fdtab.lock ();
if (fd >= 0 && fd < (int) cygheap->fdtab.size if (fd >= 0 && fd < (int) cygheap->fdtab.size
&& *(fh = cygheap->fdtab + fd) != NULL) && *(fh = cygheap->fdtab + fd) != NULL)
{ {
@ -348,7 +352,7 @@ class cygheap_fdget : public cygheap_fdmanip
if (do_set_errno) if (do_set_errno)
set_errno (EBADF); set_errno (EBADF);
if (lockit) if (lockit)
ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget"); cygheap->fdtab.unlock ();
locked = false; locked = false;
} }
} }

View File

@ -32,12 +32,6 @@ bool NO_COPY cygthread::exiting;
DWORD WINAPI DWORD WINAPI
cygthread::stub (VOID *arg) cygthread::stub (VOID *arg)
{ {
exception_list except_entry;
/* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
init_exceptions (&except_entry);
_my_tls.remove (); // Remove me from signal chain -- not signalable.
cygthread *info = (cygthread *) arg; cygthread *info = (cygthread *) arg;
if (info->arg == cygself) if (info->arg == cygself)
{ {
@ -57,6 +51,7 @@ cygthread::stub (VOID *arg)
info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
} }
} }
while (1) while (1)
{ {
if (!info->__name) if (!info->__name)
@ -92,12 +87,6 @@ cygthread::stub (VOID *arg)
DWORD WINAPI DWORD WINAPI
cygthread::simplestub (VOID *arg) cygthread::simplestub (VOID *arg)
{ {
exception_list except_entry;
/* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
init_exceptions (&except_entry);
_my_tls.remove (); // Remove me from signal chain -- not signalable.
cygthread *info = (cygthread *) arg; cygthread *info = (cygthread *) arg;
info->stack_ptr = &arg; info->stack_ptr = &arg;
info->ev = info->h; info->ev = info->h;

View File

@ -19,12 +19,10 @@ class cygthread
VOID *arg; VOID *arg;
bool is_freerange; bool is_freerange;
static bool exiting; static bool exiting;
static void stub2 (void *, void *);
static DWORD WINAPI simplestub (VOID *);
static void simplestub2 (void *, void *);
void terminate_thread (); void terminate_thread ();
public: public:
static DWORD WINAPI stub (VOID *); static DWORD WINAPI stub (VOID *);
static DWORD WINAPI simplestub (VOID *);
static DWORD main_thread_id; static DWORD main_thread_id;
static const char * name (DWORD = 0); static const char * name (DWORD = 0);
cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *);
@ -43,7 +41,6 @@ class cygthread
(void) CloseHandle (h); (void) CloseHandle (h);
h = NULL; h = NULL;
} }
}; };
#define cygself NULL #define cygself NULL

View File

@ -1,6 +1,6 @@
/* cygtls.h /* cygtls.cc
Copyright 2003 Red Hat, Inc. Copyright 2003, 2004 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@ -11,11 +11,48 @@ details. */
#include "cygtls.h" #include "cygtls.h"
#include "assert.h" #include "assert.h"
#include <syslog.h> #include <syslog.h>
#include <signal.h>
#include "exceptions.h"
#include "sync.h"
#include "cygerrno.h"
#include "path.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "cygthread.h"
static _threadinfo NO_COPY dummy_thread; class sentry
_threadinfo NO_COPY *_last_thread = &dummy_thread; {
static muto *lock;
int destroy;
public:
void init ();
bool acquired () {return lock->acquired ();}
sentry () {destroy = 0;}
sentry (DWORD wait) {destroy = lock->acquire (wait);}
~sentry () {if (destroy) lock->release ();}
friend void _threadinfo::init ();
};
CRITICAL_SECTION NO_COPY _threadinfo::protect_linked_list; muto NO_COPY *sentry::lock;
static size_t NO_COPY nthreads;
#define THREADLIST_CHUNK 256
void
_threadinfo::init ()
{
if (cygheap->threadlist)
memset (cygheap->threadlist, 0, cygheap->sthreads * sizeof (cygheap->threadlist[0]));
else
{
cygheap->sthreads = THREADLIST_CHUNK;
cygheap->threadlist = (_threadinfo **) ccalloc (HEAP_TLS, cygheap->sthreads,
sizeof (cygheap->threadlist[0]));
}
new_muto1 (sentry::lock, sentry_lock);
}
void void
_threadinfo::set_state (bool is_exception) _threadinfo::set_state (bool is_exception)
@ -32,7 +69,6 @@ _threadinfo::reset_exception ()
debug_printf ("resetting stack after an exception stack %p, stackptr %p", stack, stackptr); debug_printf ("resetting stack after an exception stack %p, stackptr %p", stack, stackptr);
#endif #endif
set_state (false); set_state (false);
stackptr--;
} }
} }
@ -47,22 +83,22 @@ _threadinfo::call (DWORD (*func) (void *, void *), void *arg)
void void
_threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf) _threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
{ {
_my_tls.init_thread (buf); exception_list except_entry;
ExitThread (func (arg, buf)); /* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
init_exceptions (&except_entry);
_my_tls.init_thread (buf, func);
DWORD res = func (arg, buf);
_my_tls.remove (INFINITE);
ExitThread (res);
} }
void void
_threadinfo::init () _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
{
InitializeCriticalSection (&protect_linked_list);
}
void
_threadinfo::init_thread (void *x)
{ {
if (x) if (x)
{ {
memset (this, 0, sizeof (*this)); memset (this, 0, CYGTLS_PADSIZE);
stackptr = stack; stackptr = stack;
if (_GLOBAL_REENT) if (_GLOBAL_REENT)
{ {
@ -76,30 +112,40 @@ _threadinfo::init_thread (void *x)
locals.process_logmask = LOG_UPTO (LOG_DEBUG); locals.process_logmask = LOG_UPTO (LOG_DEBUG);
} }
EnterCriticalSection (&protect_linked_list);
prev = _last_thread;
_last_thread->next = this;
_last_thread = this;
LeaveCriticalSection (&protect_linked_list);
set_state (false); set_state (false);
errno_addr = &(local_clib._errno); errno_addr = &(local_clib._errno);
if ((void *) func == (void *) cygthread::stub
|| (void *) func == (void *) cygthread::simplestub)
return;
sentry here (INFINITE);
if (nthreads >= cygheap->sthreads)
{
cygheap->threadlist = (_threadinfo **)
crealloc (cygheap->threadlist, (cygheap->sthreads += THREADLIST_CHUNK)
* sizeof (cygheap->threadlist[0]));
memset (cygheap->threadlist + nthreads, 0, THREADLIST_CHUNK * sizeof (cygheap->threadlist[0]));
}
cygheap->threadlist[nthreads++] = this;
} }
void void
_threadinfo::remove () _threadinfo::remove (DWORD wait)
{ {
EnterCriticalSection (&protect_linked_list); debug_printf ("wait %p\n", wait);
if (prev) sentry here (wait);
if (here.acquired ())
{ {
prev->next = next; for (size_t i = 0; i < nthreads; i++)
if (next) if (&_my_tls == cygheap->threadlist[i])
next->prev = prev; {
if (this == _last_thread) if (i < --nthreads)
_last_thread = prev; cygheap->threadlist[i] = cygheap->threadlist[nthreads];
prev = next = NULL; break;
}
} }
LeaveCriticalSection (&protect_linked_list);
} }
void void
@ -123,3 +169,48 @@ _threadinfo::pop ()
return res; return res;
} }
#define BAD_IX ((size_t) -1)
static size_t NO_COPY threadlist_ix = BAD_IX;
_threadinfo *
_threadinfo::find_tls (int sig)
{
debug_printf ("sig %d\n", sig);
sentry here (INFINITE);
__asm__ volatile (".equ _threadlist_exception_return,.");
_threadinfo *res = NULL;
for (threadlist_ix = 0; threadlist_ix < nthreads; threadlist_ix++)
if (sigismember (&(cygheap->threadlist[threadlist_ix]->sigwait_mask), sig))
{
res = cygheap->threadlist[threadlist_ix];
break;
}
threadlist_ix = BAD_IX;
return res;
}
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
static int
handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *, void *)
{
small_printf ("in handle_threadlist_exception!\n");
if (e->ExceptionCode != STATUS_ACCESS_VIOLATION)
return 1;
sentry here;
if (threadlist_ix != BAD_IX || !here.acquired ())
return 1;
extern void *threadlist_exception_return;
cygheap->threadlist[threadlist_ix]->remove (INFINITE);
threadlist_ix = 0;
RtlUnwind (frame, threadlist_exception_return, e, 0);
return 0;
}
void
_threadinfo::init_threadlist_exceptions (exception_list *el)
{
extern void init_exception_handler (exception_list *, exception_handler *);
init_exception_handler (el, handle_threadlist_exception);
}

View File

@ -28,7 +28,7 @@ details. */
# define UNLEN 256 # define UNLEN 256
#endif #endif
#define TLS_STACK_SIZE 1024 #define TLS_STACK_SIZE 256
#pragma pack(push,4) #pragma pack(push,4)
struct _local_storage struct _local_storage
@ -110,15 +110,16 @@ struct _threadinfo
__stack_t *stackptr; __stack_t *stackptr;
int sig; int sig;
__stack_t stack[TLS_STACK_SIZE]; __stack_t stack[TLS_STACK_SIZE];
unsigned padding[0];
/*gentls_offsets*/ /*gentls_offsets*/
static CRITICAL_SECTION protect_linked_list; static CRITICAL_SECTION protect_linked_list;
static void init (); static void init ();
void init_thread (void *) __attribute__ ((regparm (2))); void init_thread (void *, DWORD (*) (void *, void *));
static void call (DWORD (*) (void *, void *), void *) __attribute__ ((regparm (3))); static void call (DWORD (*) (void *, void *), void *);
static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3))); static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
static struct _threadinfo *find_tls (int sig); static struct _threadinfo *find_tls (int sig);
void remove (); void remove (DWORD);
void push (__stack_t, bool = false); void push (__stack_t, bool = false);
__stack_t pop (); __stack_t pop ();
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;} bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
@ -128,6 +129,7 @@ struct _threadinfo
__attribute__((regparm(3))); __attribute__((regparm(3)));
void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr) void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr)
__attribute__((regparm(3))); __attribute__((regparm(3)));
void init_threadlist_exceptions (struct _exception_list *);
operator HANDLE () const {return tid->win32_obj_id;} operator HANDLE () const {return tid->win32_obj_id;}
/*gentls_offsets*/ /*gentls_offsets*/
}; };
@ -140,5 +142,5 @@ extern _threadinfo *_main_tls;
#define __getreent() (&_my_tls.local_clib) #define __getreent() (&_my_tls.local_clib)
#define CYGTLS_PADSIZE (sizeof (_threadinfo)) const int CYGTLS_PADSIZE = (((char *) _main_tls->padding) - ((char *) _main_tls));
#endif /*_CYGTLS_H*/ #endif /*_CYGTLS_H*/

View File

@ -35,6 +35,7 @@ details. */
#include "dll_init.h" #include "dll_init.h"
#include "cygthread.h" #include "cygthread.h"
#include "sync.h" #include "sync.h"
#include "heap.h"
#define MAX_AT_FILE_LEVEL 10 #define MAX_AT_FILE_LEVEL 10
@ -55,11 +56,13 @@ bool strip_title_path;
bool allow_glob = true; bool allow_glob = true;
codepage_type current_codepage = ansi_cp; codepage_type current_codepage = ansi_cp;
static NO_COPY int mypid = 0;
int __argc_safe; int __argc_safe;
int _declspec(dllexport) __argc; int _declspec(dllexport) __argc;
char _declspec(dllexport) **__argv; char _declspec(dllexport) **__argv;
vfork_save NO_COPY *main_vfork = NULL; vfork_save NO_COPY *main_vfork;
static int NO_COPY envc;
char NO_COPY **envp;
extern "C" void __sinit (_reent *); extern "C" void __sinit (_reent *);
@ -519,41 +522,127 @@ alloc_stack (child_info_fork *ci)
return; return;
} }
/* Take over from libc's crt0.o and start the application. Note the #ifdef DEBUGGING
various special cases when Cygwin DLL is being runtime loaded (as void
opposed to being link-time loaded by Cygwin apps) from a non break_here ()
cygwin app via LoadLibrary. */
static void
dll_crt0_1 (char *)
{ {
/* According to onno@stack.urc.tue.nl, the exception handler record must debug_printf ("break here");
be on the stack. */ }
/* FIXME: Verify forked children get their exception handler set up ok. */ #endif
exception_list cygwin_except_entry;
/* Initialize SIGSEGV handling, etc. */ static void
init_exceptions (&cygwin_except_entry); initial_env ()
{
char buf[CYG_MAX_PATH + 1];
#ifdef DEBUGGING
DWORD len;
if (GetEnvironmentVariable ("CYGWIN_SLEEP", buf, sizeof (buf) - 1))
{
DWORD ms = atoi (buf);
buf[0] = '\0';
len = GetModuleFileName (NULL, buf, CYG_MAX_PATH);
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
while (ms--)
Sleep (1);
}
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
{
char buf1[CYG_MAX_PATH + 1];
len = GetModuleFileName (NULL, buf1, CYG_MAX_PATH);
strlwr (buf1);
strlwr (buf);
char *p = strchr (buf, ':');
if (!p)
p = (char *) "gdb.exe -nw";
else
*p++ = '\0';
if (strstr (buf1, buf))
{
error_start_init (p);
try_to_debug ();
break_here ();
}
}
#endif
/* Set the os_being_run global. */ if (GetEnvironmentVariable ("CYGWIN_TESTING", buf, sizeof (buf) - 1))
_cygwin_testing = 1;
}
void __stdcall
dll_crt0_0 ()
{
wincap.init (); wincap.init ();
initial_env ();
char zeros[sizeof (child_proc_info->zero)] = {0};
init_console_handler ();
init_global_security ();
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
GetCurrentProcess (), &hMainProc, 0, FALSE,
DUPLICATE_SAME_ACCESS))
hMainProc = GetCurrentProcess ();
DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
&hMainThread, 0, false, DUPLICATE_SAME_ACCESS);
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
STARTUPINFO si;
GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2;
int mypid = 0;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0)
child_proc_info = NULL;
else
{
if ((child_proc_info->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
multiple_cygwin_problem ("proc", child_proc_info->intro, 0);
else if (child_proc_info->intro == PROC_MAGIC_GENERIC
&& child_proc_info->magic != CHILD_INFO_MAGIC)
multiple_cygwin_problem ("proc", child_proc_info->magic,
CHILD_INFO_MAGIC);
else if (child_proc_info->cygheap != (void *) &_cygheap_start)
multiple_cygwin_problem ("cygheap", (DWORD) child_proc_info->cygheap,
(DWORD) &_cygheap_start);
unsigned should_be_cb = 0;
switch (child_proc_info->type)
{
case _PROC_FORK:
user_data->forkee = child_proc_info->cygpid;
should_be_cb = sizeof (child_info_fork);
/* fall through */;
case _PROC_SPAWN:
case _PROC_EXEC:
if (!should_be_cb)
should_be_cb = sizeof (child_info);
if (should_be_cb != child_proc_info->cb)
multiple_cygwin_problem ("proc size", child_proc_info->cb, should_be_cb);
else if (sizeof (fhandler_union) != child_proc_info->fhandler_union_cb)
multiple_cygwin_problem ("fhandler size", child_proc_info->fhandler_union_cb, sizeof (fhandler_union));
else
{
cygwin_user_h = child_proc_info->user_h;
mypid = child_proc_info->cygpid;
break;
}
default:
system_printf ("unknown exec type %d", child_proc_info->type);
/* intentionally fall through */
case _PROC_WHOOPS:
child_proc_info = NULL;
break;
}
}
device::init (); device::init ();
check_sanity_and_sync (user_data);
do_global_ctors (&__CTOR_LIST__, 1);
/* Nasty static stuff needed by newlib -- point to a local copy of
the reent stuff.
Note: this MUST be done here (before the forkee code) as the
fork copy code doesn't copy the data in libccrt0.cc (that's why we
pass in the per_process struct into the .dll from libccrt0). */
user_data->resourcelocks->Init ();
user_data->threadinterface->Init ();
winpids::init (); winpids::init ();
do_global_ctors (&__CTOR_LIST__, 1);
int envc = 0; cygthread::init ();
char **envp = NULL;
if (!child_proc_info) if (!child_proc_info)
memory_init (); memory_init ();
@ -591,6 +680,7 @@ dll_crt0_1 (char *)
__argv = spawn_info->moreinfo->argv; __argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp; envp = spawn_info->moreinfo->envp;
envc = spawn_info->moreinfo->envc; envc = spawn_info->moreinfo->envc;
envp = spawn_info->moreinfo->envp;
cygheap->fdtab.fixup_after_exec (spawn_info->parent); cygheap->fdtab.fixup_after_exec (spawn_info->parent);
signal_fixup_after_exec (); signal_fixup_after_exec ();
CloseHandle (spawn_info->parent); CloseHandle (spawn_info->parent);
@ -607,9 +697,44 @@ dll_crt0_1 (char *)
CloseHandle (child_proc_info->pppid_handle); CloseHandle (child_proc_info->pppid_handle);
} }
_threadinfo::init ();
/* Initialize events */
events_init ();
/* Init global well known SID objects */
cygsid::init ();
cygheap->cwd.init ();
}
/* Take over from libc's crt0.o and start the application. Note the
various special cases when Cygwin DLL is being runtime loaded (as
opposed to being link-time loaded by Cygwin apps) from a non
cygwin app via LoadLibrary. */
static void
dll_crt0_1 (char *)
{
/* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
check_sanity_and_sync (user_data);
malloc_init ();
/* Initialize SIGSEGV handling, etc. */
init_exceptions (&cygwin_except_entry);
/* Nasty static stuff needed by newlib -- point to a local copy of
the reent stuff.
Note: this MUST be done here (before the forkee code) as the
fork copy code doesn't copy the data in libccrt0.cc (that's why we
pass in the per_process struct into the .dll from libccrt0). */
user_data->resourcelocks->Init ();
user_data->threadinterface->Init ();
ProtectHandle (hMainProc); ProtectHandle (hMainProc);
ProtectHandle (hMainThread); ProtectHandle (hMainThread);
cygthread::init ();
/* Initialize pthread mainthread when not forked and it is safe to call new, /* Initialize pthread mainthread when not forked and it is safe to call new,
otherwise it is reinitalized in fixup_after_fork */ otherwise it is reinitalized in fixup_after_fork */
@ -629,12 +754,6 @@ dll_crt0_1 (char *)
cygheap->fdtab.vfork_child_fixup (); cygheap->fdtab.vfork_child_fixup ();
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
/* Initialize events. */
events_init ();
cygheap->cwd.init ();
main_vfork = vfork_storage.create (); main_vfork = vfork_storage.create ();
cygbench ("pre-forkee"); cygbench ("pre-forkee");
@ -663,9 +782,6 @@ dll_crt0_1 (char *)
} }
#endif #endif
/* Init global well known SID objects */
cygsid::init ();
/* Initialize our process table entry. */ /* Initialize our process table entry. */
pinfo_init (envp, envc); pinfo_init (envp, envc);
@ -773,60 +889,13 @@ dll_crt0_1 (char *)
exit (user_data->main (__argc, __argv, *user_data->envptr)); exit (user_data->main (__argc, __argv, *user_data->envptr));
} }
#ifdef DEBUGGING
void
break_here ()
{
debug_printf ("break here");
}
#endif
void
initial_env ()
{
char buf[CYG_MAX_PATH + 1];
#ifdef DEBUGGING
DWORD len;
if (GetEnvironmentVariable ("CYGWIN_SLEEP", buf, sizeof (buf) - 1))
{
DWORD ms = atoi (buf);
buf[0] = '\0';
len = GetModuleFileName (NULL, buf, CYG_MAX_PATH);
console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf);
Sleep (ms);
}
if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1))
{
char buf1[CYG_MAX_PATH + 1];
len = GetModuleFileName (NULL, buf1, CYG_MAX_PATH);
strlwr (buf1);
strlwr (buf);
char *p = strchr (buf, ':');
if (!p)
p = (char *) "gdb.exe -nw";
else
*p++ = '\0';
if (strstr (buf1, buf))
{
error_start_init (p);
try_to_debug ();
break_here ();
}
}
#endif
if (GetEnvironmentVariable ("CYGWIN_TESTING", buf, sizeof (buf) - 1))
_cygwin_testing = 1;
}
struct _reent * struct _reent *
initialize_main_tls (char *padding) initialize_main_tls (char *padding)
{ {
if (!_main_tls) if (!_main_tls)
{ {
_threadinfo::init ();
_main_tls = &_my_tls; _main_tls = &_my_tls;
_main_tls->init_thread (padding); _main_tls->init_thread (padding, NULL);
} }
return &_main_tls->local_clib; return &_main_tls->local_clib;
} }
@ -840,77 +909,27 @@ initialize_main_tls (char *padding)
extern "C" void __stdcall extern "C" void __stdcall
_dll_crt0 () _dll_crt0 ()
{ {
initial_env (); extern HANDLE sync_startup;
char zeros[max (CYGTLS_PADSIZE, sizeof (child_proc_info->zero))] = {0}; if (sync_startup)
static NO_COPY STARTUPINFO si; {
(void) WaitForSingleObject (sync_startup, INFINITE);
CloseHandle (sync_startup);
}
main_environ = user_data->envptr; main_environ = user_data->envptr;
*main_environ = NULL; *main_environ = NULL;
init_console_handler (); if (child_proc_info && child_proc_info->type == _PROC_FORK)
init_global_security ();
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
GetCurrentProcess (), &hMainProc, 0, FALSE,
DUPLICATE_SAME_ACCESS))
hMainProc = GetCurrentProcess ();
DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
&hMainThread, 0, false, DUPLICATE_SAME_ACCESS);
GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0)
child_proc_info = NULL;
else
{
if ((child_proc_info->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
multiple_cygwin_problem ("proc", child_proc_info->intro, 0);
else if (child_proc_info->intro == PROC_MAGIC_GENERIC
&& child_proc_info->magic != CHILD_INFO_MAGIC)
multiple_cygwin_problem ("proc", child_proc_info->magic,
CHILD_INFO_MAGIC);
else if (child_proc_info->cygheap != (void *) &_cygheap_start)
multiple_cygwin_problem ("cygheap", (DWORD) child_proc_info->cygheap,
(DWORD) &_cygheap_start);
unsigned should_be_cb = 0;
switch (child_proc_info->type)
{
case _PROC_FORK:
user_data->forkee = child_proc_info->cygpid; user_data->forkee = child_proc_info->cygpid;
should_be_cb = sizeof (child_info_fork);
/* fall through */;
case _PROC_SPAWN:
case _PROC_EXEC:
if (!should_be_cb)
should_be_cb = sizeof (child_info);
if (should_be_cb != child_proc_info->cb)
multiple_cygwin_problem ("proc size", child_proc_info->cb, should_be_cb);
else if (sizeof (fhandler_union) != child_proc_info->fhandler_union_cb)
multiple_cygwin_problem ("fhandler size", child_proc_info->fhandler_union_cb, sizeof (fhandler_union));
else
{
cygwin_user_h = child_proc_info->user_h;
mypid = child_proc_info->cygpid;
break;
}
default:
system_printf ("unknown exec type %d", child_proc_info->type);
/* intentionally fall through */
case _PROC_WHOOPS:
child_proc_info = NULL;
break;
}
}
char padding[CYGTLS_PADSIZE];
_impure_ptr = &reent_data; _impure_ptr = &reent_data;
_impure_ptr->_stdin = &_impure_ptr->__sf[0]; _impure_ptr->_stdin = &_impure_ptr->__sf[0];
_impure_ptr->_stdout = &_impure_ptr->__sf[1]; _impure_ptr->_stdout = &_impure_ptr->__sf[1];
_impure_ptr->_stderr = &_impure_ptr->__sf[2]; _impure_ptr->_stderr = &_impure_ptr->__sf[2];
_impure_ptr->_current_locale = "C"; _impure_ptr->_current_locale = "C";
initialize_main_tls (zeros); initialize_main_tls (padding);
dll_crt0_1 (zeros); dll_crt0_1 (padding);
} }
void void
@ -970,6 +989,7 @@ do_exit (int status)
} }
EnterCriticalSection (&exit_lock); EnterCriticalSection (&exit_lock);
muto::set_exiting_thread ();
if (exit_state < ES_EVENTS_TERMINATE) if (exit_state < ES_EVENTS_TERMINATE)
{ {
exit_state = ES_EVENTS_TERMINATE; exit_state = ES_EVENTS_TERMINATE;
@ -1090,7 +1110,8 @@ __api_fatal (const char *fmt, ...)
va_list ap; va_list ap;
va_start (ap, fmt); va_start (ap, fmt);
__small_vsprintf (buf, fmt, ap); int n = __small_sprintf (buf, "%P (%u): *** ", cygwin_pid (GetCurrentProcessId ()));
__small_vsprintf (buf + n, fmt, ap);
va_end (ap); va_end (ap);
strcat (buf, "\n"); strcat (buf, "\n");
int len = strlen (buf); int len = strlen (buf);

View File

@ -112,6 +112,9 @@ add_handle (const char *func, int ln, HANDLE h, const char *name, bool inh)
handle_list *hl; handle_list *hl;
lock_debug here; lock_debug here;
if (!cygheap)
return;
if ((hl = find_handle (h))) if ((hl = find_handle (h)))
{ {
hl = hl->next; hl = hl->next;
@ -172,6 +175,9 @@ mark_closed (const char *func, int ln, HANDLE h, const char *name, bool force)
handle_list *hl; handle_list *hl;
lock_debug here; lock_debug here;
if (!cygheap)
return true;
if ((hl = find_handle (h)) && !force) if ((hl = find_handle (h)) && !force)
{ {
hl = hl->next; hl = hl->next;

View File

@ -83,8 +83,6 @@ get_full_path_of_dll (const char* str, char *name)
void * void *
dlopen (const char *name, int) dlopen (const char *name, int)
{ {
SetResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlopen");
void *ret; void *ret;
if (name == NULL) if (name == NULL)
@ -108,7 +106,6 @@ dlopen (const char *name, int)
set_dl_error ("dlopen"); set_dl_error ("dlopen");
debug_printf ("ret %p", ret); debug_printf ("ret %p", ret);
ReleaseResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlopen");
return ret; return ret;
} }
@ -125,8 +122,6 @@ dlsym (void *handle, const char *name)
int int
dlclose (void *handle) dlclose (void *handle)
{ {
SetResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlclose");
int ret = -1; int ret = -1;
void *temphandle = (void *) GetModuleHandle (NULL); void *temphandle = (void *) GetModuleHandle (NULL);
if (temphandle == handle || FreeLibrary ((HMODULE) handle)) if (temphandle == handle || FreeLibrary ((HMODULE) handle))
@ -134,8 +129,6 @@ dlclose (void *handle)
if (ret) if (ret)
set_dl_error ("dlclose"); set_dl_error ("dlclose");
CloseHandle ((HMODULE) temphandle); CloseHandle ((HMODULE) temphandle);
ReleaseResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlclose");
return ret; return ret;
} }

View File

@ -195,7 +195,7 @@ dll_list::detach (void *retaddr)
if (d->handle != h) if (d->handle != h)
continue; continue;
else if (d->count <= 0) else if (d->count <= 0)
system_printf ("WARNING: try to detach an already detached dll ..."); system_printf ("WARNING: trying to detach an already detached dll ...");
else if (--d->count == 0) else if (--d->count == 0)
{ {
d->p.run_dtors (); d->p.run_dtors ();

View File

@ -3,11 +3,9 @@
<title>cygwin_detach_dll</title> <title>cygwin_detach_dll</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_detach_dll</function></funcdef> <function>cygwin_detach_dll</function></funcdef>
<paramdef>int <parameter>dll_index</parameter></paramdef> <paramdef>int <parameter>dll_index</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
</sect1> </sect1>

View File

@ -33,19 +33,21 @@ details. */
#include "ntdll.h" #include "ntdll.h"
#include "tty.h" #include "tty.h"
static const char NO_COPY unknown_file[] = "some disk file";
static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
STD_ERROR_HANDLE}; STD_ERROR_HANDLE};
static const char *handle_to_fn (HANDLE, char *); static const char *handle_to_fn (HANDLE, char *);
static const char NO_COPY unknown_file[] = "some disk file";
/* Set aside space for the table of fds */ /* Set aside space for the table of fds */
void void
dtable_init (void) dtable_init ()
{ {
if (!cygheap->fdtab.size) if (!cygheap->fdtab.size)
cygheap->fdtab.extend (NOFILE_INCR); cygheap->fdtab.extend (NOFILE_INCR);
cygheap->fdtab.init_lock ();
} }
void __stdcall void __stdcall
@ -57,6 +59,12 @@ set_std_handle (int fd)
SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ()); SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ());
} }
void
dtable::init_lock ()
{
new_muto (lock_cs);
}
int int
dtable::extend (int howmuch) dtable::extend (int howmuch)
{ {
@ -490,7 +498,7 @@ dtable::dup2 (int oldfd, int newfd)
MALLOC_CHECK; MALLOC_CHECK;
debug_printf ("dup2 (%d, %d)", oldfd, newfd); debug_printf ("dup2 (%d, %d)", oldfd, newfd);
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); lock ();
if (not_open (oldfd)) if (not_open (oldfd))
{ {
@ -539,7 +547,7 @@ dtable::dup2 (int oldfd, int newfd)
done: done:
MALLOC_CHECK; MALLOC_CHECK;
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); unlock ();
syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd); syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd);
return res; return res;
@ -548,7 +556,7 @@ done:
fhandler_fifo * fhandler_fifo *
dtable::find_fifo (ATOM hill) dtable::find_fifo (ATOM hill)
{ {
SetResourceLock (LOCK_FD_LIST, READ_LOCK, "dup"); lock ();
for (unsigned i = 0; i < size; i++) for (unsigned i = 0; i < size; i++)
{ {
fhandler_base *fh = fds[i]; fhandler_base *fh = fds[i];
@ -614,7 +622,7 @@ dtable::select_except (int fd, select_record *s)
void void
dtable::fixup_before_fork (DWORD target_proc_id) dtable::fixup_before_fork (DWORD target_proc_id)
{ {
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_fork"); lock ();
fhandler_base *fh; fhandler_base *fh;
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL) if ((fh = fds[i]) != NULL)
@ -622,13 +630,13 @@ dtable::fixup_before_fork (DWORD target_proc_id)
debug_printf ("fd %d (%s)", i, fh->get_name ()); debug_printf ("fd %d (%s)", i, fh->get_name ());
fh->fixup_before_fork_exec (target_proc_id); fh->fixup_before_fork_exec (target_proc_id);
} }
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_fork"); unlock ();
} }
void void
dtable::fixup_before_exec (DWORD target_proc_id) dtable::fixup_before_exec (DWORD target_proc_id)
{ {
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec"); lock ();
fhandler_base *fh; fhandler_base *fh;
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL && !fh->get_close_on_exec ()) if ((fh = fds[i]) != NULL && !fh->get_close_on_exec ())
@ -636,18 +644,18 @@ dtable::fixup_before_exec (DWORD target_proc_id)
debug_printf ("fd %d (%s)", i, fh->get_name ()); debug_printf ("fd %d (%s)", i, fh->get_name ());
fh->fixup_before_fork_exec (target_proc_id); fh->fixup_before_fork_exec (target_proc_id);
} }
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec"); unlock ();
} }
void void
dtable::set_file_pointers_for_exec () dtable::set_file_pointers_for_exec ()
{ {
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "set_file_pointers_for_exec"); lock ();
fhandler_base *fh; fhandler_base *fh;
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND) if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND)
SetFilePointer (fh->get_handle (), 0, 0, FILE_END); SetFilePointer (fh->get_handle (), 0, 0, FILE_END);
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec"); unlock ();
} }
void void
@ -655,6 +663,7 @@ dtable::fixup_after_exec (HANDLE parent)
{ {
first_fd_for_open = 0; first_fd_for_open = 0;
fhandler_base *fh; fhandler_base *fh;
cygheap->fdtab.init_lock ();
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL) if ((fh = fds[i]) != NULL)
{ {
@ -680,6 +689,7 @@ void
dtable::fixup_after_fork (HANDLE parent) dtable::fixup_after_fork (HANDLE parent)
{ {
fhandler_base *fh; fhandler_base *fh;
cygheap->fdtab.init_lock ();
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL) if ((fh = fds[i]) != NULL)
{ {
@ -699,7 +709,7 @@ int
dtable::vfork_child_dup () dtable::vfork_child_dup ()
{ {
fhandler_base **newtable; fhandler_base **newtable;
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); lock ();
newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof (fds[0])); newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof (fds[0]));
int res = 1; int res = 1;
@ -731,21 +741,21 @@ out:
/* Restore impersonation */ /* Restore impersonation */
cygheap->user.reimpersonate (); cygheap->user.reimpersonate ();
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); unlock ();
return 1; return 1;
} }
void void
dtable::vfork_parent_restore () dtable::vfork_parent_restore ()
{ {
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "restore"); lock ();
close_all_files (); close_all_files ();
fhandler_base **deleteme = fds; fhandler_base **deleteme = fds;
fds = fds_on_hold; fds = fds_on_hold;
fds_on_hold = NULL; fds_on_hold = NULL;
cfree (deleteme); cfree (deleteme);
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "restore"); unlock ();
cygheap->ctty = cygheap->ctty_on_hold; // revert cygheap->ctty = cygheap->ctty_on_hold; // revert
if (cygheap->ctty) if (cygheap->ctty)

View File

@ -12,6 +12,7 @@ details. */
#define NOFILE_INCR 32 #define NOFILE_INCR 32
#include "thread.h" #include "thread.h"
#include "sync.h"
class suffix_info; class suffix_info;
class fhandler_fifo; class fhandler_fifo;
@ -19,6 +20,7 @@ class fhandler_fifo;
#define BFH_OPTS (PC_NULLEMPTY | PC_FULL | PC_POSIX) #define BFH_OPTS (PC_NULLEMPTY | PC_FULL | PC_POSIX)
class dtable class dtable
{ {
muto *lock_cs;
fhandler_base **fds; fhandler_base **fds;
fhandler_base **fds_on_hold; fhandler_base **fds_on_hold;
fhandler_base **archetypes; fhandler_base **archetypes;
@ -27,6 +29,9 @@ class dtable
static const int initial_archetype_size = 8; static const int initial_archetype_size = 8;
int first_fd_for_open; int first_fd_for_open;
int cnt_need_fixup_before; int cnt_need_fixup_before;
void lock () {lock_cs->acquire ();}
void unlock () {lock_cs->release ();}
void init_lock ();
public: public:
size_t size; size_t size;
@ -50,11 +55,9 @@ public:
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
inline int not_open (int fd) inline int not_open (int fd)
{ {
SetResourceLock (LOCK_FD_LIST, READ_LOCK, "not_open"); lock ();
int res = fd < 0 || fd >= (int) size || fds[fd] == NULL; int res = fd < 0 || fd >= (int) size || fds[fd] == NULL;
unlock ();
ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "not open");
return res; return res;
} }
int find_unused_handle (int start); int find_unused_handle (int start);
@ -76,6 +79,11 @@ public:
fhandler_base *find_archetype (device& dev); fhandler_base *find_archetype (device& dev);
fhandler_base **add_archetype (); fhandler_base **add_archetype ();
void delete_archetype (fhandler_base *); void delete_archetype (fhandler_base *);
friend void dtable_init ();
friend void __stdcall close_all_files ();
friend class cygheap_fdmanip;
friend class cygheap_fdget;
friend class cygheap_fdnew;
}; };
fhandler_base *build_fh_dev (const device&, const char * = NULL); fhandler_base *build_fh_dev (const device&, const char * = NULL);

View File

@ -3,7 +3,6 @@
<title>cygwin_attach_handle_to_fd</title> <title>cygwin_attach_handle_to_fd</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" int <funcdef>extern "C" int
<function>cygwin_attach_handle_to_fd</function></funcdef> <function>cygwin_attach_handle_to_fd</function></funcdef>
<paramdef>char *<parameter>name</parameter></paramdef> <paramdef>char *<parameter>name</parameter></paramdef>
@ -11,7 +10,6 @@
<paramdef>HANDLE <parameter>handle</parameter></paramdef> <paramdef>HANDLE <parameter>handle</parameter></paramdef>
<paramdef>int <parameter>bin</parameter></paramdef> <paramdef>int <parameter>bin</parameter></paramdef>
<paramdef>int <parameter>access</parameter></paramdef> <paramdef>int <parameter>access</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>This function can be used to turn a Win32 "handle" into a <para>This function can be used to turn a Win32 "handle" into a

View File

@ -98,18 +98,22 @@ NO_COPY static struct
// of code that handles exceptions. The x86 on the other hand uses segment // of code that handles exceptions. The x86 on the other hand uses segment
// register fs, offset 0 to point to the current exception handler. // register fs, offset 0 to point to the current exception handler.
asm (".equ __except_list,0"); extern exception_list *_except_list asm ("%fs:0");
extern exception_list *_except_list asm ("%fs:__except_list"); void
init_exception_handler (exception_list *el, exception_handler *eh)
static void
init_exception_handler (exception_list *el)
{ {
el->handler = handle_exceptions; el->handler = eh;
el->prev = _except_list; el->prev = _except_list;
_except_list = el; _except_list = el;
} }
extern "C" void
init_exceptions (exception_list *el)
{
init_exception_handler (el, handle_exceptions);
}
void void
init_console_handler () init_console_handler ()
{ {
@ -118,12 +122,6 @@ init_console_handler ()
system_printf ("SetConsoleCtrlHandler failed, %E"); system_printf ("SetConsoleCtrlHandler failed, %E");
} }
extern "C" void
init_exceptions (exception_list *el)
{
init_exception_handler (el);
}
extern "C" void extern "C" void
error_start_init (const char *buf) error_start_init (const char *buf)
{ {
@ -363,6 +361,8 @@ try_to_debug (bool waitloop)
} }
} }
small_printf ("*** starting debugger for pid %u\n",
cygwin_pid (GetCurrentProcessId ()));
BOOL dbg; BOOL dbg;
dbg = CreateProcess (NULL, dbg = CreateProcess (NULL,
debugger_command, debugger_command,
@ -383,9 +383,9 @@ try_to_debug (bool waitloop)
return 1; return 1;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
while (!being_debugged ()) while (!being_debugged ())
Sleep (0); low_priority_sleep (0);
Sleep (2000); small_printf ("*** continuing pid %u from debugger call\n",
small_printf ("*** continuing from debugger call\n"); cygwin_pid (GetCurrentProcessId ()));
} }
SetThreadPriority (GetCurrentThread (), prio); SetThreadPriority (GetCurrentThread (), prio);
@ -615,7 +615,7 @@ sig_handle_tty_stop (int sig)
} }
} }
int bool
interruptible (DWORD pc) interruptible (DWORD pc)
{ {
int res; int res;
@ -633,11 +633,11 @@ interruptible (DWORD pc)
GetThreadContext. These resolve to a strange allocation base. GetThreadContext. These resolve to a strange allocation base.
These should *never* be treated as interruptible. */ These should *never* be treated as interruptible. */
if (!h || m.State != MEM_COMMIT) if (!h || m.State != MEM_COMMIT)
res = 0; res = false;
else if (h == user_data->hmodule) else if (h == user_data->hmodule)
res = 1; res = true;
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2)) else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
res = 0; res = false;
else else
res = !strncasematch (windows_system_directory, checkdir, res = !strncasematch (windows_system_directory, checkdir,
windows_system_directory_length); windows_system_directory_length);
@ -666,7 +666,8 @@ _threadinfo::interrupt_setup (int sig, void *handler,
/* Clear any waiting threads prior to dispatching to handler function */ /* Clear any waiting threads prior to dispatching to handler function */
int res = SetEvent (signal_arrived); // For an EINTR case int res = SetEvent (signal_arrived); // For an EINTR case
proc_subproc (PROC_CLEARWAIT, 1); proc_subproc (PROC_CLEARWAIT, 1);
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); sigproc_printf ("armed signal_arrived %p, sig %d, res %d", signal_arrived,
sig, res);
} }
bool bool
@ -762,26 +763,16 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
// FIXME - add check for reentering of DLL here // FIXME - add check for reentering of DLL here
muto *m;
/* FIXME: Make multi-thread aware */
for (m = muto_start.next; m != NULL; m = m->next)
if (m->unstable () || m->owner () == cygthread::main_thread_id)
{
sigproc_printf ("suspended thread owns a muto (%s)", m->name);
goto resume_thread;
}
cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext (hth, &cx)) if (!GetThreadContext (hth, &cx))
system_printf ("couldn't get context of main thread, %E"); system_printf ("couldn't get context of main thread, %E");
else if (interruptible (cx.Eip)) else if (interruptible (cx.Eip))
interrupted = tls->interrupt_now (&cx, sig, handler, siga); interrupted = tls->interrupt_now (&cx, sig, handler, siga);
resume_thread:
res = ResumeThread (hth); res = ResumeThread (hth);
if (interrupted) if (interrupted)
break; break;
sigproc_printf ("couldn't interrupt. trying again."); sigproc_printf ("couldn't interrupt. trying again.");
low_priority_sleep (0); low_priority_sleep (0);
} }
@ -801,7 +792,7 @@ static BOOL WINAPI
ctrl_c_handler (DWORD type) ctrl_c_handler (DWORD type)
{ {
static bool saw_close; static bool saw_close;
_my_tls.remove (); _my_tls.remove (INFINITE);
/* Return FALSE to prevent an "End task" dialog box from appearing /* Return FALSE to prevent an "End task" dialog box from appearing
for each Cygwin process window that's open when the computer for each Cygwin process window that's open when the computer
@ -892,19 +883,6 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask)
return; return;
} }
extern _threadinfo *_last_thread;
_threadinfo *
_threadinfo::find_tls (int sig)
{
EnterCriticalSection (&protect_linked_list);
for (_threadinfo *t = _last_thread; t ; t = t->prev)
if (sigismember (&t->sigwait_mask, sig))
return t;
LeaveCriticalSection (&protect_linked_list);
return NULL;
}
int __stdcall int __stdcall
sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls) sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
{ {
@ -924,15 +902,15 @@ sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
int rc = 1; int rc = 1;
bool insigwait_mask = tls ? sigismember (&tls->sigwait_mask, sig) : false; bool insigwait_mask = tls ? sigismember (&tls->sigwait_mask, sig) : false;
bool special_case = ISSTATE (myself, PID_STOPPED) || main_vfork->pid;
bool masked = sigismember (&mask, sig);
if (sig != SIGKILL && sig != SIGSTOP if (sig != SIGKILL && sig != SIGSTOP
&& (sigismember (&mask, sig) && (special_case || main_vfork->pid || masked || insigwait_mask
|| (tls || (tls && sigismember (&tls->sigmask, sig))))
&& (insigwait_mask || sigismember (&tls->sigmask, sig)))
|| main_vfork->pid
|| ISSTATE (myself, PID_STOPPED)))
{ {
sigproc_printf ("signal %d blocked", sig); sigproc_printf ("signal %d blocked", sig);
if (insigwait_mask || (tls = _threadinfo::find_tls (sig)) != NULL) if ((!special_case && !masked)
&& (insigwait_mask || (tls = _threadinfo::find_tls (sig)) != NULL))
goto thread_specific; goto thread_specific;
rc = -1; rc = -1;
goto done; goto done;
@ -1045,12 +1023,6 @@ signal_exit (int rc)
(void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); (void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE);
(void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
/* Unlock any main thread mutos since we're executing with prejudice. */
muto *m;
for (m = muto_start.next; m != NULL; m = m->next)
if (m->unstable () || m->owner () == cygthread::main_thread_id)
m->reset ();
user_data->resourcelocks->Delete (); user_data->resourcelocks->Delete ();
user_data->resourcelocks->Init (); user_data->resourcelocks->Init ();
@ -1114,6 +1086,7 @@ call_signal_handler_now ()
sa_flags = _my_tls.sa_flags; sa_flags = _my_tls.sa_flags;
int sig = _my_tls.sig; int sig = _my_tls.sig;
void (*sigfunc) (int) = _my_tls.func; void (*sigfunc) (int) = _my_tls.func;
(void) _my_tls.pop (); (void) _my_tls.pop ();
#ifdef DEBUGGING #ifdef DEBUGGING
if (_my_tls.stackptr > (_my_tls.stack + 1)) if (_my_tls.stackptr > (_my_tls.stack + 1))

View File

@ -135,16 +135,6 @@ cygwin_internal (cygwin_getinfo_types t, ...)
{ {
va_list arg; va_list arg;
va_start (arg, t); va_start (arg, t);
if (t != CW_USER_DATA)
{
wincap.init ();
if (!myself)
{
memory_init ();
malloc_init ();
set_myself (1);
}
}
switch (t) switch (t)
{ {

View File

@ -3,12 +3,10 @@
<title>cygwin_internal</title> <title>cygwin_internal</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" DWORD <funcdef>extern "C" DWORD
<function>cygwin_internal</function></funcdef> <function>cygwin_internal</function></funcdef>
<paramdef>cygwin_getinfo_types <parameter>t</parameter></paramdef> <paramdef>cygwin_getinfo_types <parameter>t</parameter></paramdef>
<paramdef><parameter>...</parameter></paramdef> <paramdef><parameter>...</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>This function gives you access to various internal data and functions. <para>This function gives you access to various internal data and functions.

View File

@ -167,8 +167,8 @@ sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
*/ */
if (errcode != STATUS_CONTROL_C_EXIT) if (errcode != STATUS_CONTROL_C_EXIT)
{ {
system_printf ("child %d(%p) died before initialization with status code %p", system_printf ("child %u(%p) died before initialization with status code %p",
pi.dwProcessId, pi.hProcess, errcode); cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
system_printf ("*** child state %s", s); system_printf ("*** child state %s", s);
#ifdef DEBUGGING #ifdef DEBUGGING
abort (); abort ();
@ -263,7 +263,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
if (fork_info->stacksize) if (fork_info->stacksize)
{ {
_main_tls = &_my_tls; _main_tls = &_my_tls;
_main_tls->init_thread (NULL); _main_tls->init_thread (NULL, NULL);
_main_tls->local_clib = *_impure_ptr; _main_tls->local_clib = *_impure_ptr;
_impure_ptr = &_main_tls->local_clib; _impure_ptr = &_main_tls->local_clib;
} }
@ -721,6 +721,7 @@ vfork ()
vf->pgid = myself->pgid; vf->pgid = myself->pgid;
cygheap->ctty_on_hold = cygheap->ctty; cygheap->ctty_on_hold = cygheap->ctty;
vf->open_fhs = cygheap->open_fhs; vf->open_fhs = cygheap->open_fhs;
debug_printf ("cygheap->ctty_on_hold %p, cygheap->open_fhs %d", cygheap->ctty_on_hold, cygheap->open_fhs);
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1; int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
debug_printf ("%d = vfork()", res); debug_printf ("%d = vfork()", res);
call_signal_handler_now (); // FIXME: racy call_signal_handler_now (); // FIXME: racy

View File

@ -31,7 +31,6 @@ extern "C" size_t getpagesize ();
#define MINHEAP_SIZE (4 * 1024 * 1024) #define MINHEAP_SIZE (4 * 1024 * 1024)
/* Initialize the heap at process start up. */ /* Initialize the heap at process start up. */
void void
heap_init () heap_init ()
{ {
@ -64,12 +63,11 @@ heap_init ()
/* total size commited in parent */ /* total size commited in parent */
DWORD allocsize = (char *) cygheap->user_heap.top - DWORD allocsize = (char *) cygheap->user_heap.top -
(char *) cygheap->user_heap.base; (char *) cygheap->user_heap.base;
/* round up by chunk size */
DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
/* Loop until we've managed to reserve an adequate amount of memory. */ /* Loop until we've managed to reserve an adequate amount of memory. */
char *p; char *p;
for (;;) DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
while (1)
{ {
p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size, p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
MEM_RESERVE, PAGE_READWRITE); MEM_RESERVE, PAGE_READWRITE);
@ -78,8 +76,13 @@ heap_init ()
if ((reserve_size -= page_const) <= allocsize) if ((reserve_size -= page_const) <= allocsize)
break; break;
} }
if (!p)
api_fatal ("couldn't allocate cygwin heap, %E, base %p, top %p, "
"reserve_size %d, allocsize %d, page_const %d",
cygheap->user_heap.base, cygheap->user_heap.top,
reserve_size, allocsize, page_const);
if (p != cygheap->user_heap.base) if (p != cygheap->user_heap.base)
api_fatal ("heap allocated but not at %p", cygheap->user_heap.base); api_fatal ("heap allocated at wrong address %p (mapped) != %p (expected)", p, cygheap->user_heap.base);
if (!VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE)) if (!VirtualAlloc (cygheap->user_heap.base, allocsize, MEM_COMMIT, PAGE_READWRITE))
api_fatal ("MEM_COMMIT failed, %E"); api_fatal ("MEM_COMMIT failed, %E");
} }
@ -87,7 +90,7 @@ heap_init ()
debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base, debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base,
cygheap->user_heap.top); cygheap->user_heap.top);
page_const--; page_const--;
malloc_init (); // malloc_init ();
} }
#define pround(n) (((size_t)(n) + page_const) & ~page_const) #define pround(n) (((size_t)(n) + page_const) & ~page_const)

View File

@ -16,51 +16,95 @@ details. */
#include "cygtls.h" #include "cygtls.h"
int NO_COPY dynamically_loaded; int NO_COPY dynamically_loaded;
static char *search_for = (char *) cygthread::stub;
static unsigned threadfunc_ix __attribute__((section ("cygwin_dll_common"), shared)) = 0;
DWORD tls_func;
HANDLE sync_startup;
#define OLDFUNC_OFFSET -1
static void WINAPI static void WINAPI
threadfunc_fe (VOID *arg) threadfunc_fe (VOID *arg)
{ {
_threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[-1]), arg); _threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
// void *threadfunc = (void *) TlsGetValue (tls_func);
// TlsFree (tls_func);
// _threadinfo::call ((DWORD (*) (void *, void *)) (threadfunc), arg);
}
static DWORD WINAPI
calibration_thread (VOID *arg)
{
ExitThread (0);
} }
static void static void
munge_threadfunc (HANDLE cygwin_hmodule) munge_threadfunc (HANDLE cygwin_hmodule)
{ {
char **ebp = (char **) __builtin_frame_address (0); char **ebp = (char **) __builtin_frame_address (0);
static unsigned threadfunc_ix;
if (!threadfunc_ix) if (!threadfunc_ix)
{ {
for (char **peb = ebp; peb < (char **) _tlsbase; peb++) for (char **peb = ebp; peb < (char **) _tlsbase; peb++)
if (*peb == (char *) cygthread::stub) if (*peb == search_for)
{ {
threadfunc_ix = peb - ebp; threadfunc_ix = peb - ebp;
goto foundit; goto foundit;
} }
#ifdef DEBUGGING
system_printf ("non-fatal warning: unknown thread! search_for %p, cygthread::stub %p, calibration_thread %p, possible func offset %p",
search_for, cygthread::stub, calibration_thread, ebp[137]);
#endif
try_to_debug ();
return; return;
} }
foundit: foundit:
char *threadfunc = ebp[threadfunc_ix]; char *threadfunc = ebp[threadfunc_ix];
if (threadfunc == (char *) calibration_thread)
/* no need for the overhead */;
else
{
ebp[threadfunc_ix] = (char *) threadfunc_fe; ebp[threadfunc_ix] = (char *) threadfunc_fe;
((char **) _tlsbase)[-1] = threadfunc; ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
// TlsSetValue (tls_func, (void *) threadfunc);
}
} }
void
prime_threads ()
{
// tls_func = TlsAlloc ();
if (!threadfunc_ix)
{
DWORD id;
search_for = (char *) calibration_thread;
sync_startup = CreateThread (NULL, 0, calibration_thread, 0, 0, &id);
}
}
extern void __stdcall dll_crt0_0 ();
extern "C" int WINAPI extern "C" int WINAPI
dll_entry (HANDLE h, DWORD reason, void *static_load) dll_entry (HANDLE h, DWORD reason, void *static_load)
{ {
switch (reason) switch (reason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
prime_threads ();
dynamically_loaded = (static_load == NULL); dynamically_loaded = (static_load == NULL);
// __cygwin_user_data.impure_ptr = &_my_tls.local_clib; // __cygwin_user_data.impure_ptr = &_my_tls.local_clib;
_my_tls.stackptr = NULL; dll_crt0_0 ();
// small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
munge_threadfunc (h); munge_threadfunc (h);
// small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
_my_tls.remove (0);
break; break;
} }
return 1; return 1;

View File

@ -316,6 +316,7 @@ void
malloc_init () malloc_init ()
{ {
new_muto (mallock); new_muto (mallock);
/* Check if mallock is provided by application. If so, redirect all /* Check if mallock is provided by application. If so, redirect all
calls to malloc/free/realloc to application provided. This may calls to 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

View File

@ -2,12 +2,10 @@
<title>cygwin_posix_to_win32_path_list</title> <title>cygwin_posix_to_win32_path_list</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_posix_to_win32_path_list</function></funcdef> <function>cygwin_posix_to_win32_path_list</function></funcdef>
<paramdef>const char *<parameter>posix</parameter></paramdef> <paramdef>const char *<parameter>posix</parameter></paramdef>
<paramdef>char *<parameter>win32</parameter></paramdef> <paramdef>char *<parameter>win32</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Given a POSIX path-style string (i.e. /foo:/bar) convert it to <para>Given a POSIX path-style string (i.e. /foo:/bar) convert it to
@ -41,12 +39,10 @@ cygwin_posix_to_win32_path_list_buf_size</link></para>
<title>cygwin_win32_to_posix_path_list</title> <title>cygwin_win32_to_posix_path_list</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_win32_to_posix_path_list</function></funcdef> <function>cygwin_win32_to_posix_path_list</function></funcdef>
<paramdef>const char *<parameter>win32</parameter></paramdef> <paramdef>const char *<parameter>win32</parameter></paramdef>
<paramdef>char *<parameter>posix</parameter></paramdef> <paramdef>char *<parameter>posix</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Given a Win32 path-style string (i.e. d:\;e:\bar) convert it to <para>Given a Win32 path-style string (i.e. d:\;e:\bar) convert it to
@ -62,11 +58,9 @@ cygwin_win32_to_posix_path_list_buf_size</link></para>
<title>cygwin_posix_to_win32_path_list_buf_size</title> <title>cygwin_posix_to_win32_path_list_buf_size</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" int <funcdef>extern "C" int
<function>cygwin_posix_to_win32_path_list_buf_size</function></funcdef> <function>cygwin_posix_to_win32_path_list_buf_size</function></funcdef>
<paramdef>const char *<parameter>path_list</parameter></paramdef> <paramdef>const char *<parameter>path_list</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Returns the number of bytes needed to hold the result of calling <para>Returns the number of bytes needed to hold the result of calling
@ -79,11 +73,9 @@ cygwin_posix_to_win32_path_list</link>.</para>
<title>cygwin_win32_to_posix_path_list_buf_size</title> <title>cygwin_win32_to_posix_path_list_buf_size</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" int <funcdef>extern "C" int
<function>cygwin_win32_to_posix_path_list_buf_size</function></funcdef> <function>cygwin_win32_to_posix_path_list_buf_size</function></funcdef>
<paramdef>const char *<parameter>path_list</parameter></paramdef> <paramdef>const char *<parameter>path_list</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Tells you how many bytes are needed for the results of <link <para>Tells you how many bytes are needed for the results of <link
@ -96,12 +88,10 @@ cygwin_win32_to_posix_path_list</link>.</para>
<title>cygwin_conv_to_posix_path</title> <title>cygwin_conv_to_posix_path</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_conv_to_posix_path</function></funcdef> <function>cygwin_conv_to_posix_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>posix_path</parameter></paramdef> <paramdef>char *<parameter>posix_path</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Converts a Win32 path to a POSIX path. If <para>Converts a Win32 path to a POSIX path. If
@ -117,12 +107,10 @@ size; use MAX_PATH if needed.</para>
<title>cygwin_conv_to_win32_path</title> <title>cygwin_conv_to_win32_path</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_conv_to_win32_path</function></funcdef> <function>cygwin_conv_to_win32_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>win32_path</parameter></paramdef> <paramdef>char *<parameter>win32_path</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Converts a POSIX path to a Win32 path. If <para>Converts a POSIX path to a Win32 path. If
@ -137,12 +125,10 @@ size; use MAX_PATH if needed.</para>
<title>cygwin_conv_to_full_posix_path</title> <title>cygwin_conv_to_full_posix_path</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_conv_to_full_posix_path</function></funcdef> <function>cygwin_conv_to_full_posix_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>posix_path</parameter></paramdef> <paramdef>char *<parameter>posix_path</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Converts a Win32 path to a POSIX path. If <para>Converts a Win32 path to a POSIX path. If
@ -158,12 +144,10 @@ buffer of sufficient size; use MAX_PATH if needed.</para>
<title>cygwin_conv_to_full_win32_path</title> <title>cygwin_conv_to_full_win32_path</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_conv_to_full_win32_path</function></funcdef> <function>cygwin_conv_to_full_win32_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>win32_path</parameter></paramdef> <paramdef>char *<parameter>win32_path</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Converts a POSIX path to a Win32 path. If <para>Converts a POSIX path to a Win32 path. If
@ -179,11 +163,9 @@ buffer of sufficient size; use MAX_PATH if needed.</para>
<title>cygwin_posix_path_list_p</title> <title>cygwin_posix_path_list_p</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" int <funcdef>extern "C" int
<function>posix_path_list_p</function></funcdef> <function>posix_path_list_p</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef> <paramdef>const char *<parameter>path</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>This function tells you if the supplied <para>This function tells you if the supplied
@ -200,14 +182,12 @@ parameter.</para>
<title>cygwin_split_path</title> <title>cygwin_split_path</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_split_path</function> <function>cygwin_split_path</function>
</funcdef> </funcdef>
<paramdef>const char * <parameter>path</parameter></paramdef> <paramdef>const char * <parameter>path</parameter></paramdef>
<paramdef>char * <parameter>dir</parameter></paramdef> <paramdef>char * <parameter>dir</parameter></paramdef>
<paramdef>char * <parameter>file</parameter></paramdef> <paramdef>char * <parameter>file</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Split a path into the directory and the file portions. Both <para>Split a path into the directory and the file portions. Both

View File

@ -610,12 +610,10 @@ pinfo::release ()
<title>cygwin_winpid_to_pid</title> <title>cygwin_winpid_to_pid</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" pid_t <funcdef>extern "C" pid_t
<function>cygwin_winpid_to_pid</function> <function>cygwin_winpid_to_pid</function>
</funcdef> </funcdef>
<paramdef>int <parameter>winpid</parameter></paramdef> <paramdef>int <parameter>winpid</parameter></paramdef>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Given a windows pid, converts to the corresponding Cygwin <para>Given a windows pid, converts to the corresponding Cygwin

View File

@ -1,6 +1,6 @@
/* select.h /* select.h
Copyright 1998, 1999, 2000, 2001 Red Hat, Inc. Copyright 1998, 1999, 2000, 2001, 2004 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -52,5 +52,4 @@ extern "C" int PASCAL win32_select(int, fd_set*, fd_set*, fd_set*, const struct
* type coercion need to appease confused prototypes * type coercion need to appease confused prototypes
*/ */
#define WINSOCK_SELECT(nfd, rd, wr, ex, timeo) \ #define WINSOCK_SELECT(nfd, rd, wr, ex, timeo) \
win32_select (nfd, (fd_set *)rd, (fd_set *)wr, (fd_set *)ex, timeo) win32_select (nfd, (fd_set *) rd, (fd_set *) wr, (fd_set *) ex, timeo)

View File

@ -3,11 +3,9 @@
<title>cygwin_getshared</title> <title>cygwin_getshared</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>shared_info * <funcdef>shared_info *
<function>cygwin_getshared</function></funcdef> <function>cygwin_getshared</function></funcdef>
<void> <void>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para>Returns a pointer to an internal Cygwin memory structure <para>Returns a pointer to an internal Cygwin memory structure

View File

@ -1,6 +1,6 @@
/* sigproc.cc: inter/intra signal and sub process handler /* sigproc.cc: inter/intra signal and sub process handler
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Written by Christopher Faylor Written by Christopher Faylor
@ -32,6 +32,7 @@ details. */
#include "cygtls.h" #include "cygtls.h"
#include "sigproc.h" #include "sigproc.h"
#include "perthread.h" #include "perthread.h"
#include "exceptions.h"
/* /*
* Convenience defines * Convenience defines
@ -1105,12 +1106,17 @@ wait_sig (VOID *self)
SetEvent (wait_sig_inited); SetEvent (wait_sig_inited);
sigtid = GetCurrentThreadId (); sigtid = GetCurrentThreadId ();
exception_list el;
_my_tls.init_threadlist_exceptions (&el);
for (;;) for (;;)
{ {
DWORD nb; DWORD nb;
sigpacket pack; sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL)) if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break; break;
if (myself->sendsig == INVALID_HANDLE_VALUE)
break;
if (nb != sizeof (pack)) if (nb != sizeof (pack))
{ {

View File

@ -2,11 +2,9 @@
<title>cygwin_stackdump</title> <title>cygwin_stackdump</title>
<funcsynopsis> <funcsynopsis>
<funcprototype>
<funcdef>extern "C" void <funcdef>extern "C" void
<function>cygwin_stackdump</function></funcdef> <function>cygwin_stackdump</function></funcdef>
<void> <void>
</funcprototype>
</funcsynopsis> </funcsynopsis>
<para> Outputs a stackdump to stderr from the called location. <para> Outputs a stackdump to stderr from the called location.

View File

@ -23,10 +23,10 @@ details. */
#include "sync.h" #include "sync.h"
#include "security.h" #include "security.h"
muto NO_COPY muto_start;
#undef WaitForSingleObject #undef WaitForSingleObject
DWORD NO_COPY muto::exiting_thread;
/* Constructor */ /* Constructor */
muto * muto *
muto::init (const char *s) muto::init (const char *s)
@ -40,8 +40,6 @@ muto::init (const char *s)
return NULL; return NULL;
} }
name = s; name = s;
next = muto_start.next;
muto_start.next = this;
return this; return this;
} }
@ -71,6 +69,8 @@ int
muto::acquire (DWORD ms) muto::acquire (DWORD ms)
{ {
DWORD this_tid = GetCurrentThreadId (); DWORD this_tid = GetCurrentThreadId ();
if (exiting_thread)
return this_tid == exiting_thread;
if (tid != this_tid) if (tid != this_tid)
{ {
@ -113,6 +113,8 @@ int
muto::release () muto::release ()
{ {
DWORD this_tid = GetCurrentThreadId (); DWORD this_tid = GetCurrentThreadId ();
if (exiting_thread)
return this_tid == exiting_thread;
if (tid != this_tid || !visits) if (tid != this_tid || !visits)
{ {
@ -135,6 +137,12 @@ muto::release ()
return 1; /* success. */ return 1; /* success. */
} }
bool
muto::acquired ()
{
return tid == GetCurrentThreadId ();
}
/* Call only when we're exiting. This is not thread safe. */ /* Call only when we're exiting. This is not thread safe. */
void void
muto::reset () muto::reset ()

View File

@ -10,17 +10,20 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#ifndef _SYNC_H
#define _SYNC_H
/* FIXME: Note that currently this class cannot be allocated via `new' since /* FIXME: Note that currently this class cannot be allocated via `new' since
there are issues with malloc and fork. */ there are issues with malloc and fork. */
class muto class muto
{ {
static DWORD exiting_thread;
LONG sync; /* Used to serialize access to this class. */ LONG sync; /* Used to serialize access to this class. */
LONG visits; /* Count of number of times a thread has called acquire. */ LONG visits; /* Count of number of times a thread has called acquire. */
LONG waiters; /* Number of threads waiting for lock. */ LONG waiters; /* Number of threads waiting for lock. */
HANDLE bruteforce; /* event handle used to control waiting for lock. */ HANDLE bruteforce; /* event handle used to control waiting for lock. */
DWORD tid; /* Thread Id of lock owner. */ DWORD tid; /* Thread Id of lock owner. */
public: public:
class muto *next; // class muto *next;
const char *name; const char *name;
/* The real constructor. */ /* The real constructor. */
@ -37,6 +40,8 @@ public:
DWORD owner () {return tid;} DWORD owner () {return tid;}
int unstable () {return !tid && (sync || waiters >= 0);} int unstable () {return !tid && (sync || waiters >= 0);}
void reset () __attribute__ ((regparm (1))); void reset () __attribute__ ((regparm (1)));
bool acquired ();
static void set_exiting_thread () {exiting_thread = GetCurrentThreadId ();}
}; };
extern muto muto_start; extern muto muto_start;
@ -44,6 +49,14 @@ 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(__name) \ #define new_muto(__name) \
({ \ ({ \
static muto __name##_storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy"))); \ static muto __name##_storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \
__name = __name##_storage.init (#__name); \ __name = __name##_storage.init (#__name); \
}) })
/* Use a statically allocated buffer as the storage for a muto */
#define new_muto1(__name, __storage) \
({ \
static muto __storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy1"))); \
__name = __storage.init (#__name); \
})
#endif /*_SYNC_H*/

View File

@ -87,7 +87,7 @@ static int __stdcall stat_worker (const char *name, struct __stat64 *buf,
void __stdcall void __stdcall
close_all_files (void) close_all_files (void)
{ {
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files"); cygheap->fdtab.lock ();
fhandler_base *fh; fhandler_base *fh;
for (int i = 0; i < (int) cygheap->fdtab.size; i++) for (int i = 0; i < (int) cygheap->fdtab.size; i++)
@ -101,13 +101,9 @@ close_all_files (void)
} }
if (cygheap->ctty) if (cygheap->ctty)
{ cygheap->close_ctty ();
debug_printf ("closing ctty");
cygheap->ctty->close ();
cygheap->ctty = NULL;
}
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files"); cygheap->fdtab.unlock ();
user_shared->delqueue.process_queue (); user_shared->delqueue.process_queue ();
} }
@ -332,10 +328,7 @@ setsid (void)
syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid, syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid,
myself->pgid, myself->ctty, cygheap->open_fhs); myself->pgid, myself->ctty, cygheap->open_fhs);
if (cygheap->ctty) if (cygheap->ctty)
{ cygheap->close_ctty ();
cygheap->ctty->close ();
cygheap->ctty = NULL;
}
return myself->sid; return myself->sid;
} }

View File

@ -297,7 +297,7 @@ pthread::exit (void *value_ptr)
::exit (0); ::exit (0);
else else
{ {
_my_tls.remove (); _my_tls.remove (INFINITE);
ExitThread (0); ExitThread (0);
} }
} }
@ -1783,9 +1783,6 @@ pthread::thread_init_wrapper (void *arg)
pthread *thread = (pthread *) arg; pthread *thread = (pthread *) arg;
_my_tls.tid = thread; _my_tls.tid = thread;
exception_list cygwin_except_entry;
init_exceptions (&cygwin_except_entry); /* Initialize SIGSEGV handling, etc. */
thread->mutex.lock (); thread->mutex.lock ();
// if thread is detached force cleanup on exit // if thread is detached force cleanup on exit

View File

@ -14,10 +14,7 @@ details. */
#ifndef _CYGNUS_THREADS_ #ifndef _CYGNUS_THREADS_
#define _CYGNUS_THREADS_ #define _CYGNUS_THREADS_
#define LOCK_FD_LIST 1 #define LOCK_MMAP_LIST 1
#define LOCK_MEMORY_LIST 2
#define LOCK_MMAP_LIST 3
#define LOCK_DLL_LIST 4
#define WRITE_LOCK 1 #define WRITE_LOCK 1
#define READ_LOCK 2 #define READ_LOCK 2

View File

@ -1,44 +1,46 @@
//;# autogenerated: Do not edit. //;# autogenerated: Do not edit.
//; $tls::func = -7148; //; $tls::func = -4076;
//; $tls::saved_errno = -7144; //; $tls::saved_errno = -4072;
//; $tls::sa_flags = -7140; //; $tls::sa_flags = -4068;
//; $tls::oldmask = -7136; //; $tls::oldmask = -4064;
//; $tls::newmask = -7132; //; $tls::newmask = -4060;
//; $tls::event = -7128; //; $tls::event = -4056;
//; $tls::errno_addr = -7124; //; $tls::errno_addr = -4052;
//; $tls::initialized = -7120; //; $tls::initialized = -4048;
//; $tls::sigmask = -7116; //; $tls::sigmask = -4044;
//; $tls::sigwait_mask = -7112; //; $tls::sigwait_mask = -4040;
//; $tls::sigwait_info = -7108; //; $tls::sigwait_info = -4036;
//; $tls::infodata = -7104; //; $tls::infodata = -4032;
//; $tls::tid = -6580; //; $tls::tid = -3508;
//; $tls::local_clib = -6576; //; $tls::local_clib = -3504;
//; $tls::locals = -5648; //; $tls::locals = -2576;
//; $tls::prev = -4112; //; $tls::prev = -1040;
//; $tls::next = -4108; //; $tls::next = -1036;
//; $tls::stackptr = -4104; //; $tls::stackptr = -1032;
//; $tls::sig = -4100; //; $tls::sig = -1028;
//; $tls::stack = -4096; //; $tls::stack = -1024;
//; $tls::padding = 0;
//; __DATA__ //; __DATA__
#define tls_func (-7148) #define tls_func (-4076)
#define tls_saved_errno (-7144) #define tls_saved_errno (-4072)
#define tls_sa_flags (-7140) #define tls_sa_flags (-4068)
#define tls_oldmask (-7136) #define tls_oldmask (-4064)
#define tls_newmask (-7132) #define tls_newmask (-4060)
#define tls_event (-7128) #define tls_event (-4056)
#define tls_errno_addr (-7124) #define tls_errno_addr (-4052)
#define tls_initialized (-7120) #define tls_initialized (-4048)
#define tls_sigmask (-7116) #define tls_sigmask (-4044)
#define tls_sigwait_mask (-7112) #define tls_sigwait_mask (-4040)
#define tls_sigwait_info (-7108) #define tls_sigwait_info (-4036)
#define tls_infodata (-7104) #define tls_infodata (-4032)
#define tls_tid (-6580) #define tls_tid (-3508)
#define tls_local_clib (-6576) #define tls_local_clib (-3504)
#define tls_locals (-5648) #define tls_locals (-2576)
#define tls_prev (-4112) #define tls_prev (-1040)
#define tls_next (-4108) #define tls_next (-1036)
#define tls_stackptr (-4104) #define tls_stackptr (-1032)
#define tls_sig (-4100) #define tls_sig (-1028)
#define tls_stack (-4096) #define tls_stack (-1024)
#define tls_padding (0)

View File

@ -8,6 +8,12 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
#ifdef DEBUGIT
#define spf(a, b, c) small_printf (a, b, c)
#else
#define spf(a, b, c) do {} while (0)
#endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif #endif
@ -150,11 +156,11 @@ extern HANDLE title_mutex;
}) })
/* Convert a signal to a signal mask */ /* Convert a signal to a signal mask */
#define SIGTOMASK(sig) (1<<((sig) - signal_shift_subtract)) #define SIGTOMASK(sig) (1 << ((sig) - signal_shift_subtract))
extern unsigned int signal_shift_subtract; extern unsigned int signal_shift_subtract;
#ifdef NEW_MACRO_VARARGS #ifdef NEW_MACRO_VARARGS
# define api_fatal(...) __api_fatal ("%P: *** " __VA_ARGS__) # define api_fatal(...) __api_fatal (__VA_ARGS__)
#else #else
# define api_fatal(fmt, args...) __api_fatal ("%P: *** " fmt,## args) # define api_fatal(fmt, args...) __api_fatal ("%P: *** " fmt,## args)
#endif #endif