]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/timer.c
2 * Please, don't add this file to libcommon because timers requires
3 * -lrt on systems with old libc (and probably also -lpthread for static
14 * Note the timeout is used for the first signal, then the signal is send
15 * repeatedly in interval ~1% of the original timeout to avoid race in signal
16 * handling -- for example you want to use timer to define timeout for a
23 * if the timeout is too short than it's possible that the signal is delivered
24 * before application enter the syscall function. For this reason timer send
25 * the signal repeatedly.
27 * The applications need to ensure that they can tolerate multiple signal
30 #ifdef HAVE_TIMER_CREATE
31 int setup_timer(struct ul_timer
*timer
,
32 struct itimerval
*timeout
,
33 void (*timeout_handler
)(int, siginfo_t
*, void *))
35 time_t sec
= timeout
->it_value
.tv_sec
;
36 long usec
= timeout
->it_value
.tv_usec
;
37 struct sigaction sig_a
;
38 static struct sigevent sig_e
= {
39 .sigev_notify
= SIGEV_SIGNAL
,
40 .sigev_signo
= SIGALRM
42 struct itimerspec val
= {
43 .it_value
.tv_sec
= sec
,
44 .it_value
.tv_nsec
= usec
* 1000,
45 .it_interval
.tv_sec
= sec
/ 100,
46 .it_interval
.tv_nsec
= (sec
? sec
% 100 : 1) * 10*1000*1000
49 if (sigemptyset(&sig_a
.sa_mask
))
52 sig_a
.sa_flags
= SA_SIGINFO
;
53 sig_a
.sa_sigaction
= timeout_handler
;
55 if (sigaction(SIGALRM
, &sig_a
, NULL
))
57 if (timer_create(CLOCK_MONOTONIC
, &sig_e
, &timer
->t_id
))
59 if (timer_settime(timer
->t_id
, 0, &val
, NULL
))
63 void cancel_timer(struct ul_timer
*timer
)
65 timer_delete(timer
->t_id
);
68 #else /* !HAVE_TIMER_CREATE */
70 int setup_timer(struct ul_timer
*timer
,
71 struct itimerval
*timeout
,
72 void (*timeout_handler
)(int, siginfo_t
*, void *))
76 memset(&sa
, 0, sizeof sa
);
77 memset(timer
, 0, sizeof(*timer
));
79 sa
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
80 sa
.sa_sigaction
= timeout_handler
;
82 if (sigaction(SIGALRM
, &sa
, &timer
->old_sa
))
84 if (setitimer(ITIMER_REAL
, timeout
, &timer
->old_timer
) != 0)
89 void cancel_timer(struct ul_timer
*timer
)
91 setitimer(ITIMER_REAL
, &timer
->old_timer
, NULL
);
92 sigaction(SIGALRM
, &timer
->old_sa
, NULL
);
95 #endif /* !HAVE_TIMER_CREATE */