]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/timer.c
2 * No copyright is claimed. This code is in the public domain; do with
5 * Please, don't add this file to libcommon because timers requires
6 * -lrt on systems with old libc (and probably also -lpthread for static
17 * Note the timeout is used for the first signal, then the signal is send
18 * repeatedly in interval ~1% of the original timeout to avoid race in signal
19 * handling -- for example you want to use timer to define timeout for a
26 * if the timeout is too short than it's possible that the signal is delivered
27 * before application enter the syscall function. For this reason timer send
28 * the signal repeatedly.
30 * The applications need to ensure that they can tolerate multiple signal
33 #ifdef HAVE_TIMER_CREATE
34 int setup_timer(struct ul_timer
*timer
,
35 struct itimerval
*timeout
,
36 void (*timeout_handler
)(int, siginfo_t
*, void *))
38 time_t sec
= timeout
->it_value
.tv_sec
;
39 long usec
= timeout
->it_value
.tv_usec
;
40 struct sigaction sig_a
;
41 static struct sigevent sig_e
= {
42 .sigev_notify
= SIGEV_SIGNAL
,
43 .sigev_signo
= SIGALRM
45 struct itimerspec val
= {
46 .it_value
.tv_sec
= sec
,
47 .it_value
.tv_nsec
= usec
* 1000,
48 .it_interval
.tv_sec
= sec
/ 100,
49 .it_interval
.tv_nsec
= (sec
? sec
% 100 : 1) * 10*1000*1000
52 if (sigemptyset(&sig_a
.sa_mask
))
55 sig_a
.sa_flags
= SA_SIGINFO
;
56 sig_a
.sa_sigaction
= timeout_handler
;
58 if (sigaction(SIGALRM
, &sig_a
, NULL
))
60 if (timer_create(CLOCK_MONOTONIC
, &sig_e
, &timer
->t_id
))
62 if (timer_settime(timer
->t_id
, 0, &val
, NULL
))
66 void cancel_timer(struct ul_timer
*timer
)
68 timer_delete(timer
->t_id
);
71 #else /* !HAVE_TIMER_CREATE */
73 int setup_timer(struct ul_timer
*timer
,
74 struct itimerval
*timeout
,
75 void (*timeout_handler
)(int, siginfo_t
*, void *))
79 memset(&sa
, 0, sizeof sa
);
80 memset(timer
, 0, sizeof(*timer
));
82 sa
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
83 sa
.sa_sigaction
= timeout_handler
;
85 if (sigaction(SIGALRM
, &sa
, &timer
->old_sa
))
87 if (setitimer(ITIMER_REAL
, timeout
, &timer
->old_timer
) != 0)
92 void cancel_timer(struct ul_timer
*timer
)
94 setitimer(ITIMER_REAL
, &timer
->old_timer
, NULL
);
95 sigaction(SIGALRM
, &timer
->old_sa
, NULL
);
98 #endif /* !HAVE_TIMER_CREATE */