Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

fdset.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Defines

#define fdset_create()   fdset_create_real(-1)

Typedefs

typedef 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)


Define Documentation

 
#define fdset_create  )     fdset_create_real(-1)
 

Definition at line 80 of file fdset.h.


Typedef Documentation

typedef struct FDSet FDSet
 

Definition at line 61 of file fdset.h.

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

Definition at line 73 of file fdset.h.


Function Documentation

FDSet* fdset_create_real long  timeout  ) 
 

Definition at line 368 of file fdset.c.

References FDSet::entries, error(), fdset_destroy(), gwlist_create, gwthread_create, poller(), FDSet::pollinfo, and FDSet::size.

Referenced by start_client_threads(), and start_server_thread().

00369 {
00370     FDSet *new;
00371 
00372     new = gw_malloc(sizeof(*new));
00373 
00374     /* Start off with space for one element because we can't malloc 0 bytes
00375      * and we don't want to worry about these pointers being NULL. */
00376     new->size = 1;
00377     new->entries = 0;
00378     new->pollinfo = gw_malloc(sizeof(new->pollinfo[0]) * new->size);
00379     new->callbacks = gw_malloc(sizeof(new->callbacks[0]) * new->size);
00380     new->datafields = gw_malloc(sizeof(new->datafields[0]) * new->size);
00381     new->times = gw_malloc(sizeof(new->times[0]) * new->size);
00382     new->timeout = timeout > 0 ? timeout : -1;
00383     new->scanning = 0;
00384     new->deleted_entries = 0;
00385 
00386     new->actions = gwlist_create();
00387 
00388     new->poll_thread = gwthread_create(poller, new);
00389     if (new->poll_thread < 0) {
00390         error(0, "Could not start internal thread for fdset.");
00391         fdset_destroy(new);
00392         return NULL;
00393     }
00394 
00395     return new;
00396 }

Here is the call graph for this function:

void fdset_destroy FDSet set  ) 
 

Definition at line 398 of file fdset.c.

References action_create(), action_destroy_item(), FDSet::actions, FDSet::callbacks, FDSet::datafields, FDSet::entries, error(), gwlist_destroy(), gwlist_len(), gwthread_join(), gwthread_self(), FDSet::poll_thread, FDSet::pollinfo, submit_action(), FDSet::times, and warning().

Referenced by client_shutdown(), fdset_create_real(), handle_action(), http_close_all_ports(), server_shutdown(), and start_client_threads().

00399 {
00400     if (set == NULL)
00401         return;
00402 
00403     if (set->poll_thread < 0 || gwthread_self() == set->poll_thread) {
00404         if (set->entries > 0) {
00405             warning(0, "Destroying fdset with %d active entries.",
00406                     set->entries);
00407         }
00408         gw_free(set->pollinfo);
00409         gw_free(set->callbacks);
00410         gw_free(set->datafields);
00411         gw_free(set->times);
00412         if (gwlist_len(set->actions) > 0) {
00413             error(0, "Destroying fdset with %ld pending actions.",
00414                   gwlist_len(set->actions));
00415         }
00416         gwlist_destroy(set->actions, action_destroy_item);
00417         gw_free(set);
00418     } else {
00419         long thread = set->poll_thread;
00420         submit_action(set, action_create(DESTROY));
00421     gwthread_join(thread);
00422     }
00423 }

Here is the call graph for this function:

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

Definition at line 470 of file fdset.c.

References action, action_create(), pollfd::events, action::events, action::fd, find_entry(), gw_assert, gwthread_self(), LISTEN, action::mask, FDSet::poll_thread, FDSet::pollinfo, pollfd::revents, FDSet::scanning, submit_action(), FDSet::times, and warning().

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

00471 {
00472     int entry;
00473 
00474     gw_assert(set != NULL);
00475 
00476     if (gwthread_self() != set->poll_thread) {
00477         struct action *action;
00478 
00479         action = action_create(LISTEN);
00480         action->fd = fd;
00481     action->mask = mask;
00482         action->events = events;
00483         submit_action(set, action);
00484         return;
00485     }
00486 
00487     entry = find_entry(set, fd);   
00488     if (entry < 0) {
00489         warning(0, "fdset_listen called on unregistered fd %d.", fd);
00490         return;
00491     }
00492 
00493     /* Copy the bits from events specified by the mask, and preserve the
00494      * bits not specified by the mask. */
00495     set->pollinfo[entry].events =
00496     (set->pollinfo[entry].events & ~mask) | (events & mask);
00497 
00498     /* If poller is currently scanning the array, then change the
00499      * revents field so that the callback function will not be called
00500      * for events we should no longer listen for.  The idea is the
00501      * same as for the events field, except that we only turn bits off. */
00502     if (set->scanning) {
00503         set->pollinfo[entry].revents =
00504             set->pollinfo[entry].revents & (events | ~mask);
00505     }
00506     
00507     time(&set->times[entry]);
00508 }

Here is the call graph for this function:

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, FDSet::callbacks, action::data, FDSet::datafields, FDSet::entries, pollfd::events, action::events, pollfd::fd, action::fd, gw_assert, gwthread_self(), FDSet::poll_thread, FDSet::pollinfo, pollfd::revents, FDSet::size, submit_action_nosync(), and FDSet::times.

Referenced by conn_register_real(), and handle_action().

00427 {
00428     int new;
00429 
00430     gw_assert(set != NULL);
00431 
00432     if (gwthread_self() != set->poll_thread) {
00433         struct action *action;
00434 
00435         action = action_create(REGISTER);
00436         action->fd = fd;
00437         action->events = events;
00438         action->callback = callback;
00439         action->data = data;
00440     submit_action_nosync(set, action);
00441         return;
00442     }
00443 
00444     gw_assert(set->entries <= set->size);
00445 
00446     if (set->entries >= set->size) {
00447         int newsize = set->entries + 1;
00448         set->pollinfo = gw_realloc(set->pollinfo,
00449                                    sizeof(set->pollinfo[0]) * newsize);
00450         set->callbacks = gw_realloc(set->callbacks,
00451                                    sizeof(set->callbacks[0]) * newsize);
00452         set->datafields = gw_realloc(set->datafields,
00453                                    sizeof(set->datafields[0]) * newsize);
00454         set->times = gw_realloc(set->times, sizeof(set->times[0]) * newsize);
00455         set->size = newsize;
00456     }
00457 
00458     /* We don't check set->scanning.  Adding new entries is not harmful
00459      * because their revents fields are 0. */
00460 
00461     new = set->entries++;
00462     set->pollinfo[new].fd = fd;
00463     set->pollinfo[new].events = events;
00464     set->pollinfo[new].revents = 0;
00465     set->callbacks[new] = callback;
00466     set->datafields[new] = data;
00467     time(&set->times[new]);
00468 }

Here is the call graph for this function:

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(), FDSet::poll_thread, submit_action(), FDSet::timeout, and action::timeout.

Referenced by http_set_client_timeout().

00548 {
00549     gw_assert(set != NULL);
00550 
00551     if (gwthread_self() != set->poll_thread) {
00552         struct action *action;
00553 
00554         action = action_create(SET_TIMEOUT);
00555         action->timeout = timeout;
00556         submit_action(set, action);
00557         return;
00558     }
00559     set->timeout = timeout;
00560 }

Here is the call graph for this function:

void fdset_unregister FDSet set,
int  fd
 

Definition at line 510 of file fdset.c.

References action, action_create(), FDSet::deleted_entries, FDSet::entries, pollfd::fd, action::fd, find_entry(), gw_assert, gwthread_self(), FDSet::poll_thread, FDSet::pollinfo, remove_entry(), FDSet::scanning, submit_action(), and warning().

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

00511 {
00512     int entry;
00513 
00514     gw_assert(set != NULL);
00515 
00516     if (gwthread_self() != set->poll_thread) {
00517         struct action *action;
00518 
00519         action = action_create(UNREGISTER);
00520         action->fd = fd;
00521         submit_action(set, action);
00522         return;
00523     }
00524 
00525     /* Remove the entry from the pollinfo array */
00526 
00527     entry = find_entry(set, fd);
00528     if (entry < 0) {
00529         warning(0, "fdset_listen called on unregistered fd %d.", fd);
00530         return;
00531     }
00532 
00533     if (entry == set->entries - 1) {
00534         /* It's the last entry.  We can safely remove it even while
00535          * the array is being scanned, because the scan checks set->entries. */
00536         set->entries--;
00537     } else if (set->scanning) {
00538         /* We can't remove entries because the array is being
00539          * scanned.  Mark it as deleted.  */
00540         set->pollinfo[entry].fd = -1;
00541         set->deleted_entries++;
00542     } else {
00543         remove_entry(set, entry);
00544     }
00545 }

Here is the call graph for this function:

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.