Cygwin: (mostly) drop NT4 and Samba < 3.0 support
[newlib-cygwin.git] / winsup / cygwin / local_includes / timerfd.h
blob80688e79ec5e67b564b57fc5004a3b235fcdc685
1 /* timerfd.h: Define timerfd classes
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #ifndef __TIMERFD_H__
10 #define __TIMERFD_H__
12 #include "clock.h"
13 #include "ntdll.h"
15 class timerfd_shared
17 clockid_t _clockid; /* clockid */
18 struct itimerspec _time_spec; /* original incoming itimerspec */
19 LONG64 _exp_ts; /* start timestamp or next expire timestamp
20 in 100ns */
21 LONG64 _interval; /* timer interval in 100ns */
22 LONG64 _expiration_count; /* expiry counter */
23 int _flags; /* settime flags */
24 DWORD _tc_time; /* timestamp of the last WM_TIMECHANGE msg */
26 /* read access methods */
27 LONG64 get_clock_now () const { return get_clock (_clockid)->n100secs (); }
28 struct itimerspec &time_spec () { return _time_spec; }
29 int get_flags () const { return _flags; }
30 void set_flags (int nflags) { _flags = nflags; }
32 /* write access methods */
33 void set_clockid (clockid_t clock_id) { _clockid = clock_id; }
34 void increment_expiration_count (LONG64 add)
35 { InterlockedAdd64 (&_expiration_count, add); }
36 void set_expiration_count (LONG64 newval)
37 { InterlockedExchange64 (&_expiration_count, newval); }
38 LONG64 reset_expiration_count ()
39 { return InterlockedExchange64 (&_expiration_count, 0); }
40 int arm_timer (int, const struct itimerspec *);
41 int disarm_timer ()
43 memset (&_time_spec, 0, sizeof _time_spec);
44 _exp_ts = 0;
45 _interval = 0;
46 /* _flags = 0; DON'T DO THAT. Required for TFD_TIMER_CANCEL_ON_SET */
47 return 0;
49 void set_exp_ts (LONG64 ts) { _exp_ts = ts; }
51 friend class timerfd_tracker;
54 class timerfd_tracker /* cygheap! */
56 /* Shared handles */
57 HANDLE tfd_shared_hdl; /* handle to shared mem */
58 HANDLE _access_mtx; /* controls access to shared data */
59 HANDLE _arm_evt; /* settimer sets event when timer is armed,
60 unsets event when timer gets disarmed. */
61 HANDLE _disarm_evt; /* settimer sets event when timer is armed,
62 unsets event when timer gets disarmed. */
63 HANDLE _timer; /* SynchronizationTimer */
64 HANDLE _expired_evt; /* Signal if timer expired, Unsignal on read. */
65 /* Process-local handles */
66 HANDLE cancel_evt; /* Signal thread to exit. */
67 HANDLE sync_thr; /* cygthread sync object. */
68 /* pointer to shared timerfd, misc */
69 timerfd_shared *tfd_shared; /* pointer to shared mem, needs
70 NtMapViewOfSection in each new process. */
71 LONG instance_count; /* each open fd increments this.
72 If 0 -> cancel thread. */
73 DWORD winpid; /* This is used @ fork/exec time to know if
74 this tracker already has been fixed up. */
75 HWND window; /* window handle */
76 ATOM atom; /* window class */
78 void create_timechange_window ();
79 void delete_timechange_window ();
80 void handle_timechange_window ();
82 bool dtor ();
84 bool enter_critical_section ()
86 return (WaitForSingleObject (_access_mtx, INFINITE) & ~WAIT_ABANDONED_0)
87 == WAIT_OBJECT_0;
89 /* A version that honors a cancel event, for use in thread_func. */
90 int enter_critical_section_cancelable ();
91 void leave_critical_section ()
93 ReleaseMutex (_access_mtx);
96 HANDLE arm_evt () const { return _arm_evt; }
97 HANDLE disarm_evt () const { return _disarm_evt; }
98 HANDLE timer () const { return _timer; }
99 HANDLE expired_evt () const { return _expired_evt; }
100 void timer_expired () { SetEvent (_expired_evt); }
101 int arm_timer (int flags, const struct itimerspec *new_value);
102 int disarm_timer ()
104 ResetEvent (_arm_evt);
105 tfd_shared->disarm_timer ();
106 NtCancelTimer (timer (), NULL);
107 SetEvent (_disarm_evt);
108 return 0;
110 void timer_expired () const { timer_expired (); }
112 LONG64 expiration_count () const { return tfd_shared->_expiration_count; }
113 void increment_expiration_count (LONG64 add) const
114 { tfd_shared->increment_expiration_count (add); }
115 void set_expiration_count (LONG64 exp_cnt) const
116 { tfd_shared->set_expiration_count ((LONG64) exp_cnt); }
117 LONG64 read_and_reset_expiration_count ()
119 LONG64 ret = tfd_shared->reset_expiration_count ();
120 if (ret)
121 ResetEvent (_expired_evt);
122 return ret;
125 struct timespec it_value () const
126 { return tfd_shared->time_spec ().it_value; }
127 struct timespec it_interval () const
128 { return tfd_shared->time_spec ().it_interval; }
130 void set_clockid (clockid_t clock_id) { tfd_shared->set_clockid (clock_id); }
131 clock_t get_clockid () const { return tfd_shared->_clockid; }
132 LONG64 get_clock_now () const { return tfd_shared->get_clock_now (); }
133 struct itimerspec &time_spec () { return tfd_shared->time_spec (); }
134 LONG64 get_exp_ts () const { return tfd_shared->_exp_ts; }
135 LONG64 get_interval () const { return tfd_shared->_interval; }
136 void set_interval (LONG64 intv) { tfd_shared->_interval = intv; }
137 int get_flags () const { return tfd_shared->get_flags (); }
138 void set_flags (int nflags) { tfd_shared->set_flags (nflags); }
139 DWORD tc_time () const { return tfd_shared->_tc_time; }
140 void set_tc_time (DWORD new_time) { tfd_shared->_tc_time = new_time; }
142 void set_exp_ts (LONG64 ts) const { tfd_shared->set_exp_ts (ts); }
143 LONG decrement_instances () { return InterlockedDecrement (&instance_count); }
145 public:
146 void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;}
147 timerfd_tracker ()
148 : tfd_shared_hdl (NULL), _access_mtx (NULL), _arm_evt (NULL),
149 _disarm_evt (NULL), cancel_evt (NULL), sync_thr (NULL), tfd_shared (NULL),
150 instance_count (1), winpid (0), window (NULL), atom (0) {}
152 void init_fixup_after_fork_exec ();
153 void fixup_after_fork_exec (bool);
154 void fixup_after_fork ()
156 init_fixup_after_fork_exec ();
157 fixup_after_fork_exec (false);
159 void fixup_after_exec () { fixup_after_fork_exec (true); }
161 void dup () { InterlockedIncrement (&instance_count); }
162 HANDLE get_timerfd_handle () const { return expired_evt (); }
163 LONG64 wait (bool);
164 int ioctl_set_ticks (uint64_t);
166 int create (clockid_t);
167 int gettime (struct itimerspec *);
168 int settime (int, const struct itimerspec *, struct itimerspec *);
170 static void dtor (timerfd_tracker *);
171 DWORD thread_func ();
174 #endif /* __TIMERFD_H__ */