Changeset aa69c1e
- Timestamp:
- Jun 22, 2011, 12:37:22 AM (13 years ago)
- Branches:
- master, release-1.10, release-1.8, release-1.9
- Children:
- e146cd7
- Parents:
- 2d04312
- git-author:
- David Benjamin <davidben@mit.edu> (05/24/11 02:10:33)
- git-committer:
- David Benjamin <davidben@mit.edu> (06/22/11 00:37:22)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
global.c
r074bdaa raa69c1e 105 105 106 106 owl_message_init_fmtext_cache(); 107 owl_list_create(&(g->io_dispatch_list));108 107 g->kill_buffer = NULL; 109 108 … … 838 837 { 839 838 return(&(g->startup_tio)); 840 }841 842 owl_list *owl_global_get_io_dispatch_list(owl_global *g)843 {844 return &(g->io_dispatch_list);845 839 } 846 840 -
owl.h
ra6a9ddb raa69c1e 121 121 #define OWL_MESSAGE_DIRECTION_IN 1 122 122 #define OWL_MESSAGE_DIRECTION_OUT 2 123 124 #define OWL_IO_READ 1125 #define OWL_IO_WRITE 2126 #define OWL_IO_EXCEPT 4127 123 128 124 #define OWL_DIRECTION_NONE 0 … … 526 522 bool overflow; 527 523 } owl_colorpair_mgr; 528 529 typedef struct _owl_io_dispatch {530 int fd; /* FD to watch for dispatch. */531 int mode;532 bool valid;533 int needs_gc;534 void (*callback)(const struct _owl_io_dispatch *, void *); /* C function to dispatch to. */535 void (*destroy)(const struct _owl_io_dispatch *); /* Destructor */536 void *data;537 GPollFD pollfd;538 } owl_io_dispatch;539 524 540 525 typedef struct _owl_popexec { … … 607 592 int pseudologin_notify; 608 593 struct termios startup_tio; 609 owl_list io_dispatch_list;610 594 guint aim_nop_timer; 611 595 int load_initial_subs; -
select.c
rbcde7926 raa69c1e 3 3 static GMainLoop *loop = NULL; 4 4 static GMainContext *main_context; 5 static int dispatch_active = 0;6 7 static GSource *owl_io_dispatch_source;8 9 /* Returns the valid owl_io_dispatch for a given file descriptor. */10 static owl_io_dispatch *owl_select_find_valid_io_dispatch_by_fd(const int fd)11 {12 int i, len;13 const owl_list *dl;14 owl_io_dispatch *d;15 dl = owl_global_get_io_dispatch_list(&g);16 len = owl_list_get_size(dl);17 for(i = 0; i < len; i++) {18 d = owl_list_get_element(dl, i);19 if (d->fd == fd && d->valid) return d;20 }21 return NULL;22 }23 24 static int owl_select_find_io_dispatch(const owl_io_dispatch *in)25 {26 int i, len;27 const owl_list *dl;28 29 if (in != NULL) {30 dl = owl_global_get_io_dispatch_list(&g);31 len = owl_list_get_size(dl);32 for(i = 0; i < len; i++) {33 const owl_io_dispatch *d = owl_list_get_element(dl, i);34 if (d == in) return i;35 }36 }37 return -1;38 }39 40 static void owl_select_invalidate_io_dispatch(owl_io_dispatch *d)41 {42 if (d == NULL || !d->valid)43 return;44 d->valid = false;45 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd);46 }47 48 void owl_select_remove_io_dispatch(const owl_io_dispatch *in)49 {50 int elt;51 if (in != NULL) {52 elt = owl_select_find_io_dispatch(in);53 if (elt != -1) {54 owl_list *dl = owl_global_get_io_dispatch_list(&g);55 owl_io_dispatch *d = owl_list_get_element(dl, elt);56 if (dispatch_active)57 d->needs_gc = 1;58 else {59 owl_select_invalidate_io_dispatch(d);60 owl_list_remove_element(dl, elt);61 if (d->destroy)62 d->destroy(d);63 g_free(d);64 }65 }66 }67 }68 69 static void owl_select_io_dispatch_gc(void)70 {71 int i;72 owl_list *dl;73 74 dl = owl_global_get_io_dispatch_list(&g);75 /*76 * Count down so we aren't set off by removing items from the list77 * during the iteration.78 */79 for(i = owl_list_get_size(dl) - 1; i >= 0; i--) {80 owl_io_dispatch *d = owl_list_get_element(dl, i);81 if(d->needs_gc) {82 owl_select_remove_io_dispatch(d);83 }84 }85 }86 87 /* Each FD may have at most one valid dispatcher.88 * If a new dispatch is added for an FD, the old one is removed.89 * mode determines what types of events are watched for, and may be any combination of:90 * OWL_IO_READ, OWL_IO_WRITE, OWL_IO_EXCEPT91 */92 const owl_io_dispatch *owl_select_add_io_dispatch(int fd, int mode, void (*cb)(const owl_io_dispatch *, void *), void (*destroy)(const owl_io_dispatch *), void *data)93 {94 owl_io_dispatch *d = g_new(owl_io_dispatch, 1);95 owl_list *dl = owl_global_get_io_dispatch_list(&g);96 owl_io_dispatch *other;97 98 d->fd = fd;99 d->valid = true;100 d->needs_gc = 0;101 d->mode = mode;102 d->callback = cb;103 d->destroy = destroy;104 d->data = data;105 106 /* TODO: Allow changing fd and mode in the middle? Probably don't care... */107 d->pollfd.fd = fd;108 d->pollfd.events = 0;109 if (d->mode & OWL_IO_READ)110 d->pollfd.events |= G_IO_IN | G_IO_HUP | G_IO_ERR;111 if (d->mode & OWL_IO_WRITE)112 d->pollfd.events |= G_IO_OUT | G_IO_ERR;113 if (d->mode & OWL_IO_EXCEPT)114 d->pollfd.events |= G_IO_PRI | G_IO_ERR;115 g_source_add_poll(owl_io_dispatch_source, &d->pollfd);116 117 118 other = owl_select_find_valid_io_dispatch_by_fd(fd);119 if (other)120 owl_select_invalidate_io_dispatch(other);121 owl_list_append_element(dl, d);122 123 return d;124 }125 126 static gboolean owl_io_dispatch_prepare(GSource *source, int *timeout) {127 *timeout = -1;128 return FALSE;129 }130 131 static gboolean owl_io_dispatch_check(GSource *source) {132 int i, len;133 const owl_list *dl;134 135 dl = owl_global_get_io_dispatch_list(&g);136 len = owl_list_get_size(dl);137 for(i = 0; i < len; i++) {138 owl_io_dispatch *d = owl_list_get_element(dl, i);139 if (!d->valid) continue;140 if (d->pollfd.revents & G_IO_NVAL) {141 owl_function_debugmsg("Pruning defunct dispatch on fd %d.", d->fd);142 owl_select_invalidate_io_dispatch(d);143 }144 if (d->pollfd.revents & d->pollfd.events)145 return TRUE;146 }147 return FALSE;148 }149 150 static gboolean owl_io_dispatch_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {151 int i, len;152 const owl_list *dl;153 154 dispatch_active = 1;155 dl = owl_global_get_io_dispatch_list(&g);156 len = owl_list_get_size(dl);157 for (i = 0; i < len; i++) {158 owl_io_dispatch *d = owl_list_get_element(dl, i);159 if (!d->valid) continue;160 if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) {161 d->callback(d, d->data);162 }163 }164 dispatch_active = 0;165 owl_select_io_dispatch_gc();166 167 return TRUE;168 }169 170 static GSourceFuncs owl_io_dispatch_funcs = {171 owl_io_dispatch_prepare,172 owl_io_dispatch_check,173 owl_io_dispatch_dispatch,174 NULL175 };176 5 177 6 void owl_select_init(void) 178 7 { 179 owl_io_dispatch_source = g_source_new(&owl_io_dispatch_funcs, sizeof(GSource));180 g_source_attach(owl_io_dispatch_source, NULL);181 8 } 182 9
Note: See TracChangeset
for help on using the changeset viewer.