61 #include "gw-config.h" 159 new = gw_malloc(
sizeof(*
new));
164 new->callback = NULL;
255 panic(0,
"fdset: handle_action got unknown action type %d.",
276 for (i = 0; i <
set->entries; i++) {
277 if (set->pollinfo[i].fd ==
fd)
286 if (entry != set->entries - 1) {
289 set->pollinfo[entry] =
set->pollinfo[
set->entries - 1];
290 set->callbacks[entry] =
set->callbacks[
set->entries - 1];
291 set->datafields[entry] =
set->datafields[
set->entries - 1];
292 set->times[entry] =
set->times[
set->entries - 1];
302 while (i < set->entries && set->deleted_entries > 0) {
303 if (set->pollinfo[i].fd < 0) {
305 set->deleted_entries--;
336 ret =
gwthread_poll(set->pollinfo, set->entries, set->timeout);
339 if (errno != EINTR) {
340 error(errno,
"Poller: can't handle error; sleeping 1 second.");
348 for (i = 0; i <
set->entries; i++) {
349 if (set->pollinfo[i].revents != 0) {
350 set->callbacks[i](
set->pollinfo[i].fd,
351 set->pollinfo[i].revents,
354 time(&set->times[i]);
355 }
else if (set->timeout > 0 && difftime(set->times[i] + set->timeout, now) <= 0) {
356 debug(
"gwlib.fdset", 0,
"Timeout for fd:%d appears.", set->pollinfo[i].fd);
357 set->callbacks[i](
set->pollinfo[i].fd,
POLLERR,
set->datafields[i]);
362 if (set->deleted_entries > 0)
372 new = gw_malloc(
sizeof(*
new));
378 new->pollinfo = gw_malloc(
sizeof(new->pollinfo[0]) * new->size);
379 new->callbacks = gw_malloc(
sizeof(new->callbacks[0]) * new->size);
380 new->datafields = gw_malloc(
sizeof(new->datafields[0]) * new->size);
381 new->times = gw_malloc(
sizeof(new->times[0]) * new->size);
384 new->deleted_entries = 0;
389 if (new->poll_thread < 0) {
390 error(0,
"Could not start internal thread for fdset.");
403 if (set->poll_thread < 0 ||
gwthread_self() == set->poll_thread) {
404 if (set->entries > 0) {
405 warning(0,
"Destroying fdset with %d active entries.",
408 gw_free(set->pollinfo);
409 gw_free(set->callbacks);
410 gw_free(set->datafields);
413 error(0,
"Destroying fdset with %ld pending actions.",
419 long thread =
set->poll_thread;
446 if (set->entries >= set->size) {
447 int newsize =
set->entries + 1;
448 set->pollinfo = gw_realloc(set->pollinfo,
449 sizeof(set->pollinfo[0]) * newsize);
450 set->callbacks = gw_realloc(set->callbacks,
451 sizeof(set->callbacks[0]) * newsize);
452 set->datafields = gw_realloc(set->datafields,
453 sizeof(set->datafields[0]) * newsize);
454 set->times = gw_realloc(set->times,
sizeof(set->times[0]) * newsize);
461 new =
set->entries++;
462 set->pollinfo[
new].fd =
fd;
463 set->pollinfo[
new].events =
events;
464 set->pollinfo[
new].revents = 0;
466 set->datafields[
new] =
data;
467 time(&set->times[
new]);
489 warning(0,
"fdset_listen called on unregistered fd %d.",
fd);
495 set->pollinfo[entry].events =
503 set->pollinfo[entry].revents =
504 set->pollinfo[entry].revents & (
events | ~
mask);
507 time(&set->times[entry]);
529 warning(0,
"fdset_listen called on unregistered fd %d.",
fd);
533 if (entry == set->entries - 1) {
537 }
else if (set->scanning) {
540 set->pollinfo[entry].fd = -1;
541 set->deleted_entries++;
void error(int err, const char *fmt,...)
static struct action * action_create(int type)
void fdset_listen(FDSet *set, int fd, int mask, int events)
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
static int find_entry(FDSet *set, int fd)
void gwlist_produce(List *list, void *item)
void gwthread_join(long thread)
long gwlist_len(List *list)
static void remove_deleted_entries(FDSet *set)
void fdset_unregister(FDSet *set, int fd)
int gwthread_poll(struct pollfd *fds, long numfds, double timeout)
void fdset_register(FDSet *set, int fd, int events, fdset_callback_t callback, void *data)
fdset_callback_t ** callbacks
void * gwlist_extract_first(List *list)
static void submit_action(FDSet *set, struct action *action)
void fdset_callback_t(int fd, int revents, void *data)
static int action(int hex)
void warning(int err, const char *fmt,...)
static void action_destroy_item(void *action)
#define gwthread_create(func, arg)
void gwthread_sleep(double seconds)
void fdset_destroy(FDSet *set)
static void remove_entry(FDSet *set, int entry)
fdset_callback_t * callback
void * gwlist_consume(List *list)
void debug(const char *place, int err, const char *fmt,...)
void gwthread_wakeup(long thread)
static void poller(void *arg)
static void submit_action_nosync(FDSet *set, struct action *action)
void fdset_set_timeout(FDSet *set, long timeout)
void gwlist_add_producer(List *list)
FDSet * fdset_create_real(long timeout)
static int handle_action(FDSet *set, struct action *action)
static void action_destroy(struct action *action)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)