* 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>
* 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@
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
@ -254,6 +254,8 @@ regexec_CFLAGS=-fomit-frame-pointer
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 \

View File

@ -354,7 +354,7 @@ LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32)
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)
@ -515,7 +515,6 @@ LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
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)

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)))
static void *__stdcall
@ -206,6 +216,7 @@ cygheap_init ()
cygheap->fdtab.init ();
if (!cygheap->sigs)
sigalloc ();
if (!cygheap->shared_prefix)
cygheap->shared_prefix = cstrdup (
wincap.has_terminal_services ()

View File

@ -19,6 +19,7 @@ enum cygheap_types
HEAP_MOUNT,
HEAP_SIGS,
HEAP_ARCHETYPES,
HEAP_TLS,
HEAP_1_START,
HEAP_1_STR,
HEAP_1_ARGV,
@ -263,7 +264,10 @@ struct init_cygheap
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))
@ -282,7 +286,7 @@ class cygheap_fdmanip
virtual ~cygheap_fdmanip ()
{
if (locked)
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdmanip");
cygheap->fdtab.unlock ();
}
void release ()
{
@ -308,7 +312,7 @@ class cygheap_fdnew : public cygheap_fdmanip
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
@ -322,7 +326,7 @@ class cygheap_fdnew : public cygheap_fdmanip
{
set_errno (EMFILE);
if (lockit)
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "cygheap_fdnew");
cygheap->fdtab.unlock ();
locked = false;
}
}
@ -335,7 +339,7 @@ class cygheap_fdget : public cygheap_fdmanip
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)
{
@ -348,7 +352,7 @@ class cygheap_fdget : public cygheap_fdmanip
if (do_set_errno)
set_errno (EBADF);
if (lockit)
ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "cygheap_fdget");
cygheap->fdtab.unlock ();
locked = false;
}
}

View File

@ -32,12 +32,6 @@ bool NO_COPY cygthread::exiting;
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)
{
@ -46,7 +40,7 @@ cygthread::stub (VOID *arg)
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
{
@ -57,6 +51,7 @@ cygthread::stub (VOID *arg)
info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
}
}
while (1)
{
if (!info->__name)
@ -92,12 +87,6 @@ cygthread::stub (VOID *arg)
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;

View File

@ -19,12 +19,10 @@ class cygthread
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 *);
@ -43,7 +41,6 @@ class cygthread
(void) CloseHandle (h);
h = 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
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@ -11,11 +11,48 @@ details. */
#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"
static _threadinfo NO_COPY dummy_thread;
_threadinfo NO_COPY *_last_thread = &dummy_thread;
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 ();
};
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
_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);
#endif
set_state (false);
stackptr--;
}
}
@ -47,22 +83,22 @@ _threadinfo::call (DWORD (*func) (void *, void *), void *arg)
void
_threadinfo::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
{
_my_tls.init_thread (buf);
ExitThread (func (arg, buf));
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 ()
{
InitializeCriticalSection (&protect_linked_list);
}
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)
{
@ -76,30 +112,40 @@ _threadinfo::init_thread (void *x)
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
@ -123,3 +169,48 @@ _threadinfo::pop ()
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
#endif
#define TLS_STACK_SIZE 1024
#define TLS_STACK_SIZE 256
#pragma pack(push,4)
struct _local_storage
@ -110,15 +110,16 @@ struct _threadinfo
__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;}
@ -128,6 +129,7 @@ struct _threadinfo
__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*/
};
@ -140,5 +142,5 @@ extern _threadinfo *_main_tls;
#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*/

View File

@ -35,6 +35,7 @@ details. */
#include "dll_init.h"
#include "cygthread.h"
#include "sync.h"
#include "heap.h"
#define MAX_AT_FILE_LEVEL 10
@ -55,11 +56,13 @@ bool strip_title_path;
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 *);
@ -519,41 +522,127 @@ alloc_stack (child_info_fork *ci)
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. */
static void
dll_crt0_1 (char *)
#ifdef DEBUGGING
void
break_here ()
{
/* 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;
debug_printf ("break here");
}
#endif
/* Initialize SIGSEGV handling, etc. */
init_exceptions (&cygwin_except_entry);
static 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);
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 ();
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 ();
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 ();
int envc = 0;
char **envp = NULL;
do_global_ctors (&__CTOR_LIST__, 1);
cygthread::init ();
if (!child_proc_info)
memory_init ();
@ -591,6 +680,7 @@ dll_crt0_1 (char *)
__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);
@ -607,9 +697,44 @@ dll_crt0_1 (char *)
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 */
@ -629,12 +754,6 @@ dll_crt0_1 (char *)
cygheap->fdtab.vfork_child_fixup ();
(void) SetErrorMode (SEM_FAILCRITICALERRORS);
/* Initialize events. */
events_init ();
cygheap->cwd.init ();
main_vfork = vfork_storage.create ();
cygbench ("pre-forkee");
@ -663,9 +782,6 @@ dll_crt0_1 (char *)
}
#endif
/* Init global well known SID objects */
cygsid::init ();
/* Initialize our process table entry. */
pinfo_init (envp, envc);
@ -773,60 +889,13 @@ dll_crt0_1 (char *)
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;
}
@ -836,81 +905,31 @@ initialize_main_tls (char *padding)
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
@ -970,6 +989,7 @@ do_exit (int status)
}
EnterCriticalSection (&exit_lock);
muto::set_exiting_thread ();
if (exit_state < ES_EVENTS_TERMINATE)
{
exit_state = ES_EVENTS_TERMINATE;
@ -1090,7 +1110,8 @@ __api_fatal (const char *fmt, ...)
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);

View File

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

View File

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

View File

@ -195,7 +195,7 @@ dll_list::detach (void *retaddr)
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 ();

View File

@ -3,11 +3,9 @@
<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>

View File

@ -33,19 +33,21 @@ details. */
#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
@ -57,6 +59,12 @@ set_std_handle (int fd)
SetStdHandle (std_consts[fd], cygheap->fdtab[fd]->get_output_handle ());
}
void
dtable::init_lock ()
{
new_muto (lock_cs);
}
int
dtable::extend (int howmuch)
{
@ -490,7 +498,7 @@ dtable::dup2 (int oldfd, int newfd)
MALLOC_CHECK;
debug_printf ("dup2 (%d, %d)", oldfd, newfd);
SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
lock ();
if (not_open (oldfd))
{
@ -539,7 +547,7 @@ dtable::dup2 (int oldfd, int newfd)
done:
MALLOC_CHECK;
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
unlock ();
syscall_printf ("%d = dup2 (%d, %d)", res, oldfd, newfd);
return res;
@ -548,7 +556,7 @@ done:
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];
@ -614,7 +622,7 @@ dtable::select_except (int fd, select_record *s)
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)
@ -622,13 +630,13 @@ dtable::fixup_before_fork (DWORD target_proc_id)
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 ())
@ -636,18 +644,18 @@ dtable::fixup_before_exec (DWORD target_proc_id)
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
@ -655,6 +663,7 @@ dtable::fixup_after_exec (HANDLE parent)
{
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)
{
@ -680,6 +689,7 @@ void
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)
{
@ -699,7 +709,7 @@ int
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;
@ -731,21 +741,21 @@ out:
/* 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)

View File

@ -12,6 +12,7 @@ details. */
#define NOFILE_INCR 32
#include "thread.h"
#include "sync.h"
class suffix_info;
class fhandler_fifo;
@ -19,6 +20,7 @@ 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;
@ -27,6 +29,9 @@ class dtable
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;
@ -50,11 +55,9 @@ public:
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);
@ -76,6 +79,11 @@ public:
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);

View File

@ -3,7 +3,6 @@
<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>
@ -11,7 +10,6 @@
<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

View File

@ -98,18 +98,22 @@ NO_COPY static struct
// 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 ()
{
@ -118,12 +122,6 @@ init_console_handler ()
system_printf ("SetConsoleCtrlHandler failed, %E");
}
extern "C" void
init_exceptions (exception_list *el)
{
init_exception_handler (el);
}
extern "C" void
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;
dbg = CreateProcess (NULL,
debugger_command,
@ -383,9 +383,9 @@ try_to_debug (bool waitloop)
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);
@ -615,7 +615,7 @@ sig_handle_tty_stop (int sig)
}
}
int
bool
interruptible (DWORD pc)
{
int res;
@ -633,11 +633,11 @@ interruptible (DWORD pc)
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);
@ -666,7 +666,8 @@ _threadinfo::interrupt_setup (int sig, void *handler,
/* 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
@ -762,26 +763,16 @@ setup_handler (int sig, void *handler, struct sigaction& siga, _threadinfo *tls)
// 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);
}
@ -801,7 +792,7 @@ static BOOL WINAPI
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
@ -892,19 +883,6 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask)
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)
{
@ -924,15 +902,15 @@ 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;
@ -1045,12 +1023,6 @@ signal_exit (int rc)
(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 ();
@ -1114,6 +1086,7 @@ call_signal_handler_now ()
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))

View File

@ -135,16 +135,6 @@ cygwin_internal (cygwin_getinfo_types t, ...)
{
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)
{

View File

@ -3,12 +3,10 @@
<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.

View File

@ -167,8 +167,8 @@ sync_with_child (PROCESS_INFORMATION &pi, HANDLE subproc_ready,
*/
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 ();
@ -263,7 +263,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
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;
}
@ -721,6 +721,7 @@ vfork ()
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

View File

@ -31,7 +31,6 @@ extern "C" size_t getpagesize ();
#define MINHEAP_SIZE (4 * 1024 * 1024)
/* Initialize the heap at process start up. */
void
heap_init ()
{
@ -64,12 +63,11 @@ 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);
@ -78,8 +76,13 @@ heap_init ()
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");
}
@ -87,7 +90,7 @@ heap_init ()
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)

View File

@ -16,51 +16,95 @@ details. */
#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;

View File

@ -316,6 +316,7 @@ void
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

View File

@ -2,12 +2,10 @@
<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
@ -41,12 +39,10 @@ cygwin_posix_to_win32_path_list_buf_size</link></para>
<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
@ -62,11 +58,9 @@ cygwin_win32_to_posix_path_list_buf_size</link></para>
<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
@ -79,11 +73,9 @@ cygwin_posix_to_win32_path_list</link>.</para>
<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
@ -96,12 +88,10 @@ cygwin_win32_to_posix_path_list</link>.</para>
<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
@ -117,12 +107,10 @@ size; use MAX_PATH if needed.</para>
<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
@ -137,12 +125,10 @@ size; use MAX_PATH if needed.</para>
<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
@ -158,12 +144,10 @@ buffer of sufficient size; use MAX_PATH if needed.</para>
<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
@ -179,11 +163,9 @@ buffer of sufficient size; use MAX_PATH if needed.</para>
<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
@ -200,14 +182,12 @@ parameter.</para>
<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

View File

@ -610,12 +610,10 @@ pinfo::release ()
<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

View File

@ -1,6 +1,6 @@
/* 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.
@ -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
*/
#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>
<funcsynopsis>
<funcprototype>
<funcdef>shared_info *
<function>cygwin_getshared</function></funcdef>
<void>
</funcprototype>
</funcsynopsis>
<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
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
@ -32,6 +32,7 @@ details. */
#include "cygtls.h"
#include "sigproc.h"
#include "perthread.h"
#include "exceptions.h"
/*
* Convenience defines
@ -1105,12 +1106,17 @@ wait_sig (VOID *self)
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))
{

View File

@ -2,11 +2,9 @@
<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.

View File

@ -23,10 +23,10 @@ details. */
#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)
@ -40,8 +40,6 @@ muto::init (const char *s)
return NULL;
}
name = s;
next = muto_start.next;
muto_start.next = this;
return this;
}
@ -71,6 +69,8 @@ int
muto::acquire (DWORD ms)
{
DWORD this_tid = GetCurrentThreadId ();
if (exiting_thread)
return this_tid == exiting_thread;
if (tid != this_tid)
{
@ -113,6 +113,8 @@ int
muto::release ()
{
DWORD this_tid = GetCurrentThreadId ();
if (exiting_thread)
return this_tid == exiting_thread;
if (tid != this_tid || !visits)
{
@ -135,6 +137,12 @@ muto::release ()
return 1; /* success. */
}
bool
muto::acquired ()
{
return tid == GetCurrentThreadId ();
}
/* Call only when we're exiting. This is not thread safe. */
void
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
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. */
@ -37,6 +40,8 @@ public:
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;
@ -44,6 +49,14 @@ 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*/

View File

@ -87,7 +87,7 @@ static int __stdcall stat_worker (const char *name, struct __stat64 *buf,
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++)
@ -101,13 +101,9 @@ close_all_files (void)
}
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 ();
}
@ -332,10 +328,7 @@ setsid (void)
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;
}

View File

@ -297,7 +297,7 @@ pthread::exit (void *value_ptr)
::exit (0);
else
{
_my_tls.remove ();
_my_tls.remove (INFINITE);
ExitThread (0);
}
}
@ -1783,9 +1783,6 @@ pthread::thread_init_wrapper (void *arg)
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

View File

@ -14,10 +14,7 @@ details. */
#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

View File

@ -1,44 +1,46 @@
//;# 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)

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
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
@ -150,11 +156,11 @@ extern HANDLE title_mutex;
})
/* 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