From b6bd703781fdbe466e5a4d41e16743a642e7c0d3 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 1 Aug 2002 16:20:31 +0000 Subject: [PATCH] * Makefile.in (DLL_OFILES): Add cygthread.o. * dcrt0.cc (dll_crt0_1): Eliminate various thread initialization functions in favor of new cygthread class. * debug.cc: Remove thread manipulation functions. * debug.h: Ditto. * external.cc (cygwin_internal): Use cygthread method for determining thread name. Remove capability for setting thread name. * fhandler_console.cc (fhandler_console::read): Use cygthread method rather than iscygthread function. * fhandler_tty.cc (fhandler_tty_master::fhandler_tty_master): Use cygthread methods to create threads. (fhandler_tty_common::__acquire_output_mutex): Use cygthread method to retrieve thread name. * select.cc (pipeinf): Use cygthread pointer rather than handle. (start_thread_pipe): Ditto. (pipe_cleanup): Ditto. (serialinf): Ditto. (start_thread_serial): Ditto. (serial_cleanup): Ditto. (socketinf): Ditto. (start_thread_socket): Ditto. (socket_cleanup): Ditto. * sigproc.cc (hwait_sig): Ditto. (hwait_subproc): Ditto. (proc_terminate): Ditto. (sigproc_terminate): Ditto. (sigproc_init): Initialize cygthread hwait_sig pointer. (subproc_init): Initialize cygthread hwait_subproc pointer. (wait_sig): Rely on cygthread HANDLE operator. * strace.cc (strace::vsprntf): Use cygthread::name rather than threadname. * window.cc (gethwnd): Use cygthread method to initialize thread. --- winsup/cygwin/ChangeLog | 34 ++++++ winsup/cygwin/Makefile.in | 34 +++--- winsup/cygwin/cygthread.cc | 186 ++++++++++++++++++++++++++++++ winsup/cygwin/cygthread.h | 30 +++++ winsup/cygwin/dcrt0.cc | 8 +- winsup/cygwin/debug.cc | 143 ----------------------- winsup/cygwin/debug.h | 8 +- winsup/cygwin/external.cc | 8 +- winsup/cygwin/fhandler_console.cc | 3 +- winsup/cygwin/fhandler_tty.cc | 42 ++----- winsup/cygwin/select.cc | 36 +++--- winsup/cygwin/sigproc.cc | 57 ++------- winsup/cygwin/strace.cc | 3 +- winsup/cygwin/tty.cc | 1 + winsup/cygwin/window.cc | 15 +-- 15 files changed, 321 insertions(+), 287 deletions(-) create mode 100644 winsup/cygwin/cygthread.cc create mode 100644 winsup/cygwin/cygthread.h diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d1f6f0402..535cbdae4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,37 @@ +2002-08-01 Christopher Faylor + + * Makefile.in (DLL_OFILES): Add cygthread.o. + * dcrt0.cc (dll_crt0_1): Eliminate various thread initialization + functions in favor of new cygthread class. + * debug.cc: Remove thread manipulation functions. + * debug.h: Ditto. + * external.cc (cygwin_internal): Use cygthread method for determining + thread name. Remove capability for setting thread name. + * fhandler_console.cc (fhandler_console::read): Use cygthread method + rather than iscygthread function. + * fhandler_tty.cc (fhandler_tty_master::fhandler_tty_master): Use + cygthread methods to create threads. + (fhandler_tty_common::__acquire_output_mutex): Use cygthread method to + retrieve thread name. + * select.cc (pipeinf): Use cygthread pointer rather than handle. + (start_thread_pipe): Ditto. + (pipe_cleanup): Ditto. + (serialinf): Ditto. + (start_thread_serial): Ditto. + (serial_cleanup): Ditto. + (socketinf): Ditto. + (start_thread_socket): Ditto. + (socket_cleanup): Ditto. + * sigproc.cc (hwait_sig): Ditto. + (hwait_subproc): Ditto. + (proc_terminate): Ditto. + (sigproc_terminate): Ditto. + (sigproc_init): Initialize cygthread hwait_sig pointer. + (subproc_init): Initialize cygthread hwait_subproc pointer. + (wait_sig): Rely on cygthread HANDLE operator. + * strace.cc (strace::vsprntf): Use cygthread::name rather than threadname. + * window.cc (gethwnd): Use cygthread method to initialize thread. + 2002-07-31 Conrad Scott * fhandler.h (fhandler_base::get_r_no_interrupt): Make non-virtual. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index 826f417af..9774fdc11 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -118,22 +118,24 @@ MALLOC_OFILES=@MALLOC_OFILES@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a # Please maintain this list in sorted order, with maximum files per 80 col line -DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o cygserver_transport.o \ - cygserver_transport_pipes.o cygserver_transport_sockets.o dcrt0.o debug.o \ - delqueue.o dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \ - exec.o external.o fcntl.o fhandler.o fhandler_clipboard.o fhandler_console.o \ - fhandler_disk_file.o fhandler_dsp.o fhandler_floppy.o fhandler_mem.o \ - fhandler_proc.o fhandler_process.o fhandler_random.o fhandler_raw.o \ - fhandler_registry.o fhandler_serial.o fhandler_socket.o \ - fhandler_tape.o fhandler_termios.o fhandler_tty.o fhandler_virtual.o \ - fhandler_windows.o fhandler_zero.o fnmatch.o fork.o glob.o grp.o \ - heap.o init.o ioctl.o ipc.o localtime.o malloc.o miscfuncs.o mmap.o \ - net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o pthread.o regcomp.o \ - regerror.o regexec.o regfree.o registry.o resource.o scandir.o sched.o \ - sec_acl.o sec_helper.o security.o select.o shared.o shm.o shortcut.o \ - signal.o sigproc.o smallprint.o spawn.o strace.o strsep.o sync.o \ - syscalls.o sysconf.o syslog.o termios.o thread.o times.o tty.o uinfo.o \ - uname.o v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o window.o \ +DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o \ + cygserver_transport.o cygserver_transport_pipes.o \ + cygserver_transport_sockets.o cygthread.o dcrt0.o debug.o delqueue.o \ + dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \ + exec.o external.o fcntl.o fhandler.o fhandler_clipboard.o \ + fhandler_console.o fhandler_disk_file.o fhandler_dsp.o \ + fhandler_floppy.o fhandler_mem.o fhandler_proc.o fhandler_process.o \ + fhandler_random.o fhandler_raw.o fhandler_registry.o fhandler_serial.o \ + fhandler_socket.o fhandler_tape.o fhandler_termios.o fhandler_tty.o \ + fhandler_virtual.o fhandler_windows.o fhandler_zero.o fnmatch.o fork.o \ + glob.o grp.o heap.o init.o ioctl.o ipc.o localtime.o malloc.o \ + miscfuncs.o mmap.o net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o \ + pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \ + resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \ + select.o shared.o shm.o shortcut.o signal.o sigproc.o smallprint.o \ + spawn.o strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o \ + termios.o thread.o times.o tty.o uinfo.o uname.o v8_regexp.o \ + v8_regerror.o v8_regsub.o wait.o wincap.o window.o \ $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) GMON_OFILES:=gmon.o mcount.o profil.o diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc new file mode 100644 index 000000000..bbfcd8218 --- /dev/null +++ b/winsup/cygwin/cygthread.cc @@ -0,0 +1,186 @@ +/* cygthread.cc + + Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +class cygthread +{ + DWORD avail; + DWORD id; + HANDLE h; + HANDLE ev; + const char *__name; + LPTHREAD_START_ROUTINE func; + VOID *arg; + static DWORD main_thread_id; + static DWORD WINAPI runner (VOID *); + static DWORD WINAPI stub (VOID *); + public: + static const char * name (DWORD = 0); + cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); + cygthread () {}; + static void init (); + void detach (); + operator HANDLE (); + static bool is (); + void * operator new (size_t); +}; +#include "winsup.h" +#include "exceptions.h" +#include "security.h" +#include "cygthread.h" +#include + +#undef CloseHandle + +static cygthread NO_COPY threads[8]; +#define NTHREADS (sizeof (threads) / sizeof (threads[0])) + +static HANDLE NO_COPY hthreads[NTHREADS]; + +DWORD NO_COPY cygthread::main_thread_id; + +/* Initial stub called by makethread. Performs initial per-thread + initialization. */ +DWORD WINAPI +cygthread::stub (VOID *arg) +{ + DECLARE_TLS_STORAGE; + exception_list except_entry; + + /* Initialize this thread's ability to respond to things like + SIGSEGV or SIGFPE. */ + init_exceptions (&except_entry); + + cygthread *info = (cygthread *) arg; + info->ev = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + while (1) + { + if (!info->func) + ExitThread (0); + + /* Cygwin threads should not call ExitThread */ + info->func (info->arg); + + info->__name = NULL; + SetEvent (info->ev); + SuspendThread (info->h); + } +} + +DWORD WINAPI +cygthread::runner (VOID *arg) +{ + for (unsigned i = 0; i < NTHREADS; i++) + hthreads[i] = threads[i].h = + CreateThread (&sec_none_nih, 0, cygthread::stub, &threads[i], + CREATE_SUSPENDED, &threads[i].avail); + return 0; +} + +void +cygthread::init () +{ + DWORD tid; + HANDLE h = CreateThread (&sec_none_nih, 0, cygthread::runner, NULL, 0, &tid); + if (!h) + api_fatal ("can't start thread_runner, %E"); + CloseHandle (h); + main_thread_id = GetCurrentThreadId (); +} + +bool +cygthread::is () +{ + DWORD tid = GetCurrentThreadId (); + + for (DWORD i = 0; i < NTHREADS; i++) + if (threads[i].id == tid) + return 1; + + return 0; +} + +void * cygthread::operator +new (size_t) +{ + DWORD id; + cygthread *info; /* Various information needed by the newly created thread */ + + for (;;) + { + /* Search the threads array for an empty slot to use */ + for (info = threads; info < threads + NTHREADS; info++) + if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0))) + { + info->id = id; + return info; + } + + /* thread_runner may not be finished yet. */ + Sleep (0); + } +} + +cygthread::cygthread (LPTHREAD_START_ROUTINE start, LPVOID param, + const char *name): __name (name), func (start), arg (param) +{ + while (ResumeThread (h) == 0) + Sleep (0); +} + +/* Return the symbolic name of the current thread for debugging. + */ +const char * +cygthread::name (DWORD tid) +{ + const char *res = NULL; + if (!tid) + tid = GetCurrentThreadId (); + + if (tid == main_thread_id) + return "main"; + + for (DWORD i = 0; i < NTHREADS; i++) + if (threads[i].id == tid) + { + res = threads[i].__name ?: "exiting thread"; + break; + } + + if (!res) + { + static char buf[30] NO_COPY = {0}; + __small_sprintf (buf, "unknown (%p)", tid); + res = buf; + } + + return res; +} + +cygthread::operator +HANDLE () +{ + while (!ev) + Sleep (0); + return ev; +} + +void +cygthread::detach () +{ + if (!avail) + { + DWORD avail = id; + if (__name) + { + DWORD res = WaitForSingleObject (*this, INFINITE); + debug_printf ("WFSO returns %d", res); + } + id = 0; + (void) InterlockedExchange ((LPLONG) &this->avail, avail); + } +} diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h new file mode 100644 index 000000000..67e9d591e --- /dev/null +++ b/winsup/cygwin/cygthread.h @@ -0,0 +1,30 @@ +/* cygthread.h + + Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +class cygthread +{ + DWORD avail; + DWORD id; + HANDLE h; + HANDLE ev; + const char *__name; + LPTHREAD_START_ROUTINE func; + VOID *arg; + static DWORD main_thread_id; + static DWORD WINAPI runner (VOID *); + static DWORD WINAPI stub (VOID *); + public: + static const char * name (DWORD = 0); + cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); + cygthread () {}; + static void init (); + void detach (); + operator HANDLE (); + static bool is (); + void * operator new (size_t); +}; diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 42fed831f..8d4d72dd7 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -33,6 +33,7 @@ details. */ #include "shared_info.h" #include "cygwin_version.h" #include "dll_init.h" +#include "cygthread.h" #include "cygwin/cygserver_transport.h" #include "cygwin/cygserver.h" @@ -40,8 +41,8 @@ details. */ #define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0])) -HANDLE NO_COPY hMainProc = NULL; -HANDLE NO_COPY hMainThread = NULL; +HANDLE NO_COPY hMainProc; +HANDLE NO_COPY hMainThread; sigthread NO_COPY mainthread; // ID of the main thread @@ -571,10 +572,8 @@ dll_crt0_1 () user_data->resourcelocks->Init (); user_data->threadinterface->Init (user_data->forkee); - threadname_init (); (void) getpagesize (); /* initialize page size constant */ - regthread ("main", GetCurrentThreadId ()); mainthread.init ("mainthread"); // For use in determining if signals // should be blocked. @@ -632,6 +631,7 @@ dll_crt0_1 () /* Initialize the cygwin subsystem if this is the first process, or attach to shared data structures if it's already running. */ memory_init (); + cygthread::init (); ProtectHandle (hMainProc); ProtectHandle (hMainThread); diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index f918b87c0..280cbb44d 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -7,7 +7,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include "exceptions.h" #include "sync.h" #include "sigproc.h" #include "pinfo.h" @@ -25,148 +24,6 @@ details. */ #undef CloseHandle -static muto NO_COPY *threadname_lock = NULL; -#define lock_threadname() \ - do {if (threadname_lock) threadname_lock->acquire (INFINITE); } while (0) - -#define unlock_threadname() \ - do {if (threadname_lock) threadname_lock->release (); } while (0) - -typedef struct - { - DWORD id; - const char *name; - } thread_info; - -static NO_COPY thread_info threads[32]; // increase as necessary -#define NTHREADS (sizeof (threads) / sizeof (threads[0])) - -void -threadname_init () -{ - new_muto (threadname_lock); -} - -void __stdcall -regthread (const char *name, DWORD tid) -{ - lock_threadname (); - for (DWORD i = 0; i < NTHREADS; i++) - if (threads[i].name == NULL || strcmp (threads[i].name, name) == 0 || - threads[i].id == tid) - { - threads[i].name = name; - threads[i].id = tid; - break; - } - unlock_threadname (); -} - -int __stdcall -iscygthread () -{ - DWORD tid = GetCurrentThreadId (); - if (tid != mainthread.id) - for (DWORD i = 0; i < NTHREADS && threads[i].name != NULL; i++) - if (threads[i].id == tid) - return 1; - return 0; -} - -struct thread_start - { - LONG notavail; - LPTHREAD_START_ROUTINE func; - VOID *arg; - }; - -/* A place to store arguments to thread_stub since they can't be - stored on the stack. An available element is !notavail. */ -thread_start NO_COPY start_buf[NTHREADS] = {{0, NULL,NULL}}; - -/* Initial stub called by makethread. Performs initial per-thread - initialization. */ -static DWORD WINAPI -thread_stub (VOID *arg) -{ - DECLARE_TLS_STORAGE; - LPTHREAD_START_ROUTINE threadfunc = ((thread_start *) arg)->func; - VOID *threadarg = ((thread_start *) arg)->arg; - - exception_list except_entry; - - /* Give up our slot in the start_buf array */ - (void) InterlockedExchange (&((thread_start *) arg)->notavail, 0); - - /* Initialize this thread's ability to respond to things like - SIGSEGV or SIGFPE. */ - init_exceptions (&except_entry); - - ExitThread (threadfunc (threadarg)); -} - -/* Wrapper for CreateThread. Registers the thread name/id and ensures that - cygwin threads are properly initialized. */ -HANDLE __stdcall -makethread (LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, - const char *name) -{ - DWORD tid; - HANDLE h; - thread_start *info; /* Various information needed by the newly created thread */ - - for (;;) - { - /* Search the start_buf array for an empty slot to use */ - for (info = start_buf; info < start_buf + NTHREADS; info++) - if (!InterlockedExchange (&info->notavail, 1)) - goto out; - - /* Should never hit here, but be defensive anyway. */ - Sleep (0); - } - -out: - info->func = start; /* Real function to start */ - info->arg = param; /* The single parameter to the thread */ - - if ((h = CreateThread (&sec_none_nih, 0, thread_stub, (VOID *) info, flags, - &tid))) - regthread (name, tid); /* Register for debugging output. */ - - return h; -} - -/* Return the symbolic name of the current thread for debugging. - */ -const char * __stdcall -threadname (DWORD tid, int lockit) -{ - const char *res = NULL; - if (!tid) - tid = GetCurrentThreadId (); - - if (lockit) - lock_threadname (); - for (DWORD i = 0; i < NTHREADS && threads[i].name != NULL; i++) - if (threads[i].id == tid) - { - res = threads[i].name; - break; - } - if (lockit) - unlock_threadname (); - - if (!res) - { - static char buf[30] NO_COPY = {0}; - __small_sprintf (buf, "unknown (%p)", tid); - res = buf; - } - - return res; -} - #ifdef DEBUGGING /* Here lies extra debugging routines which help track down internal Cygwin problems when compiled with -DDEBUGGING . */ diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h index 719641f6f..90b202543 100644 --- a/winsup/cygwin/debug.h +++ b/winsup/cygwin/debug.h @@ -1,6 +1,6 @@ /* debug.h - Copyright 1998, 1999, 2000, 2001 Red Hat, Inc. + Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for @@ -31,12 +31,6 @@ DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regpar #define being_debugged() \ (IsDebuggerPresent () /* || GetLastError () == ERROR_PROC_NOT_FOUND*/) -void threadname_init (); -HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *) __attribute__ ((regparm(3))); -const char * __stdcall threadname (DWORD, int lockit = TRUE) __attribute__ ((regparm(2))); -void __stdcall regthread (const char *, DWORD) __attribute__ ((regparm(1))); -int __stdcall iscygthread (); - #ifndef DEBUGGING # define cygbench(s) # define ForceCloseHandle CloseHandle diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 1dad1e70f..571ea6742 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -27,6 +27,7 @@ details. */ #include "cygheap.h" #include "wincap.h" #include "heap.h" +#include "cygthread.h" static external_pinfo * fillout_pinfo (pid_t pid, int winpid) @@ -145,13 +146,12 @@ cygwin_internal (cygwin_getinfo_types t, ...) return 1; case CW_GETTHREADNAME: - return (DWORD) threadname (va_arg (arg, DWORD)); + return (DWORD) cygthread::name (va_arg (arg, DWORD)); case CW_SETTHREADNAME: { - char *name = va_arg (arg, char *); - regthread (name, va_arg (arg, DWORD)); - return 1; + set_errno (ENOSYS); + return 0; } case CW_GETPINFO: diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 4d767daf5..bae7c11a7 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -29,6 +29,7 @@ details. */ #include "sigproc.h" #include "pinfo.h" #include "shared_info.h" +#include "cygthread.h" #define CONVERT_LIMIT 4096 @@ -205,7 +206,7 @@ fhandler_console::read (void *pv, size_t buflen) char tmp[60]; w4[0] = h; - if (iscygthread ()) + if (cygthread::is ()) nwait = 1; else { diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 013e8dcc2..2ead75122 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -26,6 +26,7 @@ details. */ #include "shared_info.h" #include "cygwin/cygserver_transport.h" #include "cygwin/cygserver.h" +#include "cygthread.h" /* Tty master stuff */ @@ -43,7 +44,6 @@ fhandler_tty_master::fhandler_tty_master (int unit) int fhandler_tty_master::init (int ntty) { - HANDLE h; termios_printf ("Creating master for tty%d", ntty); if (init_console ()) @@ -62,38 +62,16 @@ fhandler_tty_master::init (int ntty) inuse = get_ttyp ()->create_inuse (TTY_MASTER_ALIVE); - h = makethread (process_input, NULL, 0, "ttyin"); - if (h == NULL) - { - termios_printf ("can't create input thread"); - return -1; - } - else - { - SetThreadPriority (h, THREAD_PRIORITY_HIGHEST); - CloseHandle (h); - } + cygthread *h; + h = new cygthread (process_input, NULL, "ttyin"); + SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); - h = makethread (process_ioctl, NULL, 0, "ttyioctl"); - if (h == NULL) - { - termios_printf ("can't create ioctl thread"); - return -1; - } - else - { - SetThreadPriority (h, THREAD_PRIORITY_HIGHEST); - CloseHandle (h); - } + h = new cygthread (process_ioctl, NULL, "ttyioctl"); + SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); - hThread = makethread (process_output, NULL, 0, "ttyout"); - if (hThread != NULL) - SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST); - else - { - termios_printf ("can't create output thread"); - return -1; - } + h = new cygthread (process_output, NULL, "ttyout"); + hThread = *h; + SetThreadPriority (h, THREAD_PRIORITY_HIGHEST); return 0; } @@ -125,7 +103,7 @@ fhandler_tty_common::__acquire_output_mutex (const char *fn, int ln, #else ostack[osi].fn = fn; ostack[osi].ln = ln; - ostack[osi].tname = threadname (0, 0); + ostack[osi].tname = cygthread::name (); termios_printf ("acquired for %s:%d, osi %d", fn, ln, osi); osi++; #endif diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 808882d3f..97674a92f 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -42,6 +42,7 @@ details. */ #include "sigproc.h" #include "perthread.h" #include "tty.h" +#include "cygthread.h" /* * All these defines below should be in sys/types.h @@ -512,7 +513,7 @@ static int start_thread_pipe (select_record *me, select_stuff *stuff); struct pipeinf { - HANDLE thread; + cygthread *thread; BOOL stop_thread_pipe; select_record *start; }; @@ -556,13 +557,14 @@ start_thread_pipe (select_record *me, select_stuff *stuff) { if (stuff->device_specific[FHDEVN(FH_PIPE)]) { - me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_PIPE)])->thread; + me->h = *((pipeinf *) stuff->device_specific[FHDEVN(FH_PIPE)])->thread; return 1; } pipeinf *pi = new pipeinf; pi->start = &stuff->start; pi->stop_thread_pipe = FALSE; - pi->thread = me->h = makethread (thread_pipe, (LPVOID)pi, 0, "select_pipe"); + pi->thread = new cygthread (thread_pipe, (LPVOID)pi, "select_pipe"); + me->h = *pi->thread; if (!me->h) return 0; stuff->device_specific[FHDEVN(FH_PIPE)] = (void *)pi; @@ -576,8 +578,7 @@ pipe_cleanup (select_record *, select_stuff *stuff) if (pi && pi->thread) { pi->stop_thread_pipe = true; - WaitForSingleObject (pi->thread, INFINITE); - CloseHandle (pi->thread); + pi->thread->detach (); delete pi; stuff->device_specific[FHDEVN(FH_PIPE)] = NULL; } @@ -865,7 +866,7 @@ static int start_thread_serial (select_record *me, select_stuff *stuff); struct serialinf { - HANDLE thread; + cygthread *thread; BOOL stop_thread_serial; select_record *start; }; @@ -1007,15 +1008,14 @@ start_thread_serial (select_record *me, select_stuff *stuff) { if (stuff->device_specific[FHDEVN(FH_SERIAL)]) { - me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_SERIAL)])->thread; + me->h = *((serialinf *) stuff->device_specific[FHDEVN(FH_SERIAL)])->thread; return 1; } serialinf *si = new serialinf; si->start = &stuff->start; si->stop_thread_serial = FALSE; - si->thread = me->h = makethread (thread_serial, (LPVOID)si, 0, "select_serial"); - if (!me->h) - return 0; + si->thread = new cygthread (thread_serial, (LPVOID)si, "select_serial"); + me->h = *si->thread; stuff->device_specific[FHDEVN(FH_SERIAL)] = (void *)si; return 1; } @@ -1027,8 +1027,7 @@ serial_cleanup (select_record *, select_stuff *stuff) if (si && si->thread) { si->stop_thread_serial = true; - WaitForSingleObject (si->thread, INFINITE); - CloseHandle (si->thread); + si->thread->detach (); delete si; stuff->device_specific[FHDEVN(FH_SERIAL)] = NULL; } @@ -1169,7 +1168,7 @@ fhandler_base::select_except (select_record *s) struct socketinf { - HANDLE thread; + cygthread *thread; winsock_fd_set readfds, writefds, exceptfds; SOCKET exitsock; struct sockaddr_in sin; @@ -1280,7 +1279,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) if ((si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)])) { - me->h = si->thread; + me->h = *si->thread; return 1; } @@ -1349,9 +1348,9 @@ start_thread_socket (select_record *me, select_stuff *stuff) stuff->device_specific[FHDEVN(FH_SOCKET)] = (void *) si; si->start = &stuff->start; select_printf ("stuff_start %p", &stuff->start); - si->thread = me->h = makethread (thread_socket, (LPVOID)si, 0, - "select_socket"); - return !!me->h; + si->thread = new cygthread (thread_socket, (LPVOID)si, "select_socket"); + me->h = *si->thread; + return 1; err: set_winsock_errno (); @@ -1387,10 +1386,9 @@ socket_cleanup (select_record *, select_stuff *stuff) closesocket (s); /* Wait for thread to go away */ - WaitForSingleObject (si->thread, INFINITE); + si->thread->detach (); shutdown (si->exitsock, SD_BOTH); closesocket (si->exitsock); - CloseHandle (si->thread); stuff->device_specific[FHDEVN(FH_SOCKET)] = NULL; delete si; } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 4964582b6..49947840e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -30,6 +30,7 @@ details. */ #define NEED_VFORK #include "perthread.h" #include "shared_info.h" +#include "cygthread.h" /* * Convenience defines @@ -92,8 +93,8 @@ Static HANDLE sigcomplete_main = NULL; // Event signaled when a signal has Static HANDLE sigcomplete_nonmain = NULL;// Semaphore raised for non-main // threads when a signal has finished // processing -Static HANDLE hwait_sig = NULL; // Handle of wait_sig thread -Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread +Static cygthread *hwait_sig; // Handle of wait_sig thread +Static cygthread *hwait_subproc; // Handle of sig_subproc thread Static HANDLE wait_sig_inited = NULL; // Control synchronization of // message queue startup @@ -459,20 +460,10 @@ proc_terminate (void) /* Signal processing is assumed to be blocked in this routine. */ if (hwait_subproc) { - int rc; proc_loop_wait = 0; // Tell wait_subproc thread to exit wake_wait_subproc (); // Wake wait_subproc loop - - /* Wait for wait_subproc thread to exit (but not *too* long) */ - if ((rc = WaitForSingleObject (hwait_subproc, WWSP)) != WAIT_OBJECT_0) - if (rc == WAIT_TIMEOUT) - system_printf ("WFSO(hwait_subproc) timed out"); - else - system_printf ("WFSO(hwait_subproc), rc %d, %E", rc); - - HANDLE h = hwait_subproc; + hwait_subproc->detach (); hwait_subproc = NULL; - ForceCloseHandle1 (h, hwait_subproc); sync_proc_subproc->acquire(WPSP); (void) proc_subproc (PROC_CLEARWAIT, 1); @@ -580,13 +571,7 @@ sigproc_init () signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL); ProtectHandle (signal_arrived); - if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig"))) - { - system_printf ("cannot create wait_sig thread, %E"); - api_fatal ("terminating"); - } - - ProtectHandle (hwait_sig); + hwait_sig = new cygthread (wait_sig, NULL, "sig"); /* sync_proc_subproc is used by proc_subproc. It serialises * access to the children and zombie arrays. @@ -615,7 +600,6 @@ sigproc_init () void __stdcall sigproc_terminate (void) { - HANDLE h = hwait_sig; hwait_sig = NULL; if (GetCurrentThreadId () == sigtid) @@ -637,29 +621,6 @@ sigproc_terminate (void) sigproc_printf ("entering"); sig_loop_wait = 0; // Tell wait_sig to exit when it is // finished with anything it is doing - // sig_dispatch_pending (TRUE); // wake up and die - /* In case of a sigsuspend */ - // SetEvent (signal_arrived); - - /* If !hwait_sig, then the process probably hasn't even finished - * its initialization phase. - */ - if (0 && hwait_sig) - { - if (GetCurrentThreadId () != sigtid) - WaitForSingleObject (h, 10000); - ForceCloseHandle1 (h, hwait_sig); - - - if (GetCurrentThreadId () != sigtid) - { - ForceCloseHandle (sigcomplete_main); - ForceCloseHandle (sigcomplete_nonmain); - ForceCloseHandle (sigcatch_main); - ForceCloseHandle (sigcatch_nonmain); - ForceCloseHandle (sigcatch_nosync); - } - } sigproc_printf ("done"); } @@ -847,11 +808,9 @@ subproc_init (void) * the hchildren array. */ events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); - if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "proc"))) - system_printf ("cannot create wait_subproc thread, %E"); + hwait_subproc = new cygthread (wait_subproc, NULL, "proc"); ProtectHandle (events[0]); - ProtectHandle (hwait_subproc); - sigproc_printf ("started wait_subproc thread %p", hwait_subproc); + sigproc_printf ("started wait_subproc thread %p", (HANDLE) *hwait_subproc); } /* Initialize some of the memory block passed to child processes @@ -1074,7 +1033,7 @@ static DWORD WINAPI wait_sig (VOID *) { /* Initialization */ - (void) SetThreadPriority (hwait_sig, WAIT_SIG_PRIORITY); + (void) SetThreadPriority (*hwait_sig, WAIT_SIG_PRIORITY); /* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and * by foreign processes to force an examination of diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index 91e2cbcd1..17dcf3957 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -18,6 +18,7 @@ details. */ #include "perprocess.h" #include "cygwin_version.h" #include "hires.h" +#include "cygthread.h" #define PROTECT(x) x[sizeof(x)-1] = 0 #define CHECK(x) if (x[sizeof(x)-1] != 0) { small_printf("array bound exceeded %d\n", __LINE__); ExitProcess(1); } @@ -111,7 +112,7 @@ strace::vsprntf (char *buf, const char *func, const char *infmt, va_list ap) char fmt[80]; static NO_COPY int nonewline = FALSE; DWORD err = GetLastError (); - const char *tn = threadname (0); + const char *tn = cygthread::name (); char *pn = __progname ?: myself->progname; int microsec = microseconds (); diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 8f7fe4013..11c25b161 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -144,6 +144,7 @@ tty_list::terminate (void) ForceCloseHandle1 (t->to_slave, to_pty); ForceCloseHandle1 (t->from_slave, from_pty); CloseHandle (tty_master->inuse); + // FIXME This should be using a cygthread object WaitForSingleObject (tty_master->hThread, INFINITE); t->init (); diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc index 38b19c418..7919ab17e 100644 --- a/winsup/cygwin/window.cc +++ b/winsup/cygwin/window.cc @@ -24,6 +24,7 @@ details. */ #include "cygerrno.h" #include "perprocess.h" #include "security.h" +#include "cygthread.h" static NO_COPY UINT timer_active = 0; static NO_COPY struct itimerval itv; @@ -131,19 +132,11 @@ gethwnd () if (ourhwnd != NULL) return ourhwnd; - HANDLE hThread; + cygthread *h; window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - hThread = makethread (Winmain, NULL, 0, "win"); - if (!hThread) - { - system_printf ("Cannot start window thread"); - } - else - { - SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST); - CloseHandle (hThread); - } + h = new cygthread (Winmain, NULL, "win"); + SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); WaitForSingleObject (window_started, INFINITE); CloseHandle (window_started); return ourhwnd;