Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-09-29 06:19:35 +0400
committerChristopher Faylor <me@cgf.cx>2002-09-29 06:19:35 +0400
commitaea1f301fcc9037a222ccf7c2f0f247cdeb2d06e (patch)
tree89921a181cefa4fd5316a2c23ea9624f77b70928 /winsup/cygwin
parentfc5dae1ccab502bdb35a7581a4db8a95cf311c8a (diff)
* cygthread.h (cygthread::terminate): Declare new function.
(cygthread::initialized): Change to 'int'. * cygthread.cc (cygthread::stub): Exit thread if initialized < 0. (cygthread::new): Ditto. (cygthread::runner): Ditto. Set initialized using xor to preserve sign. (cygthread::terminate): New function. * dcrt0.cc (do_exit): Call cygthread::terminate.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/cygthread.cc35
-rw-r--r--winsup/cygwin/cygthread.h3
-rw-r--r--winsup/cygwin/dcrt0.cc1
-rw-r--r--winsup/cygwin/thread.h164
5 files changed, 125 insertions, 89 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 591dcfc30..005dea333 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2002-09-28 Christopher Faylor <cgf@redhat.com>
+
+ * cygthread.h (cygthread::terminate): Declare new function.
+ (cygthread::initialized): Change to 'int'.
+ * cygthread.cc (cygthread::stub): Exit thread if initialized < 0.
+ (cygthread::new): Ditto.
+ (cygthread::runner): Ditto. Set initialized using xor to preserve
+ sign.
+ (cygthread::terminate): New function.
+ * dcrt0.cc (do_exit): Call cygthread::terminate.
+
2002-09-27 Robert Collins <rbtcollins@hotmail.com>
* thread.cc (pthread_key::run_destructor): Run_destructor is not
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index b81c4c16f..b2a62247b 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -19,7 +19,7 @@ static cygthread NO_COPY threads[6];
#define NTHREADS (sizeof (threads) / sizeof (threads[0]))
DWORD NO_COPY cygthread::main_thread_id;
-bool NO_COPY cygthread::initialized;
+int NO_COPY cygthread::initialized;
/* Initial stub called by cygthread constructor. Performs initial
per-thread initialization and loops waiting for new thread functions
@@ -68,7 +68,10 @@ cygthread::stub (VOID *arg)
#endif
SetEvent (info->ev);
info->__name = NULL;
- SuspendThread (info->h);
+ if (initialized < 0)
+ ExitThread (0);
+ else
+ SuspendThread (info->h);
}
}
@@ -78,9 +81,14 @@ DWORD WINAPI
cygthread::runner (VOID *arg)
{
for (unsigned i = 0; i < NTHREADS; i++)
- threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub, &threads[i],
- CREATE_SUSPENDED, &threads[i].avail);
- cygthread::initialized = true;
+ if (!initialized)
+ threads[i].h = CreateThread (&sec_none_nih, 0, cygthread::stub,
+ &threads[i], CREATE_SUSPENDED,
+ &threads[i].avail);
+ else
+ return 0;
+
+ initialized ^= 1;
return 0;
}
@@ -127,7 +135,10 @@ new (size_t)
for (;;)
{
- bool was_initialized = initialized;
+ int was_initialized = initialized;
+ if (was_initialized < 0)
+ ExitThread (0);
+
/* Search the threads array for an empty slot to use */
for (info = threads + NTHREADS - 1; info >= threads; info--)
if ((id = (DWORD) InterlockedExchange ((LPLONG) &info->avail, 0)))
@@ -140,6 +151,9 @@ new (size_t)
return info;
}
+ if (was_initialized < 0)
+ ExitThread (0);
+
if (!was_initialized)
Sleep (0); /* thread_runner is not finished yet. */
else
@@ -259,3 +273,12 @@ cygthread::detach ()
}
}
}
+
+void
+cygthread::terminate ()
+{
+ initialized = -1;
+ for (cygthread *info = threads + NTHREADS - 1; info >= threads; info--)
+ if (!(DWORD) InterlockedExchange ((LPLONG) &info->avail, 0) && info->id)
+ SetEvent (info->ev);
+}
diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h
index 37f7c6537..b55aec90c 100644
--- a/winsup/cygwin/cygthread.h
+++ b/winsup/cygwin/cygthread.h
@@ -17,7 +17,7 @@ class cygthread
VOID *arg;
bool is_freerange;
static DWORD main_thread_id;
- static bool initialized;
+ static int initialized;
static DWORD WINAPI runner (VOID *);
static DWORD WINAPI free_runner (VOID *);
static DWORD WINAPI stub (VOID *);
@@ -33,6 +33,7 @@ class cygthread
void * operator new (size_t);
static void * freerange ();
void exit_thread ();
+ static void terminate ();
};
#define cygself NULL
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 701fb140c..58fb823a0 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1024,6 +1024,7 @@ do_exit (int status)
window_terminate ();
events_terminate ();
shared_terminate ();
+ cygthread::terminate ();
minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n);
myself->exit (n);
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 4be0bf14d..0ac429e14 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -159,8 +159,8 @@ class verifyable_object
public:
long magic;
- verifyable_object (long);
- ~verifyable_object ();
+ verifyable_object (long);
+ virtual ~verifyable_object ();
};
typedef enum
@@ -197,7 +197,7 @@ public:
void *get () const;
pthread_key (void (*)(void *));
- ~pthread_key ();
+ ~pthread_key ();
static void fixup_before_fork();
static void fixup_after_fork();
@@ -225,23 +225,23 @@ template <class ListNode> void
List<ListNode>::Insert (ListNode *aNode)
{
if (!aNode)
- return;
+ return;
aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
}
template <class ListNode> ListNode *
List<ListNode>::Remove ( ListNode *aNode)
{
if (!aNode)
- return NULL;
+ return NULL;
if (!head)
- return NULL;
+ return NULL;
if (aNode == head)
- return Pop ();
+ return Pop ();
ListNode *resultPrev = head;
while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
- resultPrev = resultPrev->next;
+ resultPrev = resultPrev->next;
if (resultPrev)
- return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
+ return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
return NULL;
}
template <class ListNode> ListNode *
@@ -255,10 +255,10 @@ List<ListNode>::forEach (void (*callback)(ListNode *))
{
ListNode *aNode = head;
while (aNode)
- {
- callback (aNode);
- aNode = aNode->next;
- }
+ {
+ callback (aNode);
+ aNode = aNode->next;
+ }
}
class pthread_attr:public verifyable_object
@@ -271,8 +271,8 @@ public:
struct sched_param schedparam;
size_t stacksize;
- pthread_attr ();
- ~pthread_attr ();
+ pthread_attr ();
+ ~pthread_attr ();
};
class pthread_mutexattr:public verifyable_object
@@ -281,8 +281,8 @@ public:
static bool isGoodObject(pthread_mutexattr_t const *);
int pshared;
int mutextype;
- pthread_mutexattr ();
- ~pthread_mutexattr ();
+ pthread_mutexattr ();
+ ~pthread_mutexattr ();
};
class pthread_mutex:public verifyable_object
@@ -327,80 +327,80 @@ public:
LONG *sigtodo;
virtual void create (void *(*)(void *), pthread_attr *, void *);
- pthread ();
- virtual ~pthread ();
+ pthread ();
+ virtual ~pthread ();
- static void initMainThread(pthread *, HANDLE);
- static bool isGoodObject(pthread_t const *);
- static void atforkprepare();
- static void atforkparent();
- static void atforkchild();
+ static void initMainThread(pthread *, HANDLE);
+ static bool isGoodObject(pthread_t const *);
+ static void atforkprepare();
+ static void atforkparent();
+ static void atforkchild();
- /* API calls */
- static int cancel (pthread_t);
- static int join (pthread_t * thread, void **return_val);
- static int detach (pthread_t * thread);
- static int create (pthread_t * thread, const pthread_attr_t * attr,
+ /* API calls */
+ static int cancel (pthread_t);
+ static int join (pthread_t * thread, void **return_val);
+ static int detach (pthread_t * thread);
+ static int create (pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg);
- static int once (pthread_once_t *, void (*)(void));
- static int atfork(void (*)(void), void (*)(void), void (*)(void));
- static int suspend (pthread_t * thread);
- static int resume (pthread_t * thread);
+ static int once (pthread_once_t *, void (*)(void));
+ static int atfork(void (*)(void), void (*)(void), void (*)(void));
+ static int suspend (pthread_t * thread);
+ static int resume (pthread_t * thread);
- virtual void exit (void *value_ptr);
+ virtual void exit (void *value_ptr);
- virtual int cancel ();
-
- virtual void testcancel ();
- static void static_cancel_self ();
+ virtual int cancel ();
+
+ virtual void testcancel ();
+ static void static_cancel_self ();
- virtual int setcancelstate (int state, int *oldstate);
- virtual int setcanceltype (int type, int *oldtype);
+ virtual int setcancelstate (int state, int *oldstate);
+ virtual int setcanceltype (int type, int *oldtype);
- virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
- virtual void pop_cleanup_handler (int const execute);
+ virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ virtual void pop_cleanup_handler (int const execute);
- static pthread* self ();
- static void *thread_init_wrapper (void *);
+ static pthread* self ();
+ static void *thread_init_wrapper (void *);
- virtual unsigned long getsequence_np();
+ virtual unsigned long getsequence_np();
private:
- DWORD thread_id;
- __pthread_cleanup_handler *cleanup_stack;
- pthread_mutex mutex;
-
- void pop_all_cleanup_handlers (void);
- void precreate (pthread_attr *);
- void postcreate ();
- void setThreadIdtoCurrent();
- static void setTlsSelfPointer(pthread *);
- void cancel_self ();
- DWORD getThreadId ();
+ DWORD thread_id;
+ __pthread_cleanup_handler *cleanup_stack;
+ pthread_mutex mutex;
+
+ void pop_all_cleanup_handlers (void);
+ void precreate (pthread_attr *);
+ void postcreate ();
+ void setThreadIdtoCurrent();
+ static void setTlsSelfPointer(pthread *);
+ void cancel_self ();
+ DWORD getThreadId ();
};
class pthreadNull : public pthread
{
public:
- static pthread *getNullpthread();
- ~pthreadNull();
-
- /* From pthread These should never get called
- * as the ojbect is not verifyable
- */
- void create (void *(*)(void *), pthread_attr *, void *);
- void exit (void *value_ptr);
- int cancel ();
- void testcancel ();
- int setcancelstate (int state, int *oldstate);
- int setcanceltype (int type, int *oldtype);
- void push_cleanup_handler (__pthread_cleanup_handler *handler);
- void pop_cleanup_handler (int const execute);
- unsigned long getsequence_np();
+ static pthread *getNullpthread();
+ ~pthreadNull();
+
+ /* From pthread These should never get called
+ * as the ojbect is not verifyable
+ */
+ void create (void *(*)(void *), pthread_attr *, void *);
+ void exit (void *value_ptr);
+ int cancel ();
+ void testcancel ();
+ int setcancelstate (int state, int *oldstate);
+ int setcanceltype (int type, int *oldtype);
+ void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ void pop_cleanup_handler (int const execute);
+ unsigned long getsequence_np();
private:
- pthreadNull ();
- static pthreadNull _instance;
+ pthreadNull ();
+ static pthreadNull _instance;
};
class pthread_condattr:public verifyable_object
@@ -432,8 +432,8 @@ public:
void Signal ();
void fixup_after_fork ();
- pthread_cond (pthread_condattr *);
- ~pthread_cond ();
+ pthread_cond (pthread_condattr *);
+ ~pthread_cond ();
};
class pthread_once
@@ -464,8 +464,8 @@ public:
int TryWait ();
void fixup_after_fork ();
- semaphore (int, unsigned int);
- ~semaphore ();
+ semaphore (int, unsigned int);
+ ~semaphore ();
};
class callback
@@ -505,11 +505,11 @@ public:
void fixup_after_fork (void);
MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
- {
- pthread_prepare = NULL;
- pthread_child = NULL;
- pthread_parent = NULL;
- }
+ {
+ pthread_prepare = NULL;
+ pthread_child = NULL;
+ pthread_parent = NULL;
+ }
};
extern "C"