source: muxevents.c @ 601733d

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 601733d was 948b942, checked in by James M. Kretchmar <kretch@mit.edu>, 17 years ago
Print C-\ correctly (from gildea) Dropped first brace in muxevents functions for consistency
  • Property mode set to 100644
File size: 3.4 KB
RevLine 
[afbf668]1#include <sys/poll.h>
2#include <sys/time.h>
3#include <sys/types.h>
4#include <unistd.h>
5#include "owl.h"
6
7static const char fileIdent[] = "$Id $";
8
9#define OWL_MUX_MAX_FD (FD_SETSIZE-1)
10
11static int owl_mux_nexthandle = 5000; /* next handle to hand out */
12static int owl_mux_needgc = 0;  /* number of muxevents needing to be gc'd */
13
14/* returns a handle id or 0 on failure */
[948b942]15int owl_muxevents_add(owl_muxevents *muxevents, int fd, int eventmask, void (*handler_fn)(int handle, int fd, int eventmask, void *data), void *data)
16{
[afbf668]17  owl_mux *mux;
18 
19  mux = owl_malloc(sizeof(owl_mux));
20  if (!mux) return 0;
21  if (fd > OWL_MUX_MAX_FD) {
22    owl_function_error("owl_muxevents_add: fd %d too large", fd);
23    return 0;
24  }
25  mux->handle = owl_mux_nexthandle++;
26  mux->fd = fd;
27  mux->active = 1;
28  mux->eventmask = eventmask;
29  mux->data = data;
30  mux->handler_fn = handler_fn;
31  if (0!=owl_list_append_element(muxevents, mux)) {
32    owl_free(mux);
33    return(0);
34  }
35  return mux->handle;
36}
37
38/* deactivates a muxevent entry with the given handle */
[948b942]39void owl_muxevents_remove(owl_muxevents *muxevents, int handle)
40{
[afbf668]41  int max, i;
42  owl_mux *m;
43
44  max = owl_list_get_size(muxevents);
45  for (i=0; i<max; i++) {
46    m = (owl_mux*)owl_list_get_element(muxevents, i);
47    if (m->handle == handle) {
48      m->active=0;
49      owl_mux_needgc++;
50    }
51  }
52}
53
54/* cleans up a muxevents list at a safe time (ie, when it is
55   not being traversed). */
[948b942]56void owl_muxevents_gc(owl_muxevents *muxevents)
57{
[afbf668]58  int max, i, done=0;
59  owl_mux *m;
60
61  if (!owl_mux_needgc) return;
62  while (!done) {
63    max = owl_list_get_size(muxevents);
64    for (i=0; i<max; i++) {
65      m = (owl_mux*)owl_list_get_element(muxevents, i);
66      if (!m->active) {
67        owl_list_remove_element(muxevents, i);
68        owl_free(m);
69        owl_mux_needgc--;
70        break;
71      }
72    } 
73    if (i==max) done=1;
74  }
75}
76
77/* dispatches out events */
[948b942]78void owl_muxevents_dispatch(owl_muxevents *muxevents, int timeout_usec)
79{
[afbf668]80  int nevents, i, rv, emask;
81  owl_mux *m;
82  fd_set rfds, wfds, efds;
83  int maxfd=0;
84  struct timeval tv;
85
86  FD_ZERO(&rfds);
87  FD_ZERO(&wfds);
88  FD_ZERO(&efds);
89  nevents = owl_list_get_size(muxevents);
90  for (i=0; i<nevents; i++) {
91      m = (owl_mux*)owl_list_get_element(muxevents, i);
92      if (m->eventmask & OWL_MUX_READ)   FD_SET(m->fd, &rfds);
93      if (m->eventmask & OWL_MUX_WRITE)  FD_SET(m->fd, &wfds);
94      if (m->eventmask & OWL_MUX_EXCEPT) FD_SET(m->fd, &efds);
95      if (m->fd > maxfd) maxfd = m->fd;
96  }
97  tv.tv_sec = 0;
98  tv.tv_usec = timeout_usec;
99  rv = select(maxfd+1, &rfds, &wfds, &efds, &tv);
100  if (rv == 0) return;
101 
102  for (i=0; i<nevents; i++) {
103      m = (owl_mux*)owl_list_get_element(muxevents, i);
104      if (!m->active) continue;
105      emask = 0;
106      if (m->eventmask & OWL_MUX_READ && FD_ISSET(m->fd, &rfds)) {
107        emask |= OWL_MUX_READ;
108      }
109      if (m->eventmask & OWL_MUX_WRITE && FD_ISSET(m->fd, &wfds)) {
110        emask |= OWL_MUX_WRITE;
111      }
112      if (m->eventmask & OWL_MUX_EXCEPT && FD_ISSET(m->fd, &efds)) {
113        emask |= OWL_MUX_EXCEPT;
114      }
115      owl_function_debugmsg("muxevents: dispatching %s%s%s to %d\n",
116                            emask&OWL_MUX_READ?"[read]":"",
117                            emask&OWL_MUX_WRITE?"[write]":"",
118                            emask&OWL_MUX_EXCEPT?"[except]":"",
119                            m->fd);
120      if (emask) {
121        m->handler_fn(m->handle, m->fd, emask, m->data);
122      }
123  }
124
125  owl_function_debugmsg("muxevents: finishing dispatch\n");
126  /* we need to do this here so that the size of muxevents
127  * doesn't change while we're traversing it... */
128  owl_muxevents_gc(muxevents);
129}
Note: See TracBrowser for help on using the repository browser.