* 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:
Christopher Faylor 2005-03-28 19:31:23 +00:00
parent 12f9fb4972
commit dc000a8386
5 changed files with 52 additions and 23 deletions

View File

@ -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> 2005-03-28 Christopher Faylor <cgf@timesys.com>
* timer.cc (timer_tracker::timer_tracker): Eliminate simple * timer.cc (timer_tracker::timer_tracker): Eliminate simple

View File

@ -315,7 +315,7 @@ cygthread::detach (HANDLE sigwait)
if (!sigwait) if (!sigwait)
/* If the caller specified a special handle for notification, wait for that. /* If the caller specified a special handle for notification, wait for that.
This assumes that the thread in question is auto releasing. */ This assumes that the thread in question is auto releasing. */
res = WaitForSingleObject (notify_detached ?: *this, INFINITE); res = WaitForSingleObject (*this, INFINITE);
else else
{ {
/* Lower our priority and give priority to the read thread */ /* Lower our priority and give priority to the read thread */

View File

@ -4,6 +4,7 @@ EXPORTS
__argc DATA __argc DATA
__argv DATA __argv DATA
__check_rhosts_file DATA __check_rhosts_file DATA
_ctype_ DATA
__cygwin_environ DATA __cygwin_environ DATA
__cygwin_user_data DATA __cygwin_user_data DATA
__mb_cur_max DATA __mb_cur_max DATA

View File

@ -38,7 +38,11 @@ int __cdecl _toupper(int);
#define _X 0100 #define _X 0100
#define _B 0200 #define _B 0200
#ifdef __INSIDE_CYGWIN__
extern const char _ctype_[]; extern const char _ctype_[];
#else
extern const __declspec(dllimport) char _ctype_[];
#endif
#if !defined(__cplusplus) || defined(__INSIDE_CYGWIN__) #if !defined(__cplusplus) || defined(__INSIDE_CYGWIN__)
#define isalpha(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L)) #define isalpha(c) ((_ctype_+1)[(unsigned)(c)]&(_U|_L))

View File

@ -26,11 +26,11 @@ struct timer_tracker
clockid_t clock_id; clockid_t clock_id;
sigevent evp; sigevent evp;
timespec it_interval; timespec it_interval;
HANDLE cancel; HANDLE hcancel;
HANDLE syncthread; HANDLE syncthread;
long long interval_us; long long interval_us;
long long sleepto_us; long long sleepto_us;
cygthread *th; bool cancel ();
struct timer_tracker *next; struct timer_tracker *next;
int settime (int, const itimerspec *, itimerspec *); int settime (int, const itimerspec *, itimerspec *);
void gettime (itimerspec *); void gettime (itimerspec *);
@ -61,16 +61,25 @@ lock_timer_tracker::~lock_timer_tracker ()
protect->release (); 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 () timer_tracker::~timer_tracker ()
{ {
if (cancel) if (cancel ())
{ {
SetEvent (cancel); CloseHandle (hcancel);
th->detach ();
CloseHandle (cancel);
#ifdef DEBUGGING #ifdef DEBUGGING
th = NULL; hcancel = NULL;
cancel = NULL;
#endif #endif
} }
if (syncthread) if (syncthread)
@ -90,9 +99,9 @@ timer_tracker::timer_tracker (clockid_t c, const sigevent *e)
} }
clock_id = c; clock_id = c;
magic = TT_MAGIC; magic = TT_MAGIC;
hcancel = NULL;
if (this != &ttstart) if (this != &ttstart)
{ {
cancel = NULL;
lock_timer_tracker here; lock_timer_tracker here;
next = ttstart.next; next = ttstart.next;
ttstart.next = this; ttstart.next = this;
@ -134,7 +143,7 @@ timer_thread (VOID *x)
} }
debug_printf ("%p waiting for %u ms", x, sleep_ms); 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: case WAIT_TIMEOUT:
debug_printf ("timed out"); 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); long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs (false);
lock_timer_tracker here; lock_timer_tracker here;
if (cancel) cancel ();
{
SetEvent (cancel); // should be closed when the thread exits
th->detach ();
}
if (ovalue) if (ovalue)
gettime (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); sleepto_us = now + to_us (value->it_value);
interval_us = to_us (value->it_interval); interval_us = to_us (value->it_interval);
it_interval = value->it_interval; it_interval = value->it_interval;
if (!cancel) if (!hcancel)
cancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
else else
ResetEvent (cancel); ResetEvent (hcancel);
if (!syncthread) if (!syncthread)
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
else else
ResetEvent (syncthread); ResetEvent (syncthread);
th = new cygthread (timer_thread, this, "itimer", syncthread); (void) new cygthread (timer_thread, this, "itimer", syncthread);
} }
return 0; return 0;
@ -247,7 +252,7 @@ timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalu
void void
timer_tracker::gettime (itimerspec *ovalue) timer_tracker::gettime (itimerspec *ovalue)
{ {
if (!cancel) if (!hcancel)
memset (ovalue, 0, sizeof (*ovalue)); memset (ovalue, 0, sizeof (*ovalue));
else else
{ {
@ -333,12 +338,12 @@ timer_delete (timer_t timerid)
void void
fixup_timers_after_fork () fixup_timers_after_fork ()
{ {
ttstart.cancel = ttstart.syncthread = NULL; ttstart.hcancel = ttstart.syncthread = NULL;
for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */)
{ {
timer_tracker *deleteme = tt->next; timer_tracker *deleteme = tt->next;
tt->next = deleteme->next; tt->next = deleteme->next;
deleteme->cancel = deleteme->syncthread = NULL; deleteme->hcancel = deleteme->syncthread = NULL;
delete deleteme; delete deleteme;
} }
} }