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.
+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>
* exceptions.cc (_threadinfo::interrupt_now): Avoid double call to
MALLOC_OFILES=@MALLOC_OFILES@
-DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
+DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
MT_SAFE_OBJECTS:=
# Please maintain this list in sorted order, with maximum files per 80 col line
regfree_CFLAGS=-fomit-frame-pointer
shared_CFLAGS:=-fomit-frame-pointer
smallprint_CFLAGS:=-fomit-frame-pointer
+sysconf_CFLAGS:=-fomit-frame-pointer
+uinfo_CFLAGS:=-fomit-frame-pointer
endif
.PHONY: all force dll_ofiles install all_target install_target all_host install_host \
LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32)
LoadDLLfunc (OpenProcessToken, 12, advapi32)
LoadDLLfunc (OpenThreadToken, 16, advapi32)
-LoadDLLfunc (RegCloseKey, 4, advapi32)
+// LoadDLLfunc (RegCloseKey, 4, advapi32)
LoadDLLfunc (RegCreateKeyExA, 36, advapi32)
LoadDLLfunc (RegDeleteKeyA, 8, advapi32)
LoadDLLfunc (RegDeleteValueA, 8, advapi32)
LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1)
-LoadDLLfunc (TryEnterCriticalSection, 4, kernel32)
LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)
}
}
+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)))
static void *__stdcall
cygheap->fdtab.init ();
if (!cygheap->sigs)
sigalloc ();
+
if (!cygheap->shared_prefix)
cygheap->shared_prefix = cstrdup (
wincap.has_terminal_services ()
HEAP_MOUNT,
HEAP_SIGS,
HEAP_ARCHETYPES,
+ HEAP_TLS,
HEAP_1_START,
HEAP_1_STR,
HEAP_1_ARGV,
fhandler_tty_slave *ctty; /* Current tty */
fhandler_tty_slave *ctty_on_hold;
+ struct _threadinfo **threadlist;
+ size_t sthreads;
int open_fhs;
+ void close_ctty ();
};
#define CYGHEAPSIZE (sizeof (init_cygheap) + (20000 * sizeof (fhandler_union)) + (5 * 65536))
virtual ~cygheap_fdmanip ()
{
if (locked)
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
+ cygheap->fdtab.unlock ();
}
void release ()
{
cygheap_fdnew (int seed_fd = -1, bool lockit = true)
{
if (lockit)
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
+ cygheap->fdtab.lock ();
if (seed_fd < 0)
fd = cygheap->fdtab.find_unused_handle ();
else
{
set_errno (EMFILE);
if (lockit)
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
+ cygheap->fdtab.unlock ();
locked = false;
}
}
cygheap_fdget (int fd, bool lockit = false, bool do_set_errno = true)
{
if (lockit)
- SetResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
+ cygheap->fdtab.lock ();
if (fd >= 0 && fd < (int) cygheap->fdtab.size
&& *(fh = cygheap->fdtab + fd) != NULL)
{
if (do_set_errno)
set_errno (EBADF);
if (lockit)
- ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
+ cygheap->fdtab.unlock ();
locked = false;
}
}
DWORD WINAPI
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;
if (info->arg == cygself)
{
CloseHandle (info->ev);
CloseHandle (info->thread_sync);
}
- info->ev = info->thread_sync = info->stack_ptr = NULL;
+ info->ev = info->thread_sync = info->stack_ptr = NULL;
}
else
{
info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
}
}
+
while (1)
{
if (!info->__name)
DWORD WINAPI
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;
info->stack_ptr = &arg;
info->ev = info->h;
VOID *arg;
bool is_freerange;
static bool exiting;
- static void stub2 (void *, void *);
- static DWORD WINAPI simplestub (VOID *);
- static void simplestub2 (void *, void *);
void terminate_thread ();
public:
static DWORD WINAPI stub (VOID *);
+ static DWORD WINAPI simplestub (VOID *);
static DWORD main_thread_id;
static const char * name (DWORD = 0);
cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *);
(void) CloseHandle (h);
h = NULL;
}
-
};
#define cygself NULL
-/* 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
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
#include "cygtls.h"
#include "assert.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"
+
+class sentry
+{
+ 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 ();
+};
+
+muto NO_COPY *sentry::lock;
-static _threadinfo NO_COPY dummy_thread;
-_threadinfo NO_COPY *_last_thread = &dummy_thread;
+static size_t NO_COPY nthreads;
-CRITICAL_SECTION NO_COPY _threadinfo::protect_linked_list;
+#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
_threadinfo::set_state (bool is_exception)
debug_printf ("resetting stack after an exception stack %p, stackptr %p", stack, stackptr);
#endif
set_state (false);
- stackptr--;
}
}
void
_threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
{
- _my_tls.init_thread (buf);
- ExitThread (func (arg, buf));
-}
-
-void
-_threadinfo::init ()
-{
- InitializeCriticalSection (&protect_linked_list);
+ exception_list except_entry;
+ /* 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
-_threadinfo::init_thread (void *x)
+_threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
{
if (x)
{
- memset (this, 0, sizeof (*this));
+ memset (this, 0, CYGTLS_PADSIZE);
stackptr = stack;
if (_GLOBAL_REENT)
{
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);
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
-_threadinfo::remove ()
+_threadinfo::remove (DWORD wait)
{
- EnterCriticalSection (&protect_linked_list);
- if (prev)
+ debug_printf ("wait %p\n", wait);
+ sentry here (wait);
+ if (here.acquired ())
{
- prev->next = next;
- if (next)
- next->prev = prev;
- if (this == _last_thread)
- _last_thread = prev;
- prev = next = NULL;
+ for (size_t i = 0; i < nthreads; i++)
+ if (&_my_tls == cygheap->threadlist[i])
+ {
+ if (i < --nthreads)
+ cygheap->threadlist[i] = cygheap->threadlist[nthreads];
+ break;
+ }
}
- LeaveCriticalSection (&protect_linked_list);
}
void
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);
+}
# define UNLEN 256
#endif
-#define TLS_STACK_SIZE 1024
+#define TLS_STACK_SIZE 256
#pragma pack(push,4)
struct _local_storage
__stack_t *stackptr;
int sig;
__stack_t stack[TLS_STACK_SIZE];
+ unsigned padding[0];
/*gentls_offsets*/
static CRITICAL_SECTION protect_linked_list;
static void init ();
- void init_thread (void *) __attribute__ ((regparm (2)));
- static void call (DWORD (*) (void *, void *), void *) __attribute__ ((regparm (3)));
+ void init_thread (void *, DWORD (*) (void *, void *));
+ static void call (DWORD (*) (void *, void *), void *);
static void call2 (DWORD (*) (void *, void *), void *, void *) __attribute__ ((regparm (3)));
static struct _threadinfo *find_tls (int sig);
- void remove ();
+ void remove (DWORD);
void push (__stack_t, bool = false);
__stack_t pop ();
bool isinitialized () {return initialized == CYGTLS_INITIALIZED || initialized == CYGTLS_EXCEPTION;}
__attribute__((regparm(3)));
void __stdcall interrupt_setup (int sig, void *handler, struct sigaction& siga, __stack_t retaddr)
__attribute__((regparm(3)));
+ void init_threadlist_exceptions (struct _exception_list *);
operator HANDLE () const {return tid->win32_obj_id;}
/*gentls_offsets*/
};
#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*/
#include "dll_init.h"
#include "cygthread.h"
#include "sync.h"
+#include "heap.h"
#define MAX_AT_FILE_LEVEL 10
bool allow_glob = true;
codepage_type current_codepage = ansi_cp;
-static NO_COPY int mypid = 0;
int __argc_safe;
int _declspec(dllexport) __argc;
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 *);
return;
}
-/* 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. */
+#ifdef DEBUGGING
+void
+break_here ()
+{
+ debug_printf ("break here");
+}
+#endif
+
static void
-dll_crt0_1 (char *)
+initial_env ()
{
- /* 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;
+ 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
- /* Initialize SIGSEGV handling, etc. */
- init_exceptions (&cygwin_except_entry);
+ if (GetEnvironmentVariable ("CYGWIN_TESTING", buf, sizeof (buf) - 1))
+ _cygwin_testing = 1;
+}
- /* Set the os_being_run global. */
+void __stdcall
+dll_crt0_0 ()
+{
wincap.init ();
- device::init ();
- check_sanity_and_sync (user_data);
+ initial_env ();
- do_global_ctors (&__CTOR_LIST__, 1);
+ char zeros[sizeof (child_proc_info->zero)] = {0};
- /* 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). */
+ init_console_handler ();
+ init_global_security ();
+ if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
+ GetCurrentProcess (), &hMainProc, 0, FALSE,
+ DUPLICATE_SAME_ACCESS))
+ hMainProc = GetCurrentProcess ();
- user_data->resourcelocks->Init ();
- user_data->threadinterface->Init ();
+ DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
+ &hMainThread, 0, false, DUPLICATE_SAME_ACCESS);
- winpids::init ();
+ (void) SetErrorMode (SEM_FAILCRITICALERRORS);
- int envc = 0;
- char **envp = NULL;
+ 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 ();
+ winpids::init ();
+ do_global_ctors (&__CTOR_LIST__, 1);
+ cygthread::init ();
if (!child_proc_info)
memory_init ();
__argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp;
envc = spawn_info->moreinfo->envc;
+ envp = spawn_info->moreinfo->envp;
cygheap->fdtab.fixup_after_exec (spawn_info->parent);
signal_fixup_after_exec ();
CloseHandle (spawn_info->parent);
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 (hMainThread);
- cygthread::init ();
/* Initialize pthread mainthread when not forked and it is safe to call new,
otherwise it is reinitalized in fixup_after_fork */
cygheap->fdtab.vfork_child_fixup ();
- (void) SetErrorMode (SEM_FAILCRITICALERRORS);
-
- /* Initialize events. */
- events_init ();
-
- cygheap->cwd.init ();
main_vfork = vfork_storage.create ();
cygbench ("pre-forkee");
}
#endif
- /* Init global well known SID objects */
- cygsid::init ();
-
/* Initialize our process table entry. */
pinfo_init (envp, envc);
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 *
initialize_main_tls (char *padding)
{
if (!_main_tls)
{
- _threadinfo::init ();
_main_tls = &_my_tls;
- _main_tls->init_thread (padding);
+ _main_tls->init_thread (padding, NULL);
}
return &_main_tls->local_clib;
}
UPTR is a pointer to global data that lives on the libc side of the
line [if one distinguishes the application from the dll]. */
-
+
extern "C" void __stdcall
_dll_crt0 ()
{
- initial_env ();
- char zeros[max (CYGTLS_PADSIZE, sizeof (child_proc_info->zero))] = {0};
- static NO_COPY STARTUPINFO si;
+ extern HANDLE sync_startup;
+ if (sync_startup)
+ {
+ (void) WaitForSingleObject (sync_startup, INFINITE);
+ CloseHandle (sync_startup);
+ }
main_environ = user_data->envptr;
*main_environ = NULL;
- init_console_handler ();
- init_global_security ();
- if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
- GetCurrentProcess (), &hMainProc, 0, FALSE,
- DUPLICATE_SAME_ACCESS))
- hMainProc = GetCurrentProcess ();
+ if (child_proc_info && child_proc_info->type == _PROC_FORK)
+ user_data->forkee = child_proc_info->cygpid;
- 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;
- 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->_stdin = &_impure_ptr->__sf[0];
_impure_ptr->_stdout = &_impure_ptr->__sf[1];
_impure_ptr->_stderr = &_impure_ptr->__sf[2];
_impure_ptr->_current_locale = "C";
- initialize_main_tls (zeros);
- dll_crt0_1 (zeros);
+ initialize_main_tls (padding);
+ dll_crt0_1 (padding);
}
void
}
EnterCriticalSection (&exit_lock);
+ muto::set_exiting_thread ();
if (exit_state < ES_EVENTS_TERMINATE)
{
exit_state = ES_EVENTS_TERMINATE;
va_list ap;
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);
strcat (buf, "\n");
int len = strlen (buf);
handle_list *hl;
lock_debug here;
+ if (!cygheap)
+ return;
+
if ((hl = find_handle (h)))
{
hl = hl->next;
handle_list *hl;
lock_debug here;
+ if (!cygheap)
+ return true;
+
if ((hl = find_handle (h)) && !force)
{
hl = hl->next;
void *
dlopen (const char *name, int)
{
- SetResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlopen");
-
void *ret;
if (name == NULL)
set_dl_error ("dlopen");
debug_printf ("ret %p", ret);
- ReleaseResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlopen");
return ret;
}
int
dlclose (void *handle)
{
- SetResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlclose");
-
int ret = -1;
void *temphandle = (void *) GetModuleHandle (NULL);
if (temphandle == handle || FreeLibrary ((HMODULE) handle))
if (ret)
set_dl_error ("dlclose");
CloseHandle ((HMODULE) temphandle);
-
- ReleaseResourceLock (LOCK_DLL_LIST, READ_LOCK | WRITE_LOCK, "dlclose");
return ret;
}
if (d->handle != h)
continue;
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)
{
d->p.run_dtors ();
<title>cygwin_detach_dll</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_detach_dll</function></funcdef>
<paramdef>int <parameter>dll_index</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
</sect1>
#include "ntdll.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,
STD_ERROR_HANDLE};
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 */
void
-dtable_init (void)
+dtable_init ()
{
if (!cygheap->fdtab.size)
cygheap->fdtab.extend (NOFILE_INCR);
+ cygheap->fdtab.init_lock ();
+
}
void __stdcall
SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ());
}
+void
+dtable::init_lock ()
+{
+ new_muto (lock_cs);
+}
+
int
dtable::extend (int howmuch)
{
MALLOC_CHECK;
debug_printf ("dup2 (%d, %d)", oldfd, newfd);
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
+ lock ();
if (not_open (oldfd))
{
done:
MALLOC_CHECK;
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
+ unlock ();
syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd);
return res;
fhandler_fifo *
dtable::find_fifo (ATOM hill)
{
- SetResourceLock (LOCK_FD_LIST, READ_LOCK, "dup");
+ lock ();
for (unsigned i = 0; i < size; i++)
{
fhandler_base *fh = fds[i];
void
dtable::fixup_before_fork (DWORD target_proc_id)
{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_fork");
+ lock ();
fhandler_base *fh;
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL)
debug_printf ("fd %d (%s)", i, fh->get_name ());
fh->fixup_before_fork_exec (target_proc_id);
}
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_fork");
+ unlock ();
}
void
dtable::fixup_before_exec (DWORD target_proc_id)
{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec");
+ lock ();
fhandler_base *fh;
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL && !fh->get_close_on_exec ())
debug_printf ("fd %d (%s)", i, fh->get_name ());
fh->fixup_before_fork_exec (target_proc_id);
}
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec");
+ unlock ();
}
void
dtable::set_file_pointers_for_exec ()
{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "set_file_pointers_for_exec");
+ lock ();
fhandler_base *fh;
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL && fh->get_flags () & O_APPEND)
SetFilePointer (fh->get_handle (), 0, 0, FILE_END);
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fixup_before_exec");
+ unlock ();
}
void
{
first_fd_for_open = 0;
fhandler_base *fh;
+ cygheap->fdtab.init_lock ();
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL)
{
dtable::fixup_after_fork (HANDLE parent)
{
fhandler_base *fh;
+ cygheap->fdtab.init_lock ();
for (size_t i = 0; i < size; i++)
if ((fh = fds[i]) != NULL)
{
dtable::vfork_child_dup ()
{
fhandler_base **newtable;
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
+ lock ();
newtable = (fhandler_base **) ccalloc (HEAP_ARGV, size, sizeof (fds[0]));
int res = 1;
/* Restore impersonation */
cygheap->user.reimpersonate ();
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
+ unlock ();
return 1;
}
void
dtable::vfork_parent_restore ()
{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "restore");
+ lock ();
close_all_files ();
fhandler_base **deleteme = fds;
fds = fds_on_hold;
fds_on_hold = NULL;
cfree (deleteme);
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "restore");
+ unlock ();
cygheap->ctty = cygheap->ctty_on_hold; // revert
if (cygheap->ctty)
#define NOFILE_INCR 32
#include "thread.h"
+#include "sync.h"
class suffix_info;
class fhandler_fifo;
#define BFH_OPTS (PC_NULLEMPTY | PC_FULL | PC_POSIX)
class dtable
{
+ muto *lock_cs;
fhandler_base **fds;
fhandler_base **fds_on_hold;
fhandler_base **archetypes;
static const int initial_archetype_size = 8;
int first_fd_for_open;
int cnt_need_fixup_before;
+ void lock () {lock_cs->acquire ();}
+ void unlock () {lock_cs->release ();}
+ void init_lock ();
public:
size_t size;
void fixup_after_fork (HANDLE);
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;
-
- ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "not open");
+ unlock ();
return res;
}
int find_unused_handle (int start);
fhandler_base *find_archetype (device& dev);
fhandler_base **add_archetype ();
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);
<title>cygwin_attach_handle_to_fd</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" int
<function>cygwin_attach_handle_to_fd</function></funcdef>
<paramdef>char *<parameter>name</parameter></paramdef>
<paramdef>HANDLE <parameter>handle</parameter></paramdef>
<paramdef>int <parameter>bin</parameter></paramdef>
<paramdef>int <parameter>access</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>This function can be used to turn a Win32 "handle" into a
// of code that handles exceptions. The x86 on the other hand uses segment
// 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");
-
-static void
-init_exception_handler (exception_list *el)
+void
+init_exception_handler (exception_list *el, exception_handler *eh)
{
- el->handler = handle_exceptions;
+ el->handler = eh;
el->prev = _except_list;
_except_list = el;
}
+extern "C" void
+init_exceptions (exception_list *el)
+{
+ init_exception_handler (el, handle_exceptions);
+}
+
void
init_console_handler ()
{
}
extern "C" void
-init_exceptions (exception_list *el)
-{
- init_exception_handler (el);
-}
-
-extern "C" void
error_start_init (const char *buf)
{
if (!buf || !*buf)
}
}
+ small_printf ("*** starting debugger for pid %u\n",
+ cygwin_pid (GetCurrentProcessId ()));
BOOL dbg;
dbg = CreateProcess (NULL,
debugger_command,
return 1;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
while (!being_debugged ())
- Sleep (0);
- Sleep (2000);
- small_printf ("*** continuing from debugger call\n");
+ low_priority_sleep (0);
+ small_printf ("*** continuing pid %u from debugger call\n",
+ cygwin_pid (GetCurrentProcessId ()));
}
SetThreadPriority (GetCurrentThread (), prio);
}
}
-int
+bool
interruptible (DWORD pc)
{
int res;
GetThreadContext. These resolve to a strange allocation base.
These should *never* be treated as interruptible. */
if (!h || m.State != MEM_COMMIT)
- res = 0;
+ res = false;
else if (h == user_data->hmodule)
- res = 1;
+ res = true;
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
- res = 0;
+ res = false;
else
res = !strncasematch (windows_system_directory, checkdir,
windows_system_directory_length);
/* Clear any waiting threads prior to dispatching to handler function */
int res = SetEvent (signal_arrived); // For an EINTR case
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
// 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;
if (!GetThreadContext (hth, &cx))
system_printf ("couldn't get context of main thread, %E");
else if (interruptible (cx.Eip))
interrupted = tls->interrupt_now (&cx, sig, handler, siga);
- resume_thread:
res = ResumeThread (hth);
-
if (interrupted)
break;
+
sigproc_printf ("couldn't interrupt. trying again.");
low_priority_sleep (0);
}
ctrl_c_handler (DWORD type)
{
static bool saw_close;
- _my_tls.remove ();
+ _my_tls.remove (INFINITE);
/* Return FALSE to prevent an "End task" dialog box from appearing
for each Cygwin process window that's open when the computer
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
sig_handle (int sig, sigset_t mask, int pid, _threadinfo *tls)
{
int rc = 1;
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
- && (sigismember (&mask, sig)
- || (tls
- && (insigwait_mask || sigismember (&tls->sigmask, sig)))
- || main_vfork->pid
- || ISSTATE (myself, PID_STOPPED)))
+ && (special_case || main_vfork->pid || masked || insigwait_mask
+ || (tls && sigismember (&tls->sigmask, 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;
rc = -1;
goto done;
(void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE);
(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->Init ();
sa_flags = _my_tls.sa_flags;
int sig = _my_tls.sig;
void (*sigfunc) (int) = _my_tls.func;
+
(void) _my_tls.pop ();
#ifdef DEBUGGING
if (_my_tls.stackptr > (_my_tls.stack + 1))
{
va_list arg;
va_start (arg, t);
- if (t != CW_USER_DATA)
- {
- wincap.init ();
- if (!myself)
- {
- memory_init ();
- malloc_init ();
- set_myself (1);
- }
- }
switch (t)
{
<title>cygwin_internal</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" DWORD
<function>cygwin_internal</function></funcdef>
<paramdef>cygwin_getinfo_types <parameter>t</parameter></paramdef>
<paramdef><parameter>...</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>This function gives you access to various internal data and functions.
*/
if (errcode != STATUS_CONTROL_C_EXIT)
{
- system_printf ("child %d(%p) died before initialization with status code %p",
- pi.dwProcessId, pi.hProcess, errcode);
+ system_printf ("child %u(%p) died before initialization with status code %p",
+ cygwin_pid (pi.dwProcessId), pi.hProcess, errcode);
system_printf ("*** child state %s", s);
#ifdef DEBUGGING
abort ();
if (fork_info->stacksize)
{
_main_tls = &_my_tls;
- _main_tls->init_thread (NULL);
+ _main_tls->init_thread (NULL, NULL);
_main_tls->local_clib = *_impure_ptr;
_impure_ptr = &_main_tls->local_clib;
}
vf->pgid = myself->pgid;
cygheap->ctty_on_hold = cygheap->ctty;
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;
debug_printf ("%d = vfork()", res);
call_signal_handler_now (); // FIXME: racy
#define MINHEAP_SIZE (4 * 1024 * 1024)
/* Initialize the heap at process start up. */
-
void
heap_init ()
{
/* total size commited in parent */
DWORD allocsize = (char *) cygheap->user_heap.top -
(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. */
char *p;
- for (;;)
+ DWORD reserve_size = chunk * ((allocsize + (chunk - 1)) / chunk);
+ while (1)
{
p = (char *) VirtualAlloc (cygheap->user_heap.base, reserve_size,
MEM_RESERVE, PAGE_READWRITE);
if ((reserve_size -= page_const) <= allocsize)
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)
- 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))
api_fatal ("MEM_COMMIT failed, %E");
}
debug_printf ("heap base %p, heap top %p", cygheap->user_heap.base,
cygheap->user_heap.top);
page_const--;
- malloc_init ();
+ // malloc_init ();
}
#define pround(n) (((size_t)(n) + page_const) & ~page_const)
#include "cygtls.h"
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
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
munge_threadfunc (HANDLE cygwin_hmodule)
{
- char **ebp = (char **) __builtin_frame_address (0);
- static unsigned threadfunc_ix;
+ char **ebp = (char **) __builtin_frame_address (0);
if (!threadfunc_ix)
{
for (char **peb = ebp; peb < (char **) _tlsbase; peb++)
- if (*peb == (char *) cygthread::stub)
+ if (*peb == search_for)
{
threadfunc_ix = peb - ebp;
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;
}
foundit:
char *threadfunc = ebp[threadfunc_ix];
- ebp[threadfunc_ix] = (char *) threadfunc_fe;
- ((char **) _tlsbase)[-1] = threadfunc;
+ if (threadfunc == (char *) calibration_thread)
+ /* no need for the overhead */;
+ else
+ {
+ ebp[threadfunc_ix] = (char *) threadfunc_fe;
+ ((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
dll_entry (HANDLE h, DWORD reason, void *static_load)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
+ prime_threads ();
dynamically_loaded = (static_load == NULL);
// __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;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
munge_threadfunc (h);
+ // small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break;
case DLL_THREAD_DETACH:
+ _my_tls.remove (0);
break;
}
return 1;
malloc_init ()
{
new_muto (mallock);
+
/* Check if mallock is provided by application. If so, redirect all
calls to malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides
<title>cygwin_posix_to_win32_path_list</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_posix_to_win32_path_list</function></funcdef>
<paramdef>const char *<parameter>posix</parameter></paramdef>
<paramdef>char *<parameter>win32</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Given a POSIX path-style string (i.e. /foo:/bar) convert it to
<title>cygwin_win32_to_posix_path_list</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_win32_to_posix_path_list</function></funcdef>
<paramdef>const char *<parameter>win32</parameter></paramdef>
<paramdef>char *<parameter>posix</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Given a Win32 path-style string (i.e. d:\;e:\bar) convert it to
<title>cygwin_posix_to_win32_path_list_buf_size</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" int
<function>cygwin_posix_to_win32_path_list_buf_size</function></funcdef>
<paramdef>const char *<parameter>path_list</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Returns the number of bytes needed to hold the result of calling
<title>cygwin_win32_to_posix_path_list_buf_size</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" int
<function>cygwin_win32_to_posix_path_list_buf_size</function></funcdef>
<paramdef>const char *<parameter>path_list</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Tells you how many bytes are needed for the results of <link
<title>cygwin_conv_to_posix_path</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_conv_to_posix_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>posix_path</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Converts a Win32 path to a POSIX path. If
<title>cygwin_conv_to_win32_path</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_conv_to_win32_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>win32_path</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Converts a POSIX path to a Win32 path. If
<title>cygwin_conv_to_full_posix_path</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_conv_to_full_posix_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>posix_path</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Converts a Win32 path to a POSIX path. If
<title>cygwin_conv_to_full_win32_path</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_conv_to_full_win32_path</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>char *<parameter>win32_path</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Converts a POSIX path to a Win32 path. If
<title>cygwin_posix_path_list_p</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" int
<function>posix_path_list_p</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>This function tells you if the supplied
<title>cygwin_split_path</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_split_path</function>
</funcdef>
<paramdef>const char * <parameter>path</parameter></paramdef>
<paramdef>char * <parameter>dir</parameter></paramdef>
<paramdef>char * <parameter>file</parameter></paramdef>
-</funcprototype>
</funcsynopsis>
<para>Split a path into the directory and the file portions. Both
<title>cygwin_winpid_to_pid</title>
<funcsynopsis>
- <funcprototype>
<funcdef>extern "C" pid_t
<function>cygwin_winpid_to_pid</function>
</funcdef>
<paramdef>int <parameter>winpid</parameter></paramdef>
- </funcprototype>
</funcsynopsis>
<para>Given a windows pid, converts to the corresponding Cygwin
/* 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.
* type coercion need to appease confused prototypes
*/
#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)
<title>cygwin_getshared</title>
<funcsynopsis>
-<funcprototype>
<funcdef>shared_info *
<function>cygwin_getshared</function></funcdef>
<void>
-</funcprototype>
</funcsynopsis>
<para>Returns a pointer to an internal Cygwin memory structure
/* 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
#include "cygtls.h"
#include "sigproc.h"
#include "perthread.h"
+#include "exceptions.h"
/*
* Convenience defines
SetEvent (wait_sig_inited);
sigtid = GetCurrentThreadId ();
+ exception_list el;
+ _my_tls.init_threadlist_exceptions (&el);
+
for (;;)
{
DWORD nb;
sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break;
+ if (myself->sendsig == INVALID_HANDLE_VALUE)
+ break;
if (nb != sizeof (pack))
{
<title>cygwin_stackdump</title>
<funcsynopsis>
-<funcprototype>
<funcdef>extern "C" void
<function>cygwin_stackdump</function></funcdef>
<void>
-</funcprototype>
</funcsynopsis>
<para> Outputs a stackdump to stderr from the called location.
#include "sync.h"
#include "security.h"
-muto NO_COPY muto_start;
-
#undef WaitForSingleObject
+DWORD NO_COPY muto::exiting_thread;
+
/* Constructor */
muto *
muto::init (const char *s)
return NULL;
}
name = s;
- next = muto_start.next;
- muto_start.next = this;
return this;
}
muto::acquire (DWORD ms)
{
DWORD this_tid = GetCurrentThreadId ();
+ if (exiting_thread)
+ return this_tid == exiting_thread;
if (tid != this_tid)
{
muto::release ()
{
DWORD this_tid = GetCurrentThreadId ();
+ if (exiting_thread)
+ return this_tid == exiting_thread;
if (tid != this_tid || !visits)
{
return 1; /* success. */
}
+bool
+muto::acquired ()
+{
+ return tid == GetCurrentThreadId ();
+}
+
/* Call only when we're exiting. This is not thread safe. */
void
muto::reset ()
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
+#ifndef _SYNC_H
+#define _SYNC_H
/* FIXME: Note that currently this class cannot be allocated via `new' since
there are issues with malloc and fork. */
class muto
{
+ static DWORD exiting_thread;
LONG sync; /* Used to serialize access to this class. */
LONG visits; /* Count of number of times a thread has called acquire. */
LONG waiters; /* Number of threads waiting for lock. */
HANDLE bruteforce; /* event handle used to control waiting for lock. */
DWORD tid; /* Thread Id of lock owner. */
public:
- class muto *next;
+ // class muto *next;
const char *name;
/* The real constructor. */
DWORD owner () {return tid;}
int unstable () {return !tid && (sync || waiters >= 0);}
void reset () __attribute__ ((regparm (1)));
+ bool acquired ();
+ static void set_exiting_thread () {exiting_thread = GetCurrentThreadId ();}
};
extern muto muto_start;
/* Use a statically allocated buffer as the storage for a muto */
#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); \
})
+
+/* 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*/
void __stdcall
close_all_files (void)
{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files");
+ cygheap->fdtab.lock ();
fhandler_base *fh;
for (int i = 0; i < (int) cygheap->fdtab.size; i++)
}
if (cygheap->ctty)
- {
- debug_printf ("closing ctty");
- cygheap->ctty->close ();
- cygheap->ctty = NULL;
- }
+ cygheap->close_ctty ();
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "close_all_files");
+ cygheap->fdtab.unlock ();
user_shared->delqueue.process_queue ();
}
syscall_printf ("sid %d, pgid %d, ctty %d, open_fhs %d", myself->sid,
myself->pgid, myself->ctty, cygheap->open_fhs);
if (cygheap->ctty)
- {
- cygheap->ctty->close ();
- cygheap->ctty = NULL;
- }
+ cygheap->close_ctty ();
return myself->sid;
}
::exit (0);
else
{
- _my_tls.remove ();
+ _my_tls.remove (INFINITE);
ExitThread (0);
}
}
pthread *thread = (pthread *) arg;
_my_tls.tid = thread;
- exception_list cygwin_except_entry;
- init_exceptions (&cygwin_except_entry); /* Initialize SIGSEGV handling, etc. */
-
thread->mutex.lock ();
// if thread is detached force cleanup on exit
#ifndef _CYGNUS_THREADS_
#define _CYGNUS_THREADS_
-#define LOCK_FD_LIST 1
-#define LOCK_MEMORY_LIST 2
-#define LOCK_MMAP_LIST 3
-#define LOCK_DLL_LIST 4
+#define LOCK_MMAP_LIST 1
#define WRITE_LOCK 1
#define READ_LOCK 2
//;# autogenerated: Do not edit.
-//; $tls::func = -7148;
-//; $tls::saved_errno = -7144;
-//; $tls::sa_flags = -7140;
-//; $tls::oldmask = -7136;
-//; $tls::newmask = -7132;
-//; $tls::event = -7128;
-//; $tls::errno_addr = -7124;
-//; $tls::initialized = -7120;
-//; $tls::sigmask = -7116;
-//; $tls::sigwait_mask = -7112;
-//; $tls::sigwait_info = -7108;
-//; $tls::infodata = -7104;
-//; $tls::tid = -6580;
-//; $tls::local_clib = -6576;
-//; $tls::locals = -5648;
-//; $tls::prev = -4112;
-//; $tls::next = -4108;
-//; $tls::stackptr = -4104;
-//; $tls::sig = -4100;
-//; $tls::stack = -4096;
+//; $tls::func = -4076;
+//; $tls::saved_errno = -4072;
+//; $tls::sa_flags = -4068;
+//; $tls::oldmask = -4064;
+//; $tls::newmask = -4060;
+//; $tls::event = -4056;
+//; $tls::errno_addr = -4052;
+//; $tls::initialized = -4048;
+//; $tls::sigmask = -4044;
+//; $tls::sigwait_mask = -4040;
+//; $tls::sigwait_info = -4036;
+//; $tls::infodata = -4032;
+//; $tls::tid = -3508;
+//; $tls::local_clib = -3504;
+//; $tls::locals = -2576;
+//; $tls::prev = -1040;
+//; $tls::next = -1036;
+//; $tls::stackptr = -1032;
+//; $tls::sig = -1028;
+//; $tls::stack = -1024;
+//; $tls::padding = 0;
//; __DATA__
-#define tls_func (-7148)
-#define tls_saved_errno (-7144)
-#define tls_sa_flags (-7140)
-#define tls_oldmask (-7136)
-#define tls_newmask (-7132)
-#define tls_event (-7128)
-#define tls_errno_addr (-7124)
-#define tls_initialized (-7120)
-#define tls_sigmask (-7116)
-#define tls_sigwait_mask (-7112)
-#define tls_sigwait_info (-7108)
-#define tls_infodata (-7104)
-#define tls_tid (-6580)
-#define tls_local_clib (-6576)
-#define tls_locals (-5648)
-#define tls_prev (-4112)
-#define tls_next (-4108)
-#define tls_stackptr (-4104)
-#define tls_sig (-4100)
-#define tls_stack (-4096)
+#define tls_func (-4076)
+#define tls_saved_errno (-4072)
+#define tls_sa_flags (-4068)
+#define tls_oldmask (-4064)
+#define tls_newmask (-4060)
+#define tls_event (-4056)
+#define tls_errno_addr (-4052)
+#define tls_initialized (-4048)
+#define tls_sigmask (-4044)
+#define tls_sigwait_mask (-4040)
+#define tls_sigwait_info (-4036)
+#define tls_infodata (-4032)
+#define tls_tid (-3508)
+#define tls_local_clib (-3504)
+#define tls_locals (-2576)
+#define tls_prev (-1040)
+#define tls_next (-1036)
+#define tls_stackptr (-1032)
+#define tls_sig (-1028)
+#define tls_stack (-1024)
+#define tls_padding (0)
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
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
# include "config.h"
#endif
})
/* 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;
#ifdef NEW_MACRO_VARARGS
-# define api_fatal(...) __api_fatal ("%P: *** " __VA_ARGS__)
+# define api_fatal(...) __api_fatal (__VA_ARGS__)
#else
# define api_fatal(fmt, args...) __api_fatal ("%P: *** " fmt,## args)
#endif