Changeset b279013
- Timestamp:
- Mar 25, 2011, 3:46:46 AM (13 years ago)
- Children:
- 7b2686d
- Parents:
- e9b037f
- git-author:
- David Benjamin <davidben@mit.edu> (12/29/10 07:20:12)
- git-committer:
- David Benjamin <davidben@mit.edu> (03/25/11 03:46:46)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
global.c
r47e0a6a rb279013 16 16 17 17 g_type_init(); 18 19 owl_select_init(); 18 20 19 21 g->lines=LINES; -
owl.h
r283ff1e rb279013 550 550 void (*destroy)(const struct _owl_io_dispatch *); /* Destructor */ 551 551 void *data; 552 GPollFD pollfd; 552 553 } owl_io_dispatch; 553 554 -
select.c
rd4927a7 rb279013 1 1 #include "owl.h" 2 2 3 static GMainLoop *loop = NULL; 3 4 static int dispatch_active = 0; 4 5 static int psa_active = 0; 5 static int loop_active = 0; 6 7 static GSource *owl_timer_source; 8 static GSource *owl_io_dispatch_source; 9 10 static gboolean owl_timer_prepare(GSource *source, int *timeout) { 11 GList **timers = owl_global_get_timerlist(&g); 12 GTimeVal now; 13 14 /* TODO: In the far /far/ future, g_source_get_time is what the cool 15 * kids use to get system monotonic time. */ 16 g_source_get_current_time(source, &now); 17 18 /* FIXME: bother with millisecond accuracy now that we can? */ 19 if (*timers) { 20 owl_timer *t = (*timers)->data; 21 *timeout = t->time - now.tv_sec; 22 if (*timeout <= 0) { 23 *timeout = 0; 24 return TRUE; 25 } 26 if (*timeout > 60 * 1000) 27 *timeout = 60 * 1000; 28 } else { 29 *timeout = 60 * 1000; 30 } 31 return FALSE; 32 } 33 34 static gboolean owl_timer_check(GSource *source) { 35 GList **timers = owl_global_get_timerlist(&g); 36 GTimeVal now; 37 38 /* TODO: In the far /far/ future, g_source_get_time is what the cool 39 * kids use to get system monotonic time. */ 40 g_source_get_current_time(source, &now); 41 42 /* FIXME: bother with millisecond accuracy now that we can? */ 43 if (*timers) { 44 owl_timer *t = (*timers)->data; 45 return t->time >= now.tv_sec; 46 } 47 return FALSE; 48 } 49 50 51 static gboolean owl_timer_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 52 GList **timers = owl_global_get_timerlist(&g); 53 GTimeVal now; 54 55 /* TODO: In the far /far/ future, g_source_get_time is what the cool 56 * kids use to get system monotonic time. */ 57 g_source_get_current_time(source, &now); 58 59 /* FIXME: bother with millisecond accuracy now that we can? */ 60 while(*timers) { 61 owl_timer *t = (*timers)->data; 62 int remove = 0; 63 64 if(t->time > now.tv_sec) 65 break; 66 67 /* Reschedule if appropriate */ 68 if(t->interval > 0) { 69 t->time = now.tv_sec + t->interval; 70 *timers = g_list_remove(*timers, t); 71 *timers = g_list_insert_sorted(*timers, t, 72 (GCompareFunc)_owl_select_timer_cmp); 73 } else { 74 remove = 1; 75 } 76 77 /* Do the callback */ 78 t->callback(t, t->data); 79 if(remove) { 80 owl_select_remove_timer(t); 81 } 82 } 83 return TRUE; 84 } 85 86 static GSourceFuncs owl_timer_funcs = { 87 owl_timer_prepare, 88 owl_timer_check, 89 owl_timer_dispatch, 90 NULL 91 }; 6 92 7 93 int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2) { … … 43 129 } 44 130 45 void owl_select_process_timers(struct timespec *timeout) 46 { 47 time_t now = time(NULL); 48 GList **timers = owl_global_get_timerlist(&g); 49 50 while(*timers) { 51 owl_timer *t = (*timers)->data; 52 int remove = 0; 53 54 if(t->time > now) 55 break; 56 57 /* Reschedule if appropriate */ 58 if(t->interval > 0) { 59 t->time = now + t->interval; 60 *timers = g_list_remove(*timers, t); 61 *timers = g_list_insert_sorted(*timers, t, 62 (GCompareFunc)_owl_select_timer_cmp); 63 } else { 64 remove = 1; 65 } 66 67 /* Do the callback */ 68 t->callback(t, t->data); 69 if(remove) { 70 owl_select_remove_timer(t); 71 } 72 } 73 74 if(*timers) { 75 owl_timer *t = (*timers)->data; 76 timeout->tv_sec = t->time - now; 77 if (timeout->tv_sec > 60) 78 timeout->tv_sec = 60; 79 } else { 80 timeout->tv_sec = 60; 81 } 82 83 timeout->tv_nsec = 0; 84 } 131 132 static gboolean owl_io_dispatch_prepare(GSource *source, int *timeout) { 133 owl_select_do_pre_select_actions(); /* HACK */ 134 *timeout = -1; 135 return FALSE; 136 } 137 138 static gboolean owl_io_dispatch_check(GSource *source) { 139 int i, len; 140 const owl_list *dl; 141 142 dl = owl_global_get_io_dispatch_list(&g); 143 len = owl_list_get_size(dl); 144 for(i = 0; i < len; i++) { 145 const owl_io_dispatch *d = owl_list_get_element(dl, i); 146 if (d->pollfd.revents & d->pollfd.events) 147 return TRUE; 148 } 149 return FALSE; 150 } 151 152 static gboolean owl_io_dispatch_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 153 int i, len; 154 const owl_list *dl; 155 156 dispatch_active = 1; 157 dl = owl_global_get_io_dispatch_list(&g); 158 len = owl_list_get_size(dl); 159 for (i = 0; i < len; i++) { 160 owl_io_dispatch *d = owl_list_get_element(dl, i); 161 if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) { 162 d->callback(d, d->data); 163 } 164 } 165 dispatch_active = 0; 166 owl_select_io_dispatch_gc(); 167 168 return TRUE; 169 } 170 171 static GSourceFuncs owl_io_dispatch_funcs = { 172 owl_io_dispatch_prepare, 173 owl_io_dispatch_check, 174 owl_io_dispatch_dispatch, 175 NULL 176 }; 85 177 86 178 static const owl_io_dispatch *owl_select_find_io_dispatch_by_fd(const int fd) … … 128 220 if (d->destroy) 129 221 d->destroy(d); 222 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd); 130 223 g_free(d); 131 224 } … … 169 262 d->data = data; 170 263 264 /* TODO: Allow changing fd and mode in the middle? Probably don't care... */ 265 d->pollfd.fd = fd; 266 d->pollfd.events = 0; 267 if (d->mode & OWL_IO_READ) 268 d->pollfd.events |= G_IO_IN | G_IO_HUP | G_IO_ERR; 269 if (d->mode & OWL_IO_WRITE) 270 d->pollfd.events |= G_IO_OUT | G_IO_ERR; 271 if (d->mode & OWL_IO_EXCEPT) 272 d->pollfd.events |= G_IO_PRI | G_IO_ERR; 273 g_source_add_poll(owl_io_dispatch_source, &d->pollfd); 274 275 171 276 owl_select_remove_io_dispatch(owl_select_find_io_dispatch_by_fd(fd)); 172 277 owl_list_append_element(dl, d); 173 278 174 279 return d; 175 }176 177 int owl_select_prepare_io_dispatch_fd_sets(fd_set *rfds, fd_set *wfds, fd_set *efds) {178 int i, len, max_fd;179 owl_io_dispatch *d;180 owl_list *dl = owl_global_get_io_dispatch_list(&g);181 182 max_fd = 0;183 len = owl_list_get_size(dl);184 for (i = 0; i < len; i++) {185 d = owl_list_get_element(dl, i);186 if (d->mode & (OWL_IO_READ | OWL_IO_WRITE | OWL_IO_EXCEPT)) {187 if (max_fd < d->fd) max_fd = d->fd;188 if (d->mode & OWL_IO_READ) FD_SET(d->fd, rfds);189 if (d->mode & OWL_IO_WRITE) FD_SET(d->fd, wfds);190 if (d->mode & OWL_IO_EXCEPT) FD_SET(d->fd, efds);191 }192 }193 return max_fd + 1;194 }195 196 void owl_select_io_dispatch(const fd_set *rfds, const fd_set *wfds, const fd_set *efds, const int max_fd)197 {198 int i, len;199 owl_io_dispatch *d;200 owl_list *dl = owl_global_get_io_dispatch_list(&g);201 202 dispatch_active = 1;203 len = owl_list_get_size(dl);204 for (i = 0; i < len; i++) {205 d = owl_list_get_element(dl, i);206 if (d->fd < max_fd && d->callback != NULL &&207 ((d->mode & OWL_IO_READ && FD_ISSET(d->fd, rfds)) ||208 (d->mode & OWL_IO_WRITE && FD_ISSET(d->fd, wfds)) ||209 (d->mode & OWL_IO_EXCEPT && FD_ISSET(d->fd, efds)))) {210 d->callback(d, d->data);211 }212 }213 dispatch_active = 0;214 owl_select_io_dispatch_gc();215 280 } 216 281 … … 355 420 } 356 421 422 #if 0 357 423 void owl_select(void) 358 424 { … … 439 505 } 440 506 } 507 #endif 508 509 void owl_select_init(void) 510 { 511 owl_timer_source = g_source_new(&owl_timer_funcs, sizeof(GSource)); 512 g_source_attach(owl_timer_source, NULL); 513 514 owl_io_dispatch_source = g_source_new(&owl_io_dispatch_funcs, sizeof(GSource)); 515 g_source_attach(owl_io_dispatch_source, NULL); 516 } 441 517 442 518 void owl_select_run_loop(void) 443 519 { 444 loop_active = 1; 445 while (loop_active) { 446 owl_select(); 447 } 520 loop = g_main_loop_new(NULL, FALSE); 521 g_main_loop_run(loop); 448 522 } 449 523 450 524 void owl_select_quit_loop(void) 451 525 { 452 loop_active = 0; 453 } 526 if (loop) { 527 g_main_loop_quit(loop); 528 loop = NULL; 529 } 530 }
Note: See TracChangeset
for help on using the changeset viewer.