Changeset 2c79eae
- Timestamp:
- May 23, 2011, 8:57:46 PM (13 years ago)
- Branches:
- master, release-1.10, release-1.8, release-1.9
- Children:
- 4cc49bc
- Parents:
- 1255365
- git-author:
- David Benjamin <davidben@mit.edu> (12/29/10 07:20:12)
- git-committer:
- David Benjamin <davidben@mit.edu> (05/23/11 20:57:46)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
global.c
r47e0a6a r2c79eae 16 16 17 17 g_type_init(); 18 19 owl_select_init(); 18 20 19 21 g->lines=LINES; -
owl.h
rfeeb835 r2c79eae 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
rebb8498 r2c79eae 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; 6 9 7 10 static int _owl_select_timer_cmp(const owl_timer *t1, const owl_timer *t2) { … … 39 42 } 40 43 41 void owl_select_process_timers(struct timespec *timeout) 42 { 43 time_t now = time(NULL); 44 static gboolean owl_timer_prepare(GSource *source, int *timeout) { 44 45 GList **timers = owl_global_get_timerlist(&g); 45 46 GTimeVal now; 47 48 /* TODO: In the far /far/ future, g_source_get_time is what the cool 49 * kids use to get system monotonic time. */ 50 g_source_get_current_time(source, &now); 51 52 /* FIXME: bother with millisecond accuracy now that we can? */ 53 if (*timers) { 54 owl_timer *t = (*timers)->data; 55 *timeout = t->time - now.tv_sec; 56 if (*timeout <= 0) { 57 *timeout = 0; 58 return TRUE; 59 } 60 if (*timeout > 60 * 1000) 61 *timeout = 60 * 1000; 62 } else { 63 *timeout = 60 * 1000; 64 } 65 return FALSE; 66 } 67 68 static gboolean owl_timer_check(GSource *source) { 69 GList **timers = owl_global_get_timerlist(&g); 70 GTimeVal now; 71 72 /* TODO: In the far /far/ future, g_source_get_time is what the cool 73 * kids use to get system monotonic time. */ 74 g_source_get_current_time(source, &now); 75 76 /* FIXME: bother with millisecond accuracy now that we can? */ 77 if (*timers) { 78 owl_timer *t = (*timers)->data; 79 return t->time >= now.tv_sec; 80 } 81 return FALSE; 82 } 83 84 85 static gboolean owl_timer_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 86 GList **timers = owl_global_get_timerlist(&g); 87 GTimeVal now; 88 89 /* TODO: In the far /far/ future, g_source_get_time is what the cool 90 * kids use to get system monotonic time. */ 91 g_source_get_current_time(source, &now); 92 93 /* FIXME: bother with millisecond accuracy now that we can? */ 46 94 while(*timers) { 47 95 owl_timer *t = (*timers)->data; 48 96 int remove = 0; 49 97 50 if(t->time > now )98 if(t->time > now.tv_sec) 51 99 break; 52 100 53 101 /* Reschedule if appropriate */ 54 102 if(t->interval > 0) { 55 t->time = now + t->interval;103 t->time = now.tv_sec + t->interval; 56 104 *timers = g_list_remove(*timers, t); 57 105 *timers = g_list_insert_sorted(*timers, t, … … 67 115 } 68 116 } 69 70 if(*timers) { 71 owl_timer *t = (*timers)->data; 72 timeout->tv_sec = t->time - now; 73 if (timeout->tv_sec > 60) 74 timeout->tv_sec = 60; 75 } else { 76 timeout->tv_sec = 60; 77 } 78 79 timeout->tv_nsec = 0; 80 } 117 return TRUE; 118 } 119 120 static GSourceFuncs owl_timer_funcs = { 121 owl_timer_prepare, 122 owl_timer_check, 123 owl_timer_dispatch, 124 NULL 125 }; 126 81 127 82 128 static const owl_io_dispatch *owl_select_find_io_dispatch_by_fd(const int fd) … … 124 170 if (d->destroy) 125 171 d->destroy(d); 172 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd); 126 173 g_free(d); 127 174 } … … 165 212 d->data = data; 166 213 214 /* TODO: Allow changing fd and mode in the middle? Probably don't care... */ 215 d->pollfd.fd = fd; 216 d->pollfd.events = 0; 217 if (d->mode & OWL_IO_READ) 218 d->pollfd.events |= G_IO_IN | G_IO_HUP | G_IO_ERR; 219 if (d->mode & OWL_IO_WRITE) 220 d->pollfd.events |= G_IO_OUT | G_IO_ERR; 221 if (d->mode & OWL_IO_EXCEPT) 222 d->pollfd.events |= G_IO_PRI | G_IO_ERR; 223 g_source_add_poll(owl_io_dispatch_source, &d->pollfd); 224 225 167 226 owl_select_remove_io_dispatch(owl_select_find_io_dispatch_by_fd(fd)); 168 227 owl_list_append_element(dl, d); … … 171 230 } 172 231 173 int owl_select_prepare_io_dispatch_fd_sets(fd_set *rfds, fd_set *wfds, fd_set *efds) { 174 int i, len, max_fd; 175 owl_io_dispatch *d; 176 owl_list *dl = owl_global_get_io_dispatch_list(&g); 177 178 max_fd = 0; 232 static gboolean owl_io_dispatch_prepare(GSource *source, int *timeout) { 233 owl_select_do_pre_select_actions(); /* HACK */ 234 *timeout = -1; 235 return FALSE; 236 } 237 238 static gboolean owl_io_dispatch_check(GSource *source) { 239 int i, len; 240 const owl_list *dl; 241 242 dl = owl_global_get_io_dispatch_list(&g); 243 len = owl_list_get_size(dl); 244 for(i = 0; i < len; i++) { 245 const owl_io_dispatch *d = owl_list_get_element(dl, i); 246 if (d->pollfd.revents & d->pollfd.events) 247 return TRUE; 248 } 249 return FALSE; 250 } 251 252 static gboolean owl_io_dispatch_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) { 253 int i, len; 254 const owl_list *dl; 255 256 dispatch_active = 1; 257 dl = owl_global_get_io_dispatch_list(&g); 179 258 len = owl_list_get_size(dl); 180 259 for (i = 0; i < len; i++) { 181 d = owl_list_get_element(dl, i); 182 if (d->mode & (OWL_IO_READ | OWL_IO_WRITE | OWL_IO_EXCEPT)) { 183 if (max_fd < d->fd) max_fd = d->fd; 184 if (d->mode & OWL_IO_READ) FD_SET(d->fd, rfds); 185 if (d->mode & OWL_IO_WRITE) FD_SET(d->fd, wfds); 186 if (d->mode & OWL_IO_EXCEPT) FD_SET(d->fd, efds); 187 } 188 } 189 return max_fd + 1; 190 } 191 192 void owl_select_io_dispatch(const fd_set *rfds, const fd_set *wfds, const fd_set *efds, const int max_fd) 193 { 194 int i, len; 195 owl_io_dispatch *d; 196 owl_list *dl = owl_global_get_io_dispatch_list(&g); 197 198 dispatch_active = 1; 199 len = owl_list_get_size(dl); 200 for (i = 0; i < len; i++) { 201 d = owl_list_get_element(dl, i); 202 if (d->fd < max_fd && d->callback != NULL && 203 ((d->mode & OWL_IO_READ && FD_ISSET(d->fd, rfds)) || 204 (d->mode & OWL_IO_WRITE && FD_ISSET(d->fd, wfds)) || 205 (d->mode & OWL_IO_EXCEPT && FD_ISSET(d->fd, efds)))) { 260 owl_io_dispatch *d = owl_list_get_element(dl, i); 261 if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) { 206 262 d->callback(d, d->data); 207 263 } … … 209 265 dispatch_active = 0; 210 266 owl_select_io_dispatch_gc(); 211 } 267 268 return TRUE; 269 } 270 271 static GSourceFuncs owl_io_dispatch_funcs = { 272 owl_io_dispatch_prepare, 273 owl_io_dispatch_check, 274 owl_io_dispatch_dispatch, 275 NULL 276 }; 212 277 213 278 int owl_select_add_perl_io_dispatch(int fd, int mode, SV *cb) … … 351 416 } 352 417 418 #if 0 419 /* FIXME: Reimplement the AIM hack and handle AIM events. */ 353 420 void owl_select(void) 354 421 { … … 435 502 } 436 503 } 504 #endif 505 506 void owl_select_init(void) 507 { 508 owl_timer_source = g_source_new(&owl_timer_funcs, sizeof(GSource)); 509 g_source_attach(owl_timer_source, NULL); 510 511 owl_io_dispatch_source = g_source_new(&owl_io_dispatch_funcs, sizeof(GSource)); 512 g_source_attach(owl_io_dispatch_source, NULL); 513 } 437 514 438 515 void owl_select_run_loop(void) 439 516 { 440 loop_active = 1; 441 while (loop_active) { 442 owl_select(); 443 } 517 loop = g_main_loop_new(NULL, FALSE); 518 g_main_loop_run(loop); 444 519 } 445 520 446 521 void owl_select_quit_loop(void) 447 522 { 448 loop_active = 0; 449 } 523 if (loop) { 524 g_main_loop_quit(loop); 525 loop = NULL; 526 } 527 }
Note: See TracChangeset
for help on using the changeset viewer.