* cygthread.cc (cygthread::detach): Revert to just waiting for thred event
since waiting for anything else is racy. * timer.cc (timer_tracker::hcancel): Rename from cancel. (timer_tracker::cancel): New method. (timer_tracker::th): Remove. (timer_tracker::~timer_tracker): Call cancel method. (timer_tracker::timer_tracker): Ditto. (timer_tracker::timer_tracker): Always, clear cancel, even though it is probably not strictly necessary for ttstart. (timer_thread): Accommodate cancel -> hcancel rename. (timer_tracker::settime): Ditto. (timer_tracker::gettime): Ditto. (timer_delete): Ditto. * cygwin.din: Export _ctype_. * include/ctype.h: Mark that _ctype_ is imported.
This commit is contained in:
		| @@ -1,3 +1,22 @@ | ||||
| 2005-03-28  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* cygthread.cc (cygthread::detach): Revert to just waiting for thred | ||||
| 	event since waiting for anything else is racy. | ||||
| 	* timer.cc (timer_tracker::hcancel): Rename from cancel. | ||||
| 	(timer_tracker::cancel): New method. | ||||
| 	(timer_tracker::th): Remove. | ||||
| 	(timer_tracker::~timer_tracker): Call cancel method. | ||||
| 	(timer_tracker::timer_tracker): Ditto. | ||||
| 	(timer_tracker::timer_tracker): Always, clear cancel, even though it is | ||||
| 	probably not strictly necessary for ttstart. | ||||
| 	(timer_thread): Accommodate cancel -> hcancel rename. | ||||
| 	(timer_tracker::settime): Ditto. | ||||
| 	(timer_tracker::gettime): Ditto. | ||||
| 	(timer_delete): Ditto. | ||||
|  | ||||
| 	* cygwin.din: Export _ctype_. | ||||
| 	* include/ctype.h: Mark that _ctype_ is imported. | ||||
|  | ||||
| 2005-03-28  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* timer.cc (timer_tracker::timer_tracker): Eliminate simple | ||||
|   | ||||
| @@ -315,7 +315,7 @@ cygthread::detach (HANDLE sigwait) | ||||
|       if (!sigwait) | ||||
| 	/* If the caller specified a special handle for notification, wait for that. | ||||
| 	   This assumes that the thread in question is auto releasing. */ | ||||
| 	res = WaitForSingleObject (notify_detached ?: *this, INFINITE); | ||||
| 	res = WaitForSingleObject (*this, INFINITE); | ||||
|       else | ||||
| 	{ | ||||
| 	  /* Lower our priority and give priority to the read thread */ | ||||
|   | ||||
| @@ -4,6 +4,7 @@ EXPORTS | ||||
| __argc DATA | ||||
| __argv DATA | ||||
| __check_rhosts_file DATA | ||||
| _ctype_ DATA | ||||
| __cygwin_environ DATA | ||||
| __cygwin_user_data DATA | ||||
| __mb_cur_max DATA | ||||
|   | ||||
| @@ -38,7 +38,11 @@ int __cdecl _toupper(int); | ||||
| #define _X	0100 | ||||
| #define	_B	0200 | ||||
|  | ||||
| #ifdef __INSIDE_CYGWIN__ | ||||
| extern const char _ctype_[]; | ||||
| #else | ||||
| extern const __declspec(dllimport) char _ctype_[]; | ||||
| #endif | ||||
|  | ||||
| #if !defined(__cplusplus) || defined(__INSIDE_CYGWIN__) | ||||
| #define	isalpha(c)	((_ctype_+1)[(unsigned)(c)]&(_U|_L)) | ||||
|   | ||||
| @@ -26,11 +26,11 @@ struct timer_tracker | ||||
|   clockid_t clock_id; | ||||
|   sigevent evp; | ||||
|   timespec it_interval; | ||||
|   HANDLE cancel; | ||||
|   HANDLE hcancel; | ||||
|   HANDLE syncthread; | ||||
|   long long interval_us; | ||||
|   long long sleepto_us; | ||||
|   cygthread *th; | ||||
|   bool cancel (); | ||||
|   struct timer_tracker *next; | ||||
|   int settime (int, const itimerspec *, itimerspec *); | ||||
|   void gettime (itimerspec *); | ||||
| @@ -61,16 +61,25 @@ lock_timer_tracker::~lock_timer_tracker () | ||||
|   protect->release (); | ||||
| } | ||||
|  | ||||
| bool | ||||
| timer_tracker::cancel () | ||||
| { | ||||
|   if (!hcancel) | ||||
|     return false; | ||||
|      | ||||
|   SetEvent (hcancel); | ||||
|   if (WaitForSingleObject (syncthread, INFINITE) != WAIT_OBJECT_0) | ||||
|     api_fatal ("WFSO failed waiting for timer thread, %E"); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| timer_tracker::~timer_tracker () | ||||
| { | ||||
|   if (cancel) | ||||
|   if (cancel ()) | ||||
|     { | ||||
|       SetEvent (cancel); | ||||
|       th->detach (); | ||||
|       CloseHandle (cancel); | ||||
|       CloseHandle (hcancel); | ||||
| #ifdef DEBUGGING | ||||
|       th = NULL; | ||||
|       cancel = NULL; | ||||
|       hcancel = NULL; | ||||
| #endif | ||||
|     } | ||||
|   if (syncthread) | ||||
| @@ -90,9 +99,9 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e) | ||||
|     } | ||||
|   clock_id = c; | ||||
|   magic = TT_MAGIC; | ||||
|   hcancel = NULL; | ||||
|   if (this != &ttstart) | ||||
|     { | ||||
|       cancel = NULL; | ||||
|       lock_timer_tracker here; | ||||
|       next = ttstart.next; | ||||
|       ttstart.next = this; | ||||
| @@ -134,7 +143,7 @@ timer_thread (VOID *x) | ||||
| 	} | ||||
|  | ||||
|       debug_printf ("%p waiting for %u ms", x, sleep_ms); | ||||
|       switch (WaitForSingleObject (tt->cancel, sleep_ms)) | ||||
|       switch (WaitForSingleObject (tt->hcancel, sleep_ms)) | ||||
| 	{ | ||||
| 	case WAIT_TIMEOUT: | ||||
| 	  debug_printf ("timed out"); | ||||
| @@ -216,11 +225,7 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu | ||||
|   long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs (false); | ||||
|  | ||||
|   lock_timer_tracker here; | ||||
|   if (cancel) | ||||
|     { | ||||
|       SetEvent (cancel);	// should be closed when the thread exits | ||||
|       th->detach (); | ||||
|     } | ||||
|   cancel (); | ||||
|  | ||||
|   if (ovalue) | ||||
|     gettime (ovalue); | ||||
| @@ -230,15 +235,15 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu | ||||
|       sleepto_us = now + to_us (value->it_value); | ||||
|       interval_us = to_us (value->it_interval); | ||||
|       it_interval = value->it_interval; | ||||
|       if (!cancel) | ||||
| 	cancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); | ||||
|       if (!hcancel) | ||||
| 	hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); | ||||
|       else | ||||
| 	ResetEvent (cancel); | ||||
| 	ResetEvent (hcancel); | ||||
|       if (!syncthread) | ||||
| 	syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); | ||||
|       else | ||||
| 	ResetEvent (syncthread); | ||||
|       th = new cygthread (timer_thread, this, "itimer", syncthread); | ||||
|       (void) new cygthread (timer_thread, this, "itimer", syncthread); | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| @@ -247,7 +252,7 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu | ||||
| void | ||||
| timer_tracker::gettime (itimerspec *ovalue) | ||||
| { | ||||
|   if (!cancel) | ||||
|   if (!hcancel) | ||||
|     memset (ovalue, 0, sizeof (*ovalue)); | ||||
|   else | ||||
|     { | ||||
| @@ -333,12 +338,12 @@ timer_delete (timer_t timerid) | ||||
| void | ||||
| fixup_timers_after_fork () | ||||
| { | ||||
|   ttstart.cancel = ttstart.syncthread = NULL; | ||||
|   ttstart.hcancel = ttstart.syncthread = NULL; | ||||
|   for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) | ||||
|     { | ||||
|       timer_tracker *deleteme = tt->next; | ||||
|       tt->next = deleteme->next; | ||||
|       deleteme->cancel = deleteme->syncthread = NULL; | ||||
|       deleteme->hcancel = deleteme->syncthread = NULL; | ||||
|       delete deleteme; | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user