Commit Graph

10 Commits

Author SHA1 Message Date
Corinna Vinschen 98afd02be3 Cygwin: timerfd: rework implementation
timerfd_tracker and timerfd_shared classes:

- Just because handles are shared, we don't have to store them in
  shared memory.  Move share handles into timerfd_tracker class.

- Drop shared instance counter since it's not required anymore.
  timerfd_shared only stores the actual timer data.

- Drop timerfd_shared::create, just set clock id.

- Drop timerfd_shared::dtor, it's not required anymore.

- Drop timerfd_tracker::close, just call dtor where required.

- Rename timerfd_tracker::increment_instances to timerfd_tracker::dup.
  It's the only reason it exists...

- timerfd_tracker::dtor now checks the non-shared pointers for NULL
  before attempting to close them.

- timerfd_tracker::dtor handles decrementing the local instance count
  by itself.

- Add a method timerfd_tracker::init_fixup_after_fork_exec to set
  non-shared pointers to NULL.  Together with the dtor patches it
  fixes a problem with close_on_exec timerfd descriptors.

- Fix a bug in handling the thread synchronization event.  It's
  actually nice to create it before using it...

- Drop using sec_none{_nih} in InitializeObjectAttributes.  It's
  an unnecessary roundabout route just to get a NULL pointer.

- Slightly rework timechange window handling.

- Add more comments to explain what happens.

fhandler_timerfd:

- Drop cnew macro, it just hides what happens.

- fhandler_timerfd::fixup_after_exec now calls
  timerfd_tracker::init_fixup_after_fork_exec first, so a subsequent
  call to timerfd_tracker::dtor only works on valid handles.

- fhandler_timerfd::close directly calls timerfd_tracker::dtor now.

- Drop dtor call in fhandler_timerfd destructor.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-02-25 21:01:32 +01:00
Corinna Vinschen 289b7c09c8 Cygwin: timerfd: move ioctl error handling into timerfd_tracker
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-21 12:41:00 +01:00
Corinna Vinschen 528f4d4938 Cygwin: timerfd: rename overrun_count to expiration_count
The value returned by reading from a timerfd is not an overrun
count in the same sense as for posix timers, it's an expiry counter.
Reflect that in the name.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-21 12:26:51 +01:00
Corinna Vinschen e32d1510da Cygwin: timerfd: prepare for TFD_TIMER_CANCEL_ON_SET
Also drop debugging sleep and make sure overrun count is positive.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-19 20:53:38 +01:00
Corinna Vinschen 40481dbabb Cygwin: timerfd: reimplement from scratch
Using posix timers "timer_tracker" as base class for timerfd was flawed.
Posix timers are not inherited by child processes and don't survive
execve.  The method used by posix timers didn't allow to share timers
between processes. The timers were still per-process timers and worked
entirely separate from each other.  Reading from these timers via
different descriptors was only synchronized within the same process.

This does not reflect the timerfd semantics in Linux: The per-file
timers can be dup'ed and survive fork and execve.  They are still just
descriptors pointing to the same timer object originally created by
timerfd_create.  Synchronization is performed between all descriptor
instances of the same timer, system-wide.

Thus, reimplement timerfd using a timer instance in shared memory,
a kernel timer, and a handful of sync objects.

Every process maintains a per-process timerfd struct on the cygheap
maintaining a per-process thread.  Every process sharing the same
timerfd will run this thread checking the state of the timer, similar
to the posix timer thread, just working on the shared objects and
synchronizing its job with each other thread.

Drop the timerfd implementation in the posix timer code and move the
public API to fhandler_timerfd.c.  Keep the ttstart timer_tracker
anchor out of "NO_COPY" since the fixup_after_fork code should run to
avoid memory leakage.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-19 20:00:06 +01:00
Corinna Vinschen 7f983079d4 Cygwin: timerfd/signalfd: return EINVAL from write
Linux returns EINVAL, "fd is attached to an object which is unsuitable
for writing".  If we don't handle write locally, write returns EBADF.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-17 11:51:11 +01:00
Corinna Vinschen 173e067a31 Cygwin: timerfd: implement TFD_IOC_SET_TICKS ioctl
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-16 18:40:53 +01:00
Corinna Vinschen 0e8c7b8689 Cygwin: timerfd: implement execve semantics
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-16 18:40:26 +01:00
Corinna Vinschen 4195bae67f Cygwin: timerfd: implement fork semantics
- Puzzeling: Commit ec98d19a08
  changed ttstart to NO_COPY but kept all the code to handle
  fixup after fork.  Revert to not-NO_COPY and make timerfd
  fork work.

- On fixup_after_fork, keep timerfd timers and restart thread
  if they were armed in the parent.

- Move timerfd timer_trackers to cygheap.  Overload timer_tracker
  new and delete methods to handle timers accordingly.  This is not
  exactly required for fork, but exec will be grateful.

- Give up on TFD_TIMER_CANCEL_ON_SET for now.  There's no easy way
  to recognize a discontinuous change in a clock.

- Be paranoid when cleaning out ttstart.

- Fix some minor issues.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-16 15:33:51 +01:00
Corinna Vinschen 068182e26c Cygwin: timers: implement timerfd
First cut of a timerfd implementation.

Still TODO:
- fork/exec semantics
- timerfd_settime TFD_TIMER_CANCEL_ON_SET flag
- ioctl(TFD_IOC_SET_TICKS)
- bug fixes

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2019-01-15 22:02:33 +01:00