libubox
C utility functions for OpenWrt.
uloop.h File Reference
#include <sys/time.h>
#include <sys/types.h>
#include <stdbool.h>
#include <stdint.h>
#include <signal.h>
#include "list.h"

Go to the source code of this file.

Data Structures

struct  uloop_fd
 
struct  uloop_timeout
 
struct  uloop_process
 
struct  uloop_interval
 
struct  uloop_signal
 

Macros

#define USE_EPOLL
 
#define ULOOP_READ   (1 << 0)
 
#define ULOOP_WRITE   (1 << 1)
 
#define ULOOP_EDGE_TRIGGER   (1 << 2)
 
#define ULOOP_BLOCKING   (1 << 3)
 
#define ULOOP_EVENT_MASK   (ULOOP_READ | ULOOP_WRITE)
 
#define ULOOP_EVENT_BUFFERED   (1 << 4)
 
#define ULOOP_ERROR_CB   (1 << 6)
 

Typedefs

typedef void(* uloop_fd_handler) (struct uloop_fd *u, unsigned int events)
 
typedef void(* uloop_timeout_handler) (struct uloop_timeout *t)
 
typedef void(* uloop_process_handler) (struct uloop_process *c, int ret)
 
typedef void(* uloop_interval_handler) (struct uloop_interval *t)
 
typedef void(* uloop_signal_handler) (struct uloop_signal *s)
 

Functions

int uloop_fd_add (struct uloop_fd *sock, unsigned int flags)
 
int uloop_fd_delete (struct uloop_fd *sock)
 
int uloop_get_next_timeout (void)
 
int uloop_timeout_add (struct uloop_timeout *timeout)
 
int uloop_timeout_set (struct uloop_timeout *timeout, int msecs)
 
int uloop_timeout_cancel (struct uloop_timeout *timeout)
 
int uloop_timeout_remaining (struct uloop_timeout *timeout) __attribute__((deprecated("use uloop_timeout_remaining64")))
 
int64_t uloop_timeout_remaining64 (struct uloop_timeout *timeout)
 
int uloop_process_add (struct uloop_process *p)
 
int uloop_process_delete (struct uloop_process *p)
 
int uloop_interval_set (struct uloop_interval *timer, unsigned int msecs)
 
int uloop_interval_cancel (struct uloop_interval *timer)
 
int64_t uloop_interval_remaining (struct uloop_interval *timer)
 
int uloop_signal_add (struct uloop_signal *s)
 
int uloop_signal_delete (struct uloop_signal *s)
 
bool uloop_cancelling (void)
 
static void uloop_end (void)
 
int uloop_init (void)
 
int uloop_run_timeout (int timeout)
 
static int uloop_run (void)
 
void uloop_done (void)
 

Variables

bool uloop_cancelled
 
bool uloop_handle_sigchld
 
uloop_fd_handler uloop_fd_set_cb
 

Macro Definition Documentation

◆ ULOOP_BLOCKING

#define ULOOP_BLOCKING   (1 << 3)

Definition at line 50 of file uloop.h.

◆ ULOOP_EDGE_TRIGGER

#define ULOOP_EDGE_TRIGGER   (1 << 2)

Definition at line 49 of file uloop.h.

◆ ULOOP_ERROR_CB

#define ULOOP_ERROR_CB   (1 << 6)

Definition at line 60 of file uloop.h.

◆ ULOOP_EVENT_BUFFERED

#define ULOOP_EVENT_BUFFERED   (1 << 4)

Definition at line 55 of file uloop.h.

◆ ULOOP_EVENT_MASK

#define ULOOP_EVENT_MASK   (ULOOP_READ | ULOOP_WRITE)

Definition at line 52 of file uloop.h.

◆ ULOOP_READ

#define ULOOP_READ   (1 << 0)

Definition at line 47 of file uloop.h.

◆ ULOOP_WRITE

#define ULOOP_WRITE   (1 << 1)

Definition at line 48 of file uloop.h.

◆ USE_EPOLL

#define USE_EPOLL

Definition at line 30 of file uloop.h.

Typedef Documentation

◆ uloop_fd_handler

typedef void(* uloop_fd_handler) (struct uloop_fd *u, unsigned int events)

Definition at line 41 of file uloop.h.

◆ uloop_interval_handler

typedef void(* uloop_interval_handler) (struct uloop_interval *t)

Definition at line 44 of file uloop.h.

◆ uloop_process_handler

typedef void(* uloop_process_handler) (struct uloop_process *c, int ret)

Definition at line 43 of file uloop.h.

◆ uloop_signal_handler

typedef void(* uloop_signal_handler) (struct uloop_signal *s)

Definition at line 45 of file uloop.h.

◆ uloop_timeout_handler

typedef void(* uloop_timeout_handler) (struct uloop_timeout *t)

Definition at line 42 of file uloop.h.

Function Documentation

◆ uloop_cancelling()

bool uloop_cancelling ( void  )

Definition at line 653 of file uloop.c.

654 {
655  return uloop_run_depth > 0 && uloop_cancelled;
656 }
static int uloop_run_depth
Definition: uloop.c:70
bool uloop_cancelled
Definition: uloop.c:63

◆ uloop_done()

void uloop_done ( void  )

Definition at line 686 of file uloop.c.

687 {
688  uloop_setup_signals(false);
689 
690  if (poll_fd >= 0) {
691  close(poll_fd);
692  poll_fd = -1;
693  }
694 
695  if (waker_pipe >= 0) {
697  close(waker_pipe);
698  close(waker_fd.fd);
699  waker_pipe = -1;
700  }
701 
704 }
int fd
Definition: uloop.h:65
static void uloop_clear_processes(void)
Definition: uloop.c:645
static void uloop_setup_signals(bool add)
Definition: uloop.c:537
int uloop_fd_delete(struct uloop_fd *fd)
Definition: uloop.c:265
static struct uloop_fd waker_fd
Definition: uloop.c:116
static int waker_pipe
Definition: uloop.c:115
static int poll_fd
Definition: uloop.c:62
static void uloop_clear_timeouts(void)
Definition: uloop.c:637
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_end()

static void uloop_end ( void  )
inlinestatic

Definition at line 140 of file uloop.h.

141 {
142  uloop_cancelled = true;
143 }
bool uloop_cancelled
Definition: uloop.c:63
Here is the caller graph for this function:

◆ uloop_fd_add()

int uloop_fd_add ( struct uloop_fd sock,
unsigned int  flags 
)

Definition at line 235 of file uloop.c.

236 {
237  unsigned int fl;
238  int ret;
239 
240  if (!(flags & (ULOOP_READ | ULOOP_WRITE)))
241  return uloop_fd_delete(sock);
242 
243  if (!sock->registered && !(flags & ULOOP_BLOCKING)) {
244  fl = fcntl(sock->fd, F_GETFL, 0);
245  fl |= O_NONBLOCK;
246  fcntl(sock->fd, F_SETFL, fl);
247  }
248 
249  ret = register_poll(sock, flags);
250  if (ret < 0)
251  goto out;
252 
253  if (uloop_fd_set_cb)
254  uloop_fd_set_cb(sock, flags);
255 
256  sock->flags = flags;
257  sock->registered = true;
258  sock->eof = false;
259  sock->error = false;
260 
261 out:
262  return ret;
263 }
bool eof
Definition: uloop.h:66
bool registered
Definition: uloop.h:68
uint8_t flags
Definition: uloop.h:69
bool error
Definition: uloop.h:67
static int register_poll(struct uloop_fd *fd, unsigned int flags)
Definition: uloop-epoll.c:39
uloop_fd_handler uloop_fd_set_cb
Definition: uloop.c:72
#define ULOOP_WRITE
Definition: uloop.h:48
#define ULOOP_BLOCKING
Definition: uloop.h:50
#define ULOOP_READ
Definition: uloop.h:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_fd_delete()

int uloop_fd_delete ( struct uloop_fd sock)

Definition at line 265 of file uloop.c.

266 {
267  int ret;
268  int i;
269 
270  for (i = 0; i < cur_nfds; i++) {
271  if (cur_fds[cur_fd + i].fd != fd)
272  continue;
273 
274  cur_fds[cur_fd + i].fd = NULL;
275  }
276 
277  if (!fd->registered)
278  return 0;
279 
280  if (uloop_fd_set_cb)
281  uloop_fd_set_cb(fd, 0);
282 
283  fd->registered = false;
285  ret = __uloop_fd_delete(fd);
286  fd->flags = 0;
287 
288  return ret;
289 }
struct uloop_fd * fd
Definition: uloop.c:44
int fd
Definition: udebug-priv.h:27
static int __uloop_fd_delete(struct uloop_fd *sock)
Definition: uloop-epoll.c:62
static int cur_nfds
Definition: uloop.c:69
static int cur_fd
Definition: uloop.c:69
static struct uloop_fd_event cur_fds[10]
Definition: uloop.c:68
static bool uloop_fd_stack_event(struct uloop_fd *fd, int events)
Definition: uloop.c:165
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_get_next_timeout()

int uloop_get_next_timeout ( void  )

Definition at line 595 of file uloop.c.

596 {
597  struct uloop_timeout *timeout;
598  struct timeval tv;
599  int64_t diff;
600 
601  if (list_empty(&timeouts))
602  return -1;
603 
604  uloop_gettime(&tv);
605 
606  timeout = list_first_entry(&timeouts, struct uloop_timeout, list);
607  diff = tv_diff(&timeout->time, &tv);
608  if (diff < 0)
609  return 0;
610  if (diff > INT_MAX)
611  return INT_MAX;
612 
613  return diff;
614 }
static bool list_empty(const struct list_head *head)
Definition: list.h:69
#define list_first_entry(ptr, type, field)
Definition: list.h:121
struct timeval time
Definition: uloop.h:78
static struct list_head timeouts
Definition: uloop.c:58
static int64_t tv_diff(struct timeval *t1, struct timeval *t2)
Definition: uloop.c:291
static void uloop_gettime(struct timeval *tv)
Definition: uloop.c:319
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_init()

int uloop_init ( void  )

Definition at line 150 of file uloop.c.

151 {
152  if (uloop_init_pollfd() < 0)
153  return -1;
154 
155  if (waker_init() < 0) {
156  uloop_done();
157  return -1;
158  }
159 
160  uloop_setup_signals(true);
161 
162  return 0;
163 }
static int uloop_init_pollfd(void)
Definition: uloop-epoll.c:26
void uloop_done(void)
Definition: uloop.c:686
static int waker_init(void)
Definition: uloop.c:127
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_interval_cancel()

int uloop_interval_cancel ( struct uloop_interval timer)

Definition at line 458 of file uloop.c.

459 {
460  return timer_remove(timer);
461 }
static int timer_remove(struct uloop_interval *tm)
Definition: uloop-epoll.c:163
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_interval_remaining()

int64_t uloop_interval_remaining ( struct uloop_interval timer)

Definition at line 463 of file uloop.c.

464 {
465  return timer_next(timer);
466 }
static int64_t timer_next(struct uloop_interval *tm)
Definition: uloop-epoll.c:175
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_interval_set()

int uloop_interval_set ( struct uloop_interval timer,
unsigned int  msecs 
)

Definition at line 453 of file uloop.c.

454 {
455  return timer_register(timer, msecs);
456 }
static int timer_register(struct uloop_interval *tm, unsigned int msecs)
Definition: uloop-epoll.c:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_process_add()

int uloop_process_add ( struct uloop_process p)

Definition at line 391 of file uloop.c.

392 {
393  struct uloop_process *tmp;
394  struct list_head *h = &processes;
395 
396  if (p->pending)
397  return -1;
398 
399  list_for_each_entry(tmp, &processes, list) {
400  if (tmp->pid > p->pid) {
401  h = &tmp->list;
402  break;
403  }
404  }
405 
406  list_add_tail(&p->list, h);
407  p->pending = true;
408 
409  return 0;
410 }
static void list_add_tail(struct list_head *_new, struct list_head *head)
Definition: list.h:165
#define list_for_each_entry(p, h, field)
Definition: list.h:132
Definition: list.h:53
pid_t pid
Definition: uloop.h:87
struct list_head list
Definition: uloop.h:83
bool pending
Definition: uloop.h:84
static struct list_head processes
Definition: uloop.c:59
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_process_delete()

int uloop_process_delete ( struct uloop_process p)

Definition at line 412 of file uloop.c.

413 {
414  if (!p->pending)
415  return -1;
416 
417  list_del(&p->list);
418  p->pending = false;
419 
420  return 0;
421 }
static void list_del(struct list_head *entry)
Definition: list.h:96
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_run()

static int uloop_run ( void  )
inlinestatic

Definition at line 147 of file uloop.h.

148 {
149  return uloop_run_timeout(-1);
150 }
int uloop_run_timeout(int timeout)
Definition: uloop.c:658
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_run_timeout()

int uloop_run_timeout ( int  timeout)

Definition at line 658 of file uloop.c.

659 {
660  int next_time = 0;
661 
662  uloop_run_depth++;
663 
664  uloop_status = 0;
665  uloop_cancelled = false;
666  do {
668 
669  if (do_sigchld)
671 
672  if (uloop_cancelled)
673  break;
674 
675  next_time = uloop_get_next_timeout();
676  if (timeout >= 0 && (next_time < 0 || timeout < next_time))
677  next_time = timeout;
678  uloop_run_events(next_time);
679  } while (!uloop_cancelled && timeout < 0);
680 
681  --uloop_run_depth;
682 
683  return uloop_status;
684 }
static int uloop_status
Definition: uloop.c:65
int uloop_get_next_timeout(void)
Definition: uloop.c:595
static void uloop_run_events(int64_t timeout)
Definition: uloop.c:191
static void uloop_handle_processes(void)
Definition: uloop.c:423
static bool do_sigchld
Definition: uloop.c:66
static void uloop_process_timeouts(void)
Definition: uloop.c:616
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_signal_add()

int uloop_signal_add ( struct uloop_signal s)

Definition at line 550 of file uloop.c.

551 {
552  struct list_head *h = &signals;
553  struct uloop_signal *tmp;
554  struct sigaction sa;
555 
556  if (s->pending)
557  return -1;
558 
559  list_for_each_entry(tmp, &signals, list) {
560  if (tmp->signo > s->signo) {
561  h = &tmp->list;
562  break;
563  }
564  }
565 
566  list_add_tail(&s->list, h);
567  s->pending = true;
568 
569  sigaction(s->signo, NULL, &s->orig);
570 
571  if (s->orig.sa_handler != uloop_signal_wake) {
572  sa.sa_handler = uloop_signal_wake;
573  sa.sa_flags = 0;
574  sigemptyset(&sa.sa_mask);
575  sigaction(s->signo, &sa, NULL);
576  }
577 
578  return 0;
579 }
bool pending
Definition: uloop.h:108
struct list_head list
Definition: uloop.h:106
struct sigaction orig
Definition: uloop.h:107
int signo
Definition: uloop.h:111
static struct list_head signals
Definition: uloop.c:60
static void uloop_signal_wake(int signo)
Definition: uloop.c:468
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_signal_delete()

int uloop_signal_delete ( struct uloop_signal s)

Definition at line 581 of file uloop.c.

582 {
583  if (!s->pending)
584  return -1;
585 
586  list_del(&s->list);
587  s->pending = false;
588 
589  if (s->orig.sa_handler != uloop_signal_wake)
590  sigaction(s->signo, &s->orig, NULL);
591 
592  return 0;
593 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_timeout_add()

int uloop_timeout_add ( struct uloop_timeout timeout)

Definition at line 298 of file uloop.c.

299 {
300  struct uloop_timeout *tmp;
301  struct list_head *h = &timeouts;
302 
303  if (timeout->pending)
304  return -1;
305 
306  list_for_each_entry(tmp, &timeouts, list) {
307  if (tv_diff(&tmp->time, &timeout->time) > 0) {
308  h = &tmp->list;
309  break;
310  }
311  }
312 
313  list_add_tail(&timeout->list, h);
314  timeout->pending = true;
315 
316  return 0;
317 }
bool pending
Definition: uloop.h:75
struct list_head list
Definition: uloop.h:74
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_timeout_cancel()

int uloop_timeout_cancel ( struct uloop_timeout timeout)

Definition at line 348 of file uloop.c.

349 {
350  if (!timeout->pending)
351  return -1;
352 
353  list_del(&timeout->list);
354  timeout->pending = false;
355 
356  return 0;
357 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_timeout_remaining()

int uloop_timeout_remaining ( struct uloop_timeout timeout)

Definition at line 359 of file uloop.c.

360 {
361  int64_t td;
362  struct timeval now;
363 
364  if (!timeout->pending)
365  return -1;
366 
367  uloop_gettime(&now);
368 
369  td = tv_diff(&timeout->time, &now);
370 
371  if (td > INT_MAX)
372  return INT_MAX;
373  else if (td < INT_MIN)
374  return INT_MIN;
375  else
376  return (int)td;
377 }
Here is the call graph for this function:

◆ uloop_timeout_remaining64()

int64_t uloop_timeout_remaining64 ( struct uloop_timeout timeout)

Definition at line 379 of file uloop.c.

380 {
381  struct timeval now;
382 
383  if (!timeout->pending)
384  return -1;
385 
386  uloop_gettime(&now);
387 
388  return tv_diff(&timeout->time, &now);
389 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ uloop_timeout_set()

int uloop_timeout_set ( struct uloop_timeout timeout,
int  msecs 
)

Definition at line 328 of file uloop.c.

329 {
330  struct timeval *time = &timeout->time;
331 
332  if (timeout->pending)
333  uloop_timeout_cancel(timeout);
334 
335  uloop_gettime(time);
336 
337  time->tv_sec += msecs / 1000;
338  time->tv_usec += (msecs % 1000) * 1000;
339 
340  if (time->tv_usec > 1000000) {
341  time->tv_sec++;
342  time->tv_usec -= 1000000;
343  }
344 
345  return uloop_timeout_add(timeout);
346 }
int uloop_timeout_cancel(struct uloop_timeout *timeout)
Definition: uloop.c:348
int uloop_timeout_add(struct uloop_timeout *timeout)
Definition: uloop.c:298
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ uloop_cancelled

bool uloop_cancelled
extern

Definition at line 63 of file uloop.c.

◆ uloop_fd_set_cb

uloop_fd_handler uloop_fd_set_cb
extern

Definition at line 72 of file uloop.c.

◆ uloop_handle_sigchld

bool uloop_handle_sigchld
extern

Definition at line 64 of file uloop.c.