diff options
Diffstat (limited to 'winsup/cygwin/timer.cc')
-rw-r--r-- | winsup/cygwin/timer.cc | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/winsup/cygwin/timer.cc b/winsup/cygwin/timer.cc deleted file mode 100644 index 8e836e9d4..000000000 --- a/winsup/cygwin/timer.cc +++ /dev/null @@ -1,275 +0,0 @@ -/* timer.cc - - Copyright 2004 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "winsup.h" -#include <time.h> -#include <stdlib.h> -#include "cygerrno.h" -#include "security.h" -#include "hires.h" -#include "thread.h" -#include "cygtls.h" -#include "cygthread.h" -#include "sigproc.h" -#include "sync.h" - -#define TT_MAGIC 0x513e4a1c -struct timer_tracker -{ - static muto *protect; - unsigned magic; - clockid_t clock_id; - sigevent evp; - itimerspec it; - HANDLE cancel; - int flags; - cygthread *th; - struct timer_tracker *next; - int settime (int, const itimerspec *, itimerspec *); - timer_tracker (clockid_t, const sigevent *); - timer_tracker (); -}; - -timer_tracker ttstart; - -muto *timer_tracker::protect; - -timer_tracker::timer_tracker () -{ - new_muto (protect); -} - -timer_tracker::timer_tracker (clockid_t c, const sigevent *e) -{ - if (e != NULL) - evp = *e; - else - { - evp.sigev_notify = SIGEV_SIGNAL; - evp.sigev_signo = SIGALRM; - evp.sigev_value.sival_ptr = this; - } - clock_id = c; - cancel = NULL; - flags = 0; - memset (&it, 0, sizeof (it)); - protect->acquire (); - next = ttstart.next; - ttstart.next = this; - protect->release (); - magic = TT_MAGIC; -} - -static long long -to_us (timespec& ts) -{ - long long res = ts.tv_sec; - res *= 1000000; - res += ts.tv_nsec / 1000 + ((ts.tv_nsec % 1000) >= 500 ? 1 : 0); - return res; -} - -static NO_COPY itimerspec itzero; -static NO_COPY timespec tzero; - -static DWORD WINAPI -timer_thread (VOID *x) -{ - timer_tracker *tp = ((timer_tracker *) x); - timer_tracker tt = *tp; - for (bool first = true; ; first = false) - { - long long sleep_us = to_us (first ? tt.it.it_value : tt.it.it_interval); - long long sleep_to = sleep_us; - long long now = gtod.usecs (false); - if (tt.flags & TIMER_ABSTIME) - sleep_us -= now; - else - sleep_to += now; - - DWORD sleep_ms = (sleep_us < 0) ? 0 : (sleep_us / 1000); - debug_printf ("%p waiting for %u ms, first %d", x, sleep_ms, first); - tp->it.it_value = tzero; - switch (WaitForSingleObject (tt.cancel, sleep_ms)) - { - case WAIT_TIMEOUT: - debug_printf ("timed out"); - break; - case WAIT_OBJECT_0: - now = gtod.usecs (false); - sleep_us = sleep_to - now; - if (sleep_us < 0) - sleep_us = 0; - tp->it.it_value.tv_sec = sleep_us / 1000000; - tp->it.it_value.tv_nsec = (sleep_us % 1000000) * 1000; - debug_printf ("%p cancelled, elapsed %D", x, sleep_us); - goto out; - default: - debug_printf ("%p timer wait failed, %E", x); - goto out; - } - - switch (tt.evp.sigev_notify) - { - case SIGEV_SIGNAL: - { - siginfo_t si; - memset (&si, 0, sizeof (si)); - si.si_signo = tt.evp.sigev_signo; - si.si_sigval.sival_ptr = tt.evp.sigev_value.sival_ptr; - debug_printf ("%p sending sig %d", x, tt.evp.sigev_signo); - sig_send (NULL, si); - break; - } - case SIGEV_THREAD: - { - pthread_t notify_thread; - debug_printf ("%p starting thread", x); - int rc = pthread_create (¬ify_thread, tt.evp.sigev_notify_attributes, - (void * (*) (void *)) tt.evp.sigev_notify_function, - &tt.evp.sigev_value); - if (rc) - { - debug_printf ("thread creation failed, %E"); - return 0; - } - // FIXME: pthread_join? - break; - } - } - if (!tt.it.it_interval.tv_sec && !tt.it.it_interval.tv_nsec) - break; - tt.flags = 0; - debug_printf ("looping"); - } - -out: - CloseHandle (tt.cancel); - // FIXME: race here but is it inevitable? - if (tt.cancel == tp->cancel) - tp->cancel = NULL; - return 0; -} - -static bool -it_bad (const timespec& t) -{ - if (t.tv_nsec < 0 || t.tv_nsec >= 1000000000 || t.tv_sec < 0) - { - set_errno (EINVAL); - return true; - } - return false; -} - -int -timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue) -{ - if (!value) - { - set_errno (EINVAL); - return -1; - } - - if (__check_invalid_read_ptr_errno (value, sizeof (*value))) - return -1; - - if (ovalue && check_null_invalid_struct_errno (ovalue)) - return -1; - - itimerspec *elapsed; - if (!cancel) - elapsed = &itzero; - else - { - SetEvent (cancel); // should be closed when the thread exits - th->detach (); - elapsed = ⁢ - } - - if (ovalue) - *ovalue = *elapsed; - - if (value->it_value.tv_sec || value->it_value.tv_nsec) - { - if (it_bad (value->it_value)) - return -1; - if (it_bad (value->it_interval)) - return -1; - flags = in_flags; - cancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - it = *value; - th = new cygthread (timer_thread, this, "itimer"); - } - - return 0; -} - -extern "C" int -timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid) -{ - if (evp && check_null_invalid_struct_errno (evp)) - return -1; - if (check_null_invalid_struct_errno (timerid)) - return -1; - - if (clock_id != CLOCK_REALTIME) - { - set_errno (EINVAL); - return -1; - } - - *timerid = (timer_t) new timer_tracker (clock_id, evp); - return 0; -} - -extern "C" int -timer_settime (timer_t timerid, int flags, const struct itimerspec *value, - struct itimerspec *ovalue) -{ - timer_tracker *tt = (timer_tracker *) timerid; - if (check_null_invalid_struct_errno (tt) || tt->magic != TT_MAGIC) - return -1; - return tt->settime (flags, value, ovalue); -} - -extern "C" int -timer_delete (timer_t timerid) -{ - timer_tracker *in_tt = (timer_tracker *) timerid; - if (check_null_invalid_struct_errno (in_tt) || in_tt->magic != TT_MAGIC) - return -1; - - timer_tracker::protect->acquire (); - for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next) - if (tt->next == in_tt) - { - timer_tracker *deleteme = tt->next; - tt->next = deleteme->next; - delete deleteme; - timer_tracker::protect->release (); - return 0; - } - timer_tracker::protect->release (); - - set_errno (EINVAL); - return 0; -} - -void -fixup_timers_after_fork () -{ - for (timer_tracker *tt = &ttstart; tt->next != NULL; /* nothing */) - { - timer_tracker *deleteme = tt->next; - tt->next = deleteme->next; - delete deleteme; - } -} |