diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2022-08-04 17:58:50 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2022-08-05 13:02:11 +0300 |
commit | 007e23d6390af11582e55453269b7a51c723d2dd (patch) | |
tree | 8e8cff3ca23f5e56d9766a5ee6c6abb366611b07 /winsup/cygwin/local_includes/timerfd.h | |
parent | 1e428bee1c5ef7c76ba4e46e6693b913edc9bbf3 (diff) |
Cygwin: Reorganize cygwin source dir
Create subdirs and move files accordingly:
- DevDocs: doc files
- fhandler: fhandler sources, split fhandler.cc into base.cc and null.cc
- local_includes: local include files
- scripts: scripts called during build
- sec: security sources
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/local_includes/timerfd.h')
-rw-r--r-- | winsup/cygwin/local_includes/timerfd.h | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/winsup/cygwin/local_includes/timerfd.h b/winsup/cygwin/local_includes/timerfd.h new file mode 100644 index 000000000..80688e79e --- /dev/null +++ b/winsup/cygwin/local_includes/timerfd.h @@ -0,0 +1,174 @@ +/* timerfd.h: Define timerfd classes + +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. */ + +#ifndef __TIMERFD_H__ +#define __TIMERFD_H__ + +#include "clock.h" +#include "ntdll.h" + +class timerfd_shared +{ + clockid_t _clockid; /* clockid */ + struct itimerspec _time_spec; /* original incoming itimerspec */ + LONG64 _exp_ts; /* start timestamp or next expire timestamp + in 100ns */ + LONG64 _interval; /* timer interval in 100ns */ + LONG64 _expiration_count; /* expiry counter */ + int _flags; /* settime flags */ + DWORD _tc_time; /* timestamp of the last WM_TIMECHANGE msg */ + + /* read access methods */ + LONG64 get_clock_now () const { return get_clock (_clockid)->n100secs (); } + struct itimerspec &time_spec () { return _time_spec; } + int get_flags () const { return _flags; } + void set_flags (int nflags) { _flags = nflags; } + + /* write access methods */ + void set_clockid (clockid_t clock_id) { _clockid = clock_id; } + void increment_expiration_count (LONG64 add) + { InterlockedAdd64 (&_expiration_count, add); } + void set_expiration_count (LONG64 newval) + { InterlockedExchange64 (&_expiration_count, newval); } + LONG64 reset_expiration_count () + { return InterlockedExchange64 (&_expiration_count, 0); } + int arm_timer (int, const struct itimerspec *); + int disarm_timer () + { + memset (&_time_spec, 0, sizeof _time_spec); + _exp_ts = 0; + _interval = 0; + /* _flags = 0; DON'T DO THAT. Required for TFD_TIMER_CANCEL_ON_SET */ + return 0; + } + void set_exp_ts (LONG64 ts) { _exp_ts = ts; } + + friend class timerfd_tracker; +}; + +class timerfd_tracker /* cygheap! */ +{ + /* Shared handles */ + HANDLE tfd_shared_hdl; /* handle to shared mem */ + HANDLE _access_mtx; /* controls access to shared data */ + HANDLE _arm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _disarm_evt; /* settimer sets event when timer is armed, + unsets event when timer gets disarmed. */ + HANDLE _timer; /* SynchronizationTimer */ + HANDLE _expired_evt; /* Signal if timer expired, Unsignal on read. */ + /* Process-local handles */ + HANDLE cancel_evt; /* Signal thread to exit. */ + HANDLE sync_thr; /* cygthread sync object. */ + /* pointer to shared timerfd, misc */ + timerfd_shared *tfd_shared; /* pointer to shared mem, needs + NtMapViewOfSection in each new process. */ + LONG instance_count; /* each open fd increments this. + If 0 -> cancel thread. */ + DWORD winpid; /* This is used @ fork/exec time to know if + this tracker already has been fixed up. */ + HWND window; /* window handle */ + ATOM atom; /* window class */ + + void create_timechange_window (); + void delete_timechange_window (); + void handle_timechange_window (); + + bool dtor (); + + bool enter_critical_section () + { + return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0) + == WAIT_OBJECT_0; + } + /* A version that honors a cancel event, for use in thread_func. */ + int enter_critical_section_cancelable (); + void leave_critical_section () + { + ReleaseMutex (_access_mtx); + } + + HANDLE arm_evt () const { return _arm_evt; } + HANDLE disarm_evt () const { return _disarm_evt; } + HANDLE timer () const { return _timer; } + HANDLE expired_evt () const { return _expired_evt; } + void timer_expired () { SetEvent (_expired_evt); } + int arm_timer (int flags, const struct itimerspec *new_value); + int disarm_timer () + { + ResetEvent (_arm_evt); + tfd_shared->disarm_timer (); + NtCancelTimer (timer (), NULL); + SetEvent (_disarm_evt); + return 0; + } + void timer_expired () const { timer_expired (); } + + LONG64 expiration_count () const { return tfd_shared->_expiration_count; } + void increment_expiration_count (LONG64 add) const + { tfd_shared->increment_expiration_count (add); } + void set_expiration_count (LONG64 exp_cnt) const + { tfd_shared->set_expiration_count ((LONG64) exp_cnt); } + LONG64 read_and_reset_expiration_count () + { + LONG64 ret = tfd_shared->reset_expiration_count (); + if (ret) + ResetEvent (_expired_evt); + return ret; + } + + struct timespec it_value () const + { return tfd_shared->time_spec ().it_value; } + struct timespec it_interval () const + { return tfd_shared->time_spec ().it_interval; } + + void set_clockid (clockid_t clock_id) { tfd_shared->set_clockid (clock_id); } + clock_t get_clockid () const { return tfd_shared->_clockid; } + LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); } + struct itimerspec &time_spec () { return tfd_shared->time_spec (); } + LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; } + LONG64 get_interval () const { return tfd_shared->_interval; } + void set_interval (LONG64 intv) { tfd_shared->_interval = intv; } + int get_flags () const { return tfd_shared->get_flags (); } + void set_flags (int nflags) { tfd_shared->set_flags (nflags); } + DWORD tc_time () const { return tfd_shared->_tc_time; } + void set_tc_time (DWORD new_time) { tfd_shared->_tc_time = new_time; } + + void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); } + LONG decrement_instances () { return InterlockedDecrement (&instance_count); } + + public: + void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} + timerfd_tracker () + : tfd_shared_hdl (NULL), _access_mtx (NULL), _arm_evt (NULL), + _disarm_evt (NULL), cancel_evt (NULL), sync_thr (NULL), tfd_shared (NULL), + instance_count (1), winpid (0), window (NULL), atom (0) {} + + void init_fixup_after_fork_exec (); + void fixup_after_fork_exec (bool); + void fixup_after_fork () + { + init_fixup_after_fork_exec (); + fixup_after_fork_exec (false); + } + void fixup_after_exec () { fixup_after_fork_exec (true); } + + void dup () { InterlockedIncrement (&instance_count); } + HANDLE get_timerfd_handle () const { return expired_evt (); } + LONG64 wait (bool); + int ioctl_set_ticks (uint64_t); + + int create (clockid_t); + int gettime (struct itimerspec *); + int settime (int, const struct itimerspec *, struct itimerspec *); + + static void dtor (timerfd_tracker *); + DWORD thread_func (); +}; + +#endif /* __TIMERFD_H__ */ |