Kannel: Open Source WAP and SMS gateway  svn-r5335
fdset.h File Reference

Go to the source code of this file.

Macros

#define fdset_create()   fdset_create_real(-1)
 

Typedefs

typedef struct FDSet FDSet
 
typedef void fdset_callback_t(int fd, int revents, void *data)
 

Functions

FDSetfdset_create_real (long timeout)
 
void fdset_destroy (FDSet *set)
 
void fdset_register (FDSet *set, int fd, int events, fdset_callback_t callback, void *data)
 
void fdset_listen (FDSet *set, int fd, int mask, int events)
 
void fdset_unregister (FDSet *set, int fd)
 
void fdset_set_timeout (FDSet *set, long timeout)
 

Macro Definition Documentation

◆ fdset_create

#define fdset_create ( )    fdset_create_real(-1)

Definition at line 80 of file fdset.h.

Typedef Documentation

◆ FDSet

typedef struct FDSet FDSet

Definition at line 61 of file fdset.h.

◆ fdset_callback_t

typedef void fdset_callback_t(int fd, int revents, void *data)

Definition at line 73 of file fdset.h.

Function Documentation

◆ fdset_create_real()

FDSet* fdset_create_real ( long  timeout)

Definition at line 368 of file fdset.c.

References error(), fdset_destroy(), gwlist_create, gwthread_create, poller(), and action::timeout.

Referenced by port_add(), and start_client_threads().

369 {
370  FDSet *new;
371 
372  new = gw_malloc(sizeof(*new));
373 
374  /* Start off with space for one element because we can't malloc 0 bytes
375  * and we don't want to worry about these pointers being NULL. */
376  new->size = 1;
377  new->entries = 0;
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);
382  new->timeout = timeout > 0 ? timeout : -1;
383  new->scanning = 0;
384  new->deleted_entries = 0;
385 
386  new->actions = gwlist_create();
387 
388  new->poll_thread = gwthread_create(poller, new);
389  if (new->poll_thread < 0) {
390  error(0, "Could not start internal thread for fdset.");
391  fdset_destroy(new);
392  return NULL;
393  }
394 
395  return new;
396 }
void error(int err, const char *fmt,...)
Definition: log.c:648
long timeout
Definition: fdset.c:148
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void fdset_destroy(FDSet *set)
Definition: fdset.c:398
#define gwlist_create()
Definition: list.h:136
Definition: fdset.c:70
static void poller(void *arg)
Definition: fdset.c:318

◆ fdset_destroy()

void fdset_destroy ( FDSet set)

Definition at line 398 of file fdset.c.

References action_create(), action_destroy_item(), action::DESTROY, error(), gwlist_destroy(), gwlist_len(), gwthread_join(), gwthread_self(), submit_action(), and warning().

Referenced by client_shutdown(), fdset_create_real(), handle_action(), port_remove(), and start_client_threads().

399 {
400  if (set == NULL)
401  return;
402 
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.",
406  set->entries);
407  }
408  gw_free(set->pollinfo);
409  gw_free(set->callbacks);
410  gw_free(set->datafields);
411  gw_free(set->times);
412  if (gwlist_len(set->actions) > 0) {
413  error(0, "Destroying fdset with %ld pending actions.",
414  gwlist_len(set->actions));
415  }
417  gw_free(set);
418  } else {
419  long thread = set->poll_thread;
421  gwthread_join(thread);
422  }
423 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static struct action * action_create(int type)
Definition: fdset.c:155
long gwthread_self(void)
void gwthread_join(long thread)
long gwlist_len(List *list)
Definition: list.c:166
time_t * times
Definition: fdset.c:88
fdset_callback_t ** callbacks
Definition: fdset.c:96
List * actions
Definition: fdset.c:126
struct pollfd * pollinfo
Definition: fdset.c:83
void ** datafields
Definition: fdset.c:97
static void submit_action(FDSet *set, struct action *action)
Definition: fdset.c:191
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void action_destroy_item(void *action)
Definition: fdset.c:181
int entries
Definition: fdset.c:85
long poll_thread
Definition: fdset.c:76
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ fdset_listen()

void fdset_listen ( FDSet set,
int  fd,
int  mask,
int  events 
)

Definition at line 470 of file fdset.c.

References action(), action_create(), action::events, action::fd, find_entry(), gw_assert(), gwthread_self(), action::LISTEN, action::mask, submit_action(), and warning().

Referenced by handle_action(), unlocked_register_pollin(), and unlocked_register_pollout().

471 {
472  int entry;
473 
474  gw_assert(set != NULL);
475 
476  if (gwthread_self() != set->poll_thread) {
477  struct action *action;
478 
480  action->fd = fd;
481  action->mask = mask;
482  action->events = events;
483  submit_action(set, action);
484  return;
485  }
486 
487  entry = find_entry(set, fd);
488  if (entry < 0) {
489  warning(0, "fdset_listen called on unregistered fd %d.", fd);
490  return;
491  }
492 
493  /* Copy the bits from events specified by the mask, and preserve the
494  * bits not specified by the mask. */
495  set->pollinfo[entry].events =
496  (set->pollinfo[entry].events & ~mask) | (events & mask);
497 
498  /* If poller is currently scanning the array, then change the
499  * revents field so that the callback function will not be called
500  * for events we should no longer listen for. The idea is the
501  * same as for the events field, except that we only turn bits off. */
502  if (set->scanning) {
503  set->pollinfo[entry].revents =
504  set->pollinfo[entry].revents & (events | ~mask);
505  }
506 
507  time(&set->times[entry]);
508 }
static struct action * action_create(int type)
Definition: fdset.c:155
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
int events
Definition: fdset.c:145
static int find_entry(FDSet *set, int fd)
Definition: fdset.c:269
Definition: fdset.c:140
int scanning
Definition: fdset.c:112
time_t * times
Definition: fdset.c:88
int fd
Definition: fdset.c:143
static void submit_action(FDSet *set, struct action *action)
Definition: fdset.c:191
static int action(int hex)
void warning(int err, const char *fmt,...)
Definition: log.c:660
int mask
Definition: fdset.c:144
long poll_thread
Definition: fdset.c:76

◆ fdset_register()

void fdset_register ( FDSet set,
int  fd,
int  events,
fdset_callback_t  callback,
void *  data 
)

Definition at line 425 of file fdset.c.

References action(), action_create(), action::callback, action::data, action::events, action::fd, gw_assert(), gwthread_self(), action::REGISTER, and submit_action_nosync().

Referenced by conn_register_real(), and handle_action().

427 {
428  int new;
429 
430  gw_assert(set != NULL);
431 
432  if (gwthread_self() != set->poll_thread) {
433  struct action *action;
434 
436  action->fd = fd;
437  action->events = events;
439  action->data = data;
441  return;
442  }
443 
444  gw_assert(set->entries <= set->size);
445 
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);
455  set->size = newsize;
456  }
457 
458  /* We don't check set->scanning. Adding new entries is not harmful
459  * because their revents fields are 0. */
460 
461  new = set->entries++;
462  set->pollinfo[new].fd = fd;
463  set->pollinfo[new].events = events;
464  set->pollinfo[new].revents = 0;
465  set->callbacks[new] = callback;
466  set->datafields[new] = data;
467  time(&set->times[new]);
468 }
static struct action * action_create(int type)
Definition: fdset.c:155
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
int events
Definition: fdset.c:145
Definition: fdset.c:140
int size
Definition: fdset.c:84
time_t * times
Definition: fdset.c:88
int fd
Definition: fdset.c:143
fdset_callback_t ** callbacks
Definition: fdset.c:96
struct pollfd * pollinfo
Definition: fdset.c:83
void ** datafields
Definition: fdset.c:97
static int action(int hex)
fdset_callback_t * callback
Definition: fdset.c:146
int entries
Definition: fdset.c:85
static void submit_action_nosync(FDSet *set, struct action *action)
Definition: fdset.c:216
void * data
Definition: fdset.c:147
long poll_thread
Definition: fdset.c:76

◆ fdset_set_timeout()

void fdset_set_timeout ( FDSet set,
long  timeout 
)

Set timeout in seconds for this FDSet.

Definition at line 547 of file fdset.c.

References action(), action_create(), gw_assert(), gwthread_self(), action::SET_TIMEOUT, submit_action(), and action::timeout.

Referenced by http_set_client_timeout(), and port_set_timeout().

548 {
549  gw_assert(set != NULL);
550 
551  if (gwthread_self() != set->poll_thread) {
552  struct action *action;
553 
556  submit_action(set, action);
557  return;
558  }
559  set->timeout = timeout;
560 }
static struct action * action_create(int type)
Definition: fdset.c:155
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
Definition: fdset.c:140
long timeout
Definition: fdset.c:148
static void submit_action(FDSet *set, struct action *action)
Definition: fdset.c:191
static int action(int hex)
long poll_thread
Definition: fdset.c:76

◆ fdset_unregister()

void fdset_unregister ( FDSet set,
int  fd 
)

Definition at line 510 of file fdset.c.

References action(), action_create(), action::fd, find_entry(), gw_assert(), gwthread_self(), remove_entry(), submit_action(), action::UNREGISTER, and warning().

Referenced by conn_destroy(), conn_unregister(), and handle_action().

511 {
512  int entry;
513 
514  gw_assert(set != NULL);
515 
516  if (gwthread_self() != set->poll_thread) {
517  struct action *action;
518 
520  action->fd = fd;
521  submit_action(set, action);
522  return;
523  }
524 
525  /* Remove the entry from the pollinfo array */
526 
527  entry = find_entry(set, fd);
528  if (entry < 0) {
529  warning(0, "fdset_listen called on unregistered fd %d.", fd);
530  return;
531  }
532 
533  if (entry == set->entries - 1) {
534  /* It's the last entry. We can safely remove it even while
535  * the array is being scanned, because the scan checks set->entries. */
536  set->entries--;
537  } else if (set->scanning) {
538  /* We can't remove entries because the array is being
539  * scanned. Mark it as deleted. */
540  set->pollinfo[entry].fd = -1;
541  set->deleted_entries++;
542  } else {
543  remove_entry(set, entry);
544  }
545 }
static struct action * action_create(int type)
Definition: fdset.c:155
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
static int find_entry(FDSet *set, int fd)
Definition: fdset.c:269
Definition: fdset.c:140
int scanning
Definition: fdset.c:112
int fd
Definition: fdset.c:143
static void submit_action(FDSet *set, struct action *action)
Definition: fdset.c:191
static int action(int hex)
void warning(int err, const char *fmt,...)
Definition: log.c:660
static void remove_entry(FDSet *set, int entry)
Definition: fdset.c:284
int entries
Definition: fdset.c:85
long poll_thread
Definition: fdset.c:76
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.