a simple object-oriented event loop
More...
#include <stdlib.h>
#include "process.h"
#include "socket.h"
Go to the source code of this file.
|
#define | LOOP_MAXPROC 20 |
|
#define | LOOP_MAXSOCK 20 |
|
#define | LOOP_MAXEVENT 64 |
|
#define | LOOP_TIMEOUT 5 |
|
#define | LOOP_MAXTIMER 20 |
|
|
struct co_timer_t | __attribute__ ((packed)) |
|
int | co_loop_create (void) |
| sets up the event loop
|
|
int | co_loop_destroy (void) |
| closes the event loop
|
|
void | co_loop_start (void) |
| starts the event loop, listening for messages on sockets via _co_loop_poll_sockets
|
|
void | co_loop_stop (void) |
| stops the event loop
|
|
int | co_loop_add_process (co_obj_t *proc) |
| adds a process to the event loop (for it to listen for) More...
|
|
int | co_loop_remove_process (pid_t pid) |
| removes a process from the event loop More...
|
|
int | co_loop_add_socket (co_obj_t *new_sock, co_obj_t *context) |
| adds a new socket to the event loop (for it to listen on) More...
|
|
int | co_loop_remove_socket (co_obj_t *old_sock, co_obj_t *context) |
| removes a socket from the event loop More...
|
|
co_obj_t * | co_loop_get_socket (char *uri, co_obj_t *context) |
| gets a socket that is registered with the event loop More...
|
|
int | co_loop_add_timer (co_obj_t *new_timer, co_obj_t *context) |
| schedules a new timer with the event loop More...
|
|
int | co_loop_remove_timer (co_obj_t *old_timer, co_obj_t *context) |
| removes a timer from the event loop More...
|
|
int | co_loop_set_timer (co_obj_t *timer, long msecs, co_obj_t *context) |
| sets timer to expire in msecs from now More...
|
|
co_obj_t * | co_loop_get_timer (void *ptr, co_obj_t *context) |
| gets a socket that is registered with the event loop More...
|
|
co_obj_t * | co_timer_create (struct timeval deadline, co_cb_t timer_cb, void *ptr) |
| malloc and initialize a timer More...
|
|
|
co_obj_t | _header |
|
uint8_t | _exttype |
|
uint8_t | _len |
|
bool | pending |
|
struct timeval | deadline |
|
co_cb_t | timer_cb |
|
void * | ptr |
|
a simple object-oriented event loop
- Author
- Josh King (jheretic), jking.nosp@m.@cha.nosp@m.mbana.nosp@m..net
int co_loop_add_process |
( |
co_obj_t * |
proc | ) |
|
adds a process to the event loop (for it to listen for)
- Parameters
-
proc | the process to be added |
References co_list_append().
311 CHECK(IS_PROCESS(proc),
"Not a process.");
int co_list_append(co_obj_t *list, co_obj_t *new_obj)
insert new item at end of list
Definition: list.c:425
adds a new socket to the event loop (for it to listen on)
- Parameters
-
new_sock | the new socket to be added |
context | a co_obj_t context pointer (currently unused) |
References co_list_append(), co_list_contains(), co_list_parse(), and co_loop_remove_socket().
Referenced by _watch(), and main().
331 DEBUG(
"Adding socket to event loop.");
332 CHECK(IS_SOCK(new_sock),
"Not a socket.");
335 CHECK(fd->socket == sock,
"FD does not match socket");
337 struct epoll_event event;
339 memset(&event, 0,
sizeof(
struct epoll_event));
340 event.events = EPOLLIN;
342 if((node =
co_list_parse(sockets, _co_loop_match_socket_i, sock->uri))) {
343 CHECK((node == (
co_obj_t*)sock),
"Different socket with URI %s already registered.", sock->uri);
344 if ((sock->listen) && (sock->fd->fd > 0) && sock->fd_registered) {
346 DEBUG(
"Adding RFD %d to epoll.", fd->fd);
348 CHECK((epoll_ctl(poll_fd, EPOLL_CTL_ADD, fd->fd, &event)) != -1,
"Failed to add receive FD epoll event.");
350 SENTINEL(
"Socket %s already registered.", sock->uri);
352 }
else if((sock->listen) && (sock->fd->fd > 0) && !sock->fd_registered) {
353 CHECK(fd = sock->fd,
"Invalid listening socket");
354 DEBUG(
"Adding FD %d to epoll.", sock->fd->fd);
356 CHECK((epoll_ctl(poll_fd, EPOLL_CTL_ADD, sock->fd->fd, &event)) != -1,
"Failed to add listen FD epoll event.");
357 sock->fd_registered =
true;
362 SENTINEL(
"Unknown error registering socket %s.", sock->uri);
int co_list_append(co_obj_t *list, co_obj_t *new_obj)
insert new item at end of list
Definition: list.c:425
int co_list_contains(co_obj_t *list, co_obj_t *item)
determine if list contains specified item
Definition: list.c:258
int co_loop_remove_socket(co_obj_t *old_sock, co_obj_t *context)
removes a socket from the event loop
Definition: loop.c:375
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
schedules a new timer with the event loop
- Parameters
-
timer | the timer to schedule |
context | a co_obj_t context pointer (currently unused) |
References co_list_append(), co_list_insert_before(), and co_list_parse().
Referenced by _schedule(), and co_loop_set_timer().
405 _co_loop_gettime(&now);
406 CHECK(timer->timer_cb,
"No callback function associated with timer");
407 CHECK(_co_loop_tv_diff(&timer->deadline,&now) > -1000,
"Invalid timer deadline: %ld.%06ld %ld.%06ld",
408 timer->deadline.tv_sec,timer->deadline.tv_usec,
409 now.tv_sec,now.tv_usec);
411 CHECK(
co_list_parse(timers,_co_loop_match_timer_i,timer->ptr) == NULL,
"Timer already scheduled");
414 if((node =
co_list_parse(timers, _co_loop_compare_timer_i, &timer->deadline))) {
422 timer->pending =
true;
int co_list_append(co_obj_t *list, co_obj_t *new_obj)
insert new item at end of list
Definition: list.c:425
int co_list_insert_before(co_obj_t *list, co_obj_t *new_obj, co_obj_t *this_obj)
insert new item in list before specified item
Definition: list.c:273
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
gets a socket that is registered with the event loop
- Parameters
-
uri | a URI to match against the available sockets |
context | a co_obj_t context pointer (currently unused) |
References co_list_parse().
391 CHECK((sock =
co_list_parse(sockets, _co_loop_match_socket_i, uri)),
"Failed to find socket %s", uri);
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
gets a socket that is registered with the event loop
- Parameters
-
ptr | void pointer to match against the available timers |
context | a co_obj_t context pointer (currently unused) |
References co_list_parse().
Referenced by _unschedule().
450 CHECK((timer =
co_list_parse(timers, _co_loop_match_timer_i, ptr)),
"Failed to find timer: %p",ptr);
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
int co_loop_remove_process |
( |
pid_t |
pid | ) |
|
removes a process from the event loop
- Parameters
-
pid | the id of the process to be removed |
References co_list_delete(), and co_list_parse().
321 CHECK((proc =
co_list_parse(processes, _co_loop_match_process_i, &pid)),
"Failed to delete process %d!", pid);
co_obj_t * co_list_delete(co_obj_t *list, co_obj_t *item)
delete specified item from list
Definition: list.c:457
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
removes a socket from the event loop
- Parameters
-
old_sock | the socket to be removed |
context | a co_obj_t context pointer (currently unused) |
References co_list_delete(), and co_list_parse().
Referenced by co_loop_add_socket().
378 CHECK((node =
co_list_parse(sockets, _co_loop_match_socket_i, sock->uri)),
"Failed to delete socket %s!", sock->uri);
380 sock->fd_registered =
false;
381 epoll_ctl(poll_fd, EPOLL_CTL_DEL, sock->fd->fd, NULL);
382 CHECK(
co_list_parse(sock->rfd_lst,_co_loop_remove_fd_i,NULL) == NULL,
"Failed to delete rfd_lst");
co_obj_t * co_list_delete(co_obj_t *list, co_obj_t *item)
delete specified item from list
Definition: list.c:457
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
removes a timer from the event loop
- Parameters
-
old_timer | the timer to remove from list |
context | a co_obj_t context pointer (currently unused) |
References co_list_delete(), and co_list_parse().
Referenced by _unschedule(), and co_loop_set_timer().
437 CHECK((node =
co_list_parse(timers, _co_loop_match_timer_i, timer->ptr)),
438 "Failed to delete timer %ld.%06ld %p",timer->deadline.tv_sec,timer->deadline.tv_usec,timer->ptr);
441 timer->pending =
false;
co_obj_t * co_list_delete(co_obj_t *list, co_obj_t *item)
delete specified item from list
Definition: list.c:457
co_obj_t * co_list_parse(co_obj_t *list, co_iter_t iter, void *context)
process list with given iterator function
Definition: list.c:233
sets timer to expire in msecs from now
- Parameters
-
timer | the timer to set |
msecs | number of milliseconds |
context | a co_obj_t context pointer (currently unused) |
References co_loop_add_timer(), and co_loop_remove_timer().
458 struct timeval *deadline = &timer->deadline;
463 _co_loop_gettime(&timer->deadline);
465 deadline->tv_sec += msecs / 1000;
466 deadline->tv_usec += (msecs % 1000) * 1000;
468 if (deadline->tv_usec > 1000000) {
470 deadline->tv_usec %= 1000000;
int co_loop_remove_timer(co_obj_t *old_timer, co_obj_t *context)
removes a timer from the event loop
Definition: loop.c:429
int co_loop_add_timer(co_obj_t *new_timer, co_obj_t *context)
schedules a new timer with the event loop
Definition: loop.c:397
co_obj_t* co_timer_create |
( |
struct timeval |
deadline, |
|
|
co_cb_t |
timer_cb, |
|
|
void * |
ptr |
|
) |
| |
malloc and initialize a timer
- Parameters
-
size | timer struct size |
proto | timer protocol |
Referenced by _schedule().
479 new_timer->_header._type = _ext8;
480 new_timer->_header._ref = 0;
481 new_timer->_header._flags = 0;
482 new_timer->_exttype = _co_timer;
484 new_timer->pending =
false;
485 if (deadline.tv_sec > 0 || deadline.tv_usec > 0) {
486 new_timer->deadline.tv_sec = deadline.tv_sec;
487 new_timer->deadline.tv_usec = deadline.tv_usec;
489 new_timer->deadline = (
struct timeval){0};
490 new_timer->timer_cb = timer_cb ? timer_cb : NULL;
491 new_timer->ptr = ptr ? ptr : (
void*)new_timer;