* - <private> is initialized by the poller's init() function, and cleaned by
* the term() function.
* - clo() should be used to do indicate the poller that fd will be closed.
- * - poll() calls the poller, expiring at <exp>
+ * - poll() calls the poller, expiring at <exp>, or immediately if <wake> is set
* - flags indicate what the poller supports (HAP_POLL_F_*)
*/
struct poller {
void *private; /* any private data for the poller */
void REGPRM1 (*clo)(const int fd); /* mark <fd> as closed */
- void REGPRM2 (*poll)(struct poller *p, int exp); /* the poller itself */
+ void REGPRM3 (*poll)(struct poller *p, int exp, int wake); /* the poller itself */
int REGPRM1 (*init)(struct poller *p); /* poller initialization */
void REGPRM1 (*term)(struct poller *p); /* termination of this poller */
int REGPRM1 (*test)(struct poller *p); /* pre-init check of the poller */
/*
* Linux epoll() poller
*/
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
{
int status;
int fd;
thread_harmless_now();
/* now let's wait for polled events */
- wait_time = compute_poll_timeout(exp);
+ wait_time = wake ? 0 : compute_poll_timeout(exp);
tv_entering_poll();
activity_count_runtime();
do {
break;
if (timeout || !wait_time)
break;
- if (signal_queue_len)
+ if (signal_queue_len || wake)
break;
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
break;
* "src/fd.c" for more information.
*/
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
{
int i;
int wait_time;
/*
* Determine how long to wait for events to materialise on the port.
*/
- wait_time = compute_poll_timeout(exp);
+ wait_time = wake ? 0 : compute_poll_timeout(exp);
tv_entering_poll();
activity_count_runtime();
break;
if (timeout || !wait_time)
break;
- if (signal_queue_len)
+ if (signal_queue_len || wake)
break;
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
break;
/*
* kqueue() poller
*/
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
{
int status;
int count, fd, wait_time;
fd_nbupdt = 0;
/* now let's wait for events */
- wait_time = compute_poll_timeout(exp);
+ wait_time = wake ? 0 : compute_poll_timeout(exp);
fd = global.tune.maxpollevents;
tv_entering_poll();
activity_count_runtime();
break;
if (timeout || !wait_time)
break;
- if (signal_queue_len)
+ if (signal_queue_len || wake)
break;
if (tick_isset(exp) && tick_is_expired(exp, now_ms))
break;
/*
* Poll() poller
*/
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
{
int status;
int fd;
}
/* now let's wait for events */
- wait_time = compute_poll_timeout(exp);
+ wait_time = wake ? 0 : compute_poll_timeout(exp);
tv_entering_poll();
activity_count_runtime();
status = poll(poll_events, nbfd, wait_time);
/*
* Select() poller
*/
-REGPRM2 static void _do_poll(struct poller *p, int exp)
+REGPRM3 static void _do_poll(struct poller *p, int exp, int wake)
{
int status;
int fd, i;
}
/* now let's wait for events */
- delta_ms = compute_poll_timeout(exp);
+ delta_ms = wake ? 0 : compute_poll_timeout(exp);
delta.tv_sec = (delta_ms / 1000);
delta.tv_usec = (delta_ms % 1000) * 1000;
tv_entering_poll();
/* Runs the polling loop */
static void run_poll_loop()
{
- int next, exp;
+ int next, wake;
tv_update_date(0,1);
while (1) {
break;
/* expire immediately if events are pending */
- exp = now_ms;
+ wake = 1;
if (fd_cache_mask & tid_bit)
activity[tid].wake_cache++;
else if (active_tasks_mask & tid_bit)
activity[tid].wake_tasks++;
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
} else
- exp = next;
+ wake = 0;
}
/* The poller will ensure it returns around <next> */
- cur_poller.poll(&cur_poller, exp);
+ cur_poller.poll(&cur_poller, next, wake);
if (sleeping_thread_mask & tid_bit)
_HA_ATOMIC_AND(&sleeping_thread_mask, ~tid_bit);
fd_process_cached_events();