1 /** @file matchtimeout.h
2 * @brief Time limits for the matcher
4 /* Copyright (C) 2013,2014,2015,2016,2017 Olly Betts
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 #ifndef XAPIAN_INCLUDED_MATCHTIMEOUT_H
23 #define XAPIAN_INCLUDED_MATCHTIMEOUT_H
25 #ifdef HAVE_TIMER_CREATE
30 #include "safeunistd.h" // For _POSIX_* feature test macros.
35 set_timeout_flag(union sigval sv
)
37 *(reinterpret_cast<volatile bool*>(sv
.sival_ptr
)) = true;
42 // The monotonic clock is the better basis for timeouts, but not always
45 #ifndef _POSIX_MONOTONIC_CLOCK
46 const clockid_t TIMEOUT_CLOCK
= CLOCK_REALTIME
;
48 // Solaris defines CLOCK_MONOTONIC, but "man timer_create" doesn't mention it
49 // and when using it timer_create() fails with "EPERM" (perhaps you need to be
50 // root to use it? I can't test that).
52 // Solaris defines _POSIX_MONOTONIC_CLOCK so we need to special case.
53 const clockid_t TIMEOUT_CLOCK
= CLOCK_REALTIME
;
54 #elif defined __CYGWIN__
55 // https://cygwin.com/cygwin-api/std-notes.html currently (2016-05-13) says:
57 // clock_nanosleep currently supports only CLOCK_REALTIME and
58 // CLOCK_MONOTONIC. clock_setres, clock_settime, and timer_create
59 // currently support only CLOCK_REALTIME.
61 // So CLOCK_MONOTONIC is defined, but not supported by timer_create().
62 const clockid_t TIMEOUT_CLOCK
= CLOCK_REALTIME
;
64 const clockid_t TIMEOUT_CLOCK
= CLOCK_MONOTONIC
;
70 volatile bool expired
;
72 TimeOut(const TimeOut
&) = delete;
74 TimeOut
& operator=(const TimeOut
&) = delete;
77 explicit TimeOut(double limit
) : expired(false) {
79 sev
.sigev_notify
= SIGEV_THREAD
;
80 sev
.sigev_notify_function
= set_timeout_flag
;
81 sev
.sigev_notify_attributes
= NULL
;
82 sev
.sigev_value
.sival_ptr
=
83 static_cast<void*>(const_cast<bool*>(&expired
));
84 if (usual(timer_create(TIMEOUT_CLOCK
, &sev
, &timerid
) == 0)) {
85 struct itimerspec interval
;
86 interval
.it_interval
.tv_sec
= 0;
87 interval
.it_interval
.tv_nsec
= 0;
88 RealTime::to_timespec(limit
, &interval
.it_value
);
89 if (usual(timer_settime(timerid
, 0, &interval
, NULL
) == 0)) {
90 // Timeout successfully set.
93 timer_delete(timerid
);
96 sev
.sigev_notify
= SIGEV_NONE
;
100 if (sev
.sigev_notify
!= SIGEV_NONE
) {
101 timer_delete(timerid
);
102 sev
.sigev_notify
= SIGEV_NONE
;
106 bool timed_out() const { return expired
; }
111 explicit TimeOut(double) { }
112 bool timed_out() const { return false; }
116 #endif // XAPIAN_INCLUDED_MATCHTIMEOUT_H