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>
This commit is contained in:
Corinna Vinschen
2019-01-16 15:33:15 +01:00
parent f5808867cf
commit 4195bae67f
4 changed files with 58 additions and 20 deletions

View File

@@ -27,10 +27,19 @@ fhandler_timerfd::get_proc_fd_name (char *buf)
return strcpy (buf, "anon_inode:[timerfd]");
}
/* The timers connected to a descriptor are stored on the cygheap
together with their fhandler. */
#define cnew(name, ...) \
({ \
void* ptr = (void*) ccalloc (HEAP_FHANDLER, 1, sizeof (name)); \
ptr ? new (ptr) name (__VA_ARGS__) : NULL; \
})
int
fhandler_timerfd::timerfd (clockid_t clock_id, int flags)
{
timerid = (timer_t) new timer_tracker (clock_id, NULL, true);
timerid = (timer_t) cnew (timer_tracker, clock_id, NULL, true);
if (flags & TFD_NONBLOCK)
set_nonblocking (true);
if (flags & TFD_CLOEXEC)
@@ -150,13 +159,9 @@ fhandler_timerfd::dup (fhandler_base *child, int flags)
}
void
fhandler_timerfd::fixup_after_fork_exec (bool execing)
fhandler_timerfd::fixup_after_exec ()
{
if (!execing)
{
/* TODO after fork */
}
else if (!close_on_exec ())
if (!close_on_exec ())
{
/* TODO after exec */
}