libubox
C utility functions for OpenWrt.
uloop-kqueue.c File Reference

Go to the source code of this file.

Functions

static int uloop_init_pollfd (void)
 
static uint16_t get_flags (unsigned int flags, unsigned int mask)
 
static int register_kevent (struct uloop_fd *fd, unsigned int flags)
 
static int register_poll (struct uloop_fd *fd, unsigned int flags)
 
static int __uloop_fd_delete (struct uloop_fd *fd)
 
static int64_t get_timestamp_us (void)
 
static int uloop_fetch_events (int timeout)
 
static int timer_register (struct uloop_interval *tm, unsigned int msecs)
 
static int timer_remove (struct uloop_interval *tm)
 
static int64_t timer_next (struct uloop_interval *tm)
 

Variables

static struct kevent events [ULOOP_MAX_EVENTS]
 

Function Documentation

◆ __uloop_fd_delete()

static int __uloop_fd_delete ( struct uloop_fd fd)
static

Definition at line 101 of file uloop-kqueue.c.

102 {
103  return register_poll(fd, 0);
104 }
int fd
Definition: udebug-priv.h:27
static int register_poll(struct uloop_fd *fd, unsigned int flags)
Definition: uloop-kqueue.c:91
Here is the call graph for this function:

◆ get_flags()

static uint16_t get_flags ( unsigned int  flags,
unsigned int  mask 
)
static

Definition at line 37 of file uloop-kqueue.c.

38 {
39  uint16_t kflags = 0;
40 
41  if (!(flags & mask))
42  return EV_DELETE;
43 
44  kflags = EV_ADD;
45  if (flags & ULOOP_EDGE_TRIGGER)
46  kflags |= EV_CLEAR;
47 
48  return kflags;
49 }
#define ULOOP_EDGE_TRIGGER
Definition: uloop.h:49
Here is the caller graph for this function:

◆ get_timestamp_us()

static int64_t get_timestamp_us ( void  )
static

Definition at line 106 of file uloop-kqueue.c.

107 {
108 #ifdef CLOCK_MONOTONIC
109  struct timespec ts = { 0, 0 };
110 
111  clock_gettime(CLOCK_MONOTONIC, &ts);
112 
113  return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
114 #else
115  struct timeval tv = { 0, 0 };
116 
117  gettimeofday(&tv, NULL);
118 
119  return tv.tv_sec * 1000000 + tv.tv_usec;
120 #endif
121 }
Here is the caller graph for this function:

◆ register_kevent()

static int register_kevent ( struct uloop_fd fd,
unsigned int  flags 
)
static

Definition at line 53 of file uloop-kqueue.c.

54 {
55  struct timespec timeout = { 0, 0 };
56  struct kevent ev[2];
57  int nev = 0;
58  unsigned int fl = 0;
59  unsigned int changed;
60  uint16_t kflags;
61 
62  if (flags & ULOOP_EDGE_DEFER)
63  flags &= ~ULOOP_EDGE_TRIGGER;
64 
65  changed = flags ^ fd->flags;
66  if (changed & ULOOP_EDGE_TRIGGER)
67  changed |= flags;
68 
69  if (!changed)
70  return 0;
71 
72  if (changed & ULOOP_READ) {
73  kflags = get_flags(flags, ULOOP_READ);
74  EV_SET(&ev[nev++], fd->fd, EVFILT_READ, kflags, 0, 0, fd);
75  }
76 
77  if (changed & ULOOP_WRITE) {
78  kflags = get_flags(flags, ULOOP_WRITE);
79  EV_SET(&ev[nev++], fd->fd, EVFILT_WRITE, kflags, 0, 0, fd);
80  }
81 
82  if (!flags)
83  fl |= EV_DELETE;
84 
85  if (kevent(poll_fd, ev, nev, NULL, fl, &timeout) == -1)
86  return -1;
87 
88  return 0;
89 }
static uint16_t get_flags(unsigned int flags, unsigned int mask)
Definition: uloop-kqueue.c:37
static int poll_fd
Definition: uloop.c:62
#define ULOOP_WRITE
Definition: uloop.h:48
#define ULOOP_READ
Definition: uloop.h:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_poll()

static int register_poll ( struct uloop_fd fd,
unsigned int  flags 
)
static

Definition at line 91 of file uloop-kqueue.c.

92 {
93  if (flags & ULOOP_EDGE_TRIGGER)
94  flags |= ULOOP_EDGE_DEFER;
95  else
96  flags &= ~ULOOP_EDGE_DEFER;
97 
98  return register_kevent(fd, flags);
99 }
static int register_kevent(struct uloop_fd *fd, unsigned int flags)
Definition: uloop-kqueue.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timer_next()

static int64_t timer_next ( struct uloop_interval tm)
static

Definition at line 200 of file uloop-kqueue.c.

201 {
202  int64_t t1 = tm->priv.time.fired;
203  int64_t t2 = get_timestamp_us();
204 
205  while (t1 < t2)
206  t1 += tm->priv.time.msecs * 1000;
207 
208  return (t1 - t2) / 1000;
209 }
union uloop_interval::@15 priv
struct uloop_interval::@15::@16 time
static int64_t get_timestamp_us(void)
Definition: uloop-kqueue.c:106
Here is the call graph for this function:

◆ timer_register()

static int timer_register ( struct uloop_interval tm,
unsigned int  msecs 
)
static

Definition at line 179 of file uloop-kqueue.c.

180 {
181  struct kevent ev;
182 
183  tm->priv.time.msecs = msecs;
184  tm->priv.time.fired = get_timestamp_us();
185 
186  EV_SET(&ev, (uintptr_t)tm, EVFILT_TIMER, EV_ADD, NOTE_USECONDS, msecs * 1000, tm);
187 
188  return kevent(poll_fd, &ev, 1, NULL, 0, NULL);
189 }
Here is the call graph for this function:

◆ timer_remove()

static int timer_remove ( struct uloop_interval tm)
static

Definition at line 191 of file uloop-kqueue.c.

192 {
193  struct kevent ev;
194 
195  EV_SET(&ev, (uintptr_t)tm, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
196 
197  return kevent(poll_fd, &ev, 1, NULL, 0, NULL);
198 }

◆ uloop_fetch_events()

static int uloop_fetch_events ( int  timeout)
static

Definition at line 123 of file uloop-kqueue.c.

124 {
125  struct timespec ts;
126  int nfds, n;
127 
128  if (timeout >= 0) {
129  ts.tv_sec = timeout / 1000;
130  ts.tv_nsec = (timeout % 1000) * 1000000;
131  }
132 
133  nfds = kevent(poll_fd, NULL, 0, events, ARRAY_SIZE(events), timeout >= 0 ? &ts : NULL);
134  for (n = 0; n < nfds; n++) {
135  if (events[n].filter == EVFILT_TIMER) {
136  struct uloop_interval *tm = events[n].udata;
137 
138  tm->priv.time.fired = get_timestamp_us();
139  tm->expirations += events[n].data;
140  tm->cb(tm);
141 
142  continue;
143  }
144 
145  struct uloop_fd_event *cur = &cur_fds[n];
146  struct uloop_fd *u = events[n].udata;
147  unsigned int ev = 0;
148 
149  cur->fd = u;
150  if (!u)
151  continue;
152 
153  if (events[n].flags & EV_ERROR) {
154  u->error = true;
155  if (!(u->flags & ULOOP_ERROR_CB))
156  uloop_fd_delete(u);
157  }
158 
159  if(events[n].filter == EVFILT_READ)
160  ev |= ULOOP_READ;
161  else if (events[n].filter == EVFILT_WRITE)
162  ev |= ULOOP_WRITE;
163 
164  if (events[n].flags & EV_EOF)
165  u->eof = true;
166  else if (!ev)
167  cur->fd = NULL;
168 
169  cur->events = ev;
170  if (u->flags & ULOOP_EDGE_DEFER) {
171  u->flags &= ~ULOOP_EDGE_DEFER;
173  register_kevent(u, u->flags);
174  }
175  }
176  return nfds;
177 }
struct uloop_fd * fd
Definition: uloop.c:44
unsigned int events
Definition: uloop.c:45
Definition: uloop.h:63
bool eof
Definition: uloop.h:66
uint8_t flags
Definition: uloop.h:69
bool error
Definition: uloop.h:67
uint64_t expirations
Definition: uloop.h:93
uloop_interval_handler cb
Definition: uloop.h:92
#define ARRAY_SIZE(x)
static struct kevent events[ULOOP_MAX_EVENTS]
Definition: uloop-kqueue.c:51
int uloop_fd_delete(struct uloop_fd *fd)
Definition: uloop.c:265
static struct uloop_fd_event cur_fds[10]
Definition: uloop.c:68
#define ULOOP_ERROR_CB
Definition: uloop.h:60
Here is the call graph for this function:

◆ uloop_init_pollfd()

static int uloop_init_pollfd ( void  )
static

Definition at line 18 of file uloop-kqueue.c.

19 {
20  struct timespec timeout = { 0, 0 };
21  struct kevent ev = {};
22 
23  if (poll_fd >= 0)
24  return 0;
25 
26  poll_fd = kqueue();
27  if (poll_fd < 0)
28  return -1;
29 
30  EV_SET(&ev, SIGCHLD, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
31  kevent(poll_fd, &ev, 1, NULL, 0, &timeout);
32 
33  return 0;
34 }

Variable Documentation

◆ events

struct kevent events[ULOOP_MAX_EVENTS]
static

Definition at line 37 of file uloop-kqueue.c.