Changes in select.c [2f69081:1895c29]
Legend:
- Unmodified
- Added
- Removed
-
select.c
r2f69081 r1895c29 2 2 3 3 static const char fileIdent[] = "$Id: select.c 894 2008-01-17 07:13:44Z asedeno $"; 4 5 static int dispatch_active = 0; 6 7 int _owl_select_timer_cmp(owl_timer *t1, owl_timer *t2) { 8 return t1->time - t2->time; 9 } 10 11 int _owl_select_timer_eq(owl_timer *t1, owl_timer *t2) { 12 return t1 == t2; 13 } 14 15 owl_timer *owl_select_add_timer(int after, int interval, void (*cb)(owl_timer *, void *), void (*destroy)(owl_timer*), void *data) 16 { 17 owl_timer *t = owl_malloc(sizeof(owl_timer)); 18 GList **timers = owl_global_get_timerlist(&g); 19 20 t->time = time(NULL) + after; 21 t->interval = interval; 22 t->callback = cb; 23 t->destroy = destroy; 24 t->data = data; 25 26 *timers = g_list_insert_sorted(*timers, t, 27 (GCompareFunc)_owl_select_timer_cmp); 28 return t; 29 } 30 31 void owl_select_remove_timer(owl_timer *t) 32 { 33 GList **timers = owl_global_get_timerlist(&g); 34 if (t && g_list_find(*timers, t)) { 35 *timers = g_list_remove(*timers, t); 36 if(t->destroy) { 37 t->destroy(t); 38 } 39 owl_free(t); 40 } 41 } 42 43 void owl_select_process_timers(struct timeval *timeout) 44 { 45 time_t now = time(NULL); 46 GList **timers = owl_global_get_timerlist(&g); 47 48 while(*timers) { 49 owl_timer *t = (*timers)->data; 50 int remove = 0; 51 52 if(t->time > now) 53 break; 54 55 /* Reschedule if appropriate */ 56 if(t->interval > 0) { 57 t->time = now + t->interval; 58 *timers = g_list_remove(*timers, t); 59 *timers = g_list_insert_sorted(*timers, t, 60 (GCompareFunc)_owl_select_timer_cmp); 61 } else { 62 remove = 1; 63 } 64 65 /* Do the callback */ 66 t->callback(t, t->data); 67 if(remove) { 68 owl_select_remove_timer(t); 69 } 70 } 71 72 if(*timers) { 73 owl_timer *t = (*timers)->data; 74 timeout->tv_sec = t->time - now; 75 if (timeout->tv_sec > 60) 76 timeout->tv_sec = 60; 77 } else { 78 timeout->tv_sec = 60; 79 } 80 81 timeout->tv_usec = 0; 82 } 4 83 5 84 /* Returns the index of the dispatch for the file descriptor. */ … … 19 98 } 20 99 100 void owl_select_remove_dispatch_at(int elt) /* noproto */ 101 { 102 owl_list *dl; 103 owl_dispatch *d; 104 105 dl = owl_global_get_dispatchlist(&g); 106 d = (owl_dispatch*)owl_list_get_element(dl, elt); 107 owl_list_remove_element(dl, elt); 108 if (d->destroy) { 109 d->destroy(d); 110 } 111 } 112 21 113 /* Adds a new owl_dispatch to the list, replacing existing ones if needed. */ 22 114 void owl_select_add_dispatch(owl_dispatch *d) … … 24 116 int elt; 25 117 owl_list *dl; 118 119 d->needs_gc = 0; 26 120 27 121 elt = owl_select_find_dispatch(d->fd); … … 34 128 replace the old dispatch. */ 35 129 if (d_old != d) { 36 owl_list_replace_element(dl, elt, d); 37 owl_free(d_old); 38 } 39 } 40 else { 41 owl_list_append_element(dl, d); 42 } 130 owl_select_remove_dispatch_at(elt); 131 } 132 } 133 owl_list_append_element(dl, d); 43 134 } 44 135 … … 48 139 int elt; 49 140 owl_list *dl; 141 owl_dispatch *d; 50 142 51 143 elt = owl_select_find_dispatch(fd); 52 dl = owl_global_get_dispatchlist(&g); 53 54 if (elt != -1) { 55 owl_dispatch *d; 144 if(elt == -1) { 145 return; 146 } else if(dispatch_active) { 147 /* Defer the removal until dispatch is done walking the list */ 148 dl = owl_global_get_dispatchlist(&g); 56 149 d = (owl_dispatch*)owl_list_get_element(dl, elt); 57 owl_list_remove_element(dl, elt); 58 if (d->pfunc) { 59 owl_perlconfig_dispatch_free(d); 60 } 61 owl_free(d); 150 d->needs_gc = 1; 151 } else { 152 owl_select_remove_dispatch_at(elt); 62 153 } 63 154 } … … 75 166 if (elt != -1) { 76 167 d = (owl_dispatch*)owl_list_get_element(owl_global_get_dispatchlist(&g), elt); 77 if (d-> pfunc == NULL) {168 if (d->cfunc != owl_perlconfig_dispatch) { 78 169 /* don't mess with non-perl dispatch functions from here. */ 79 170 return 1; … … 83 174 d = malloc(sizeof(owl_dispatch)); 84 175 d->fd = fd; 85 d->cfunc = NULL; 86 d->pfunc = cb; 176 d->cfunc = owl_perlconfig_dispatch; 177 d->destroy = owl_perlconfig_dispatch_free; 178 d->data = cb; 87 179 owl_select_add_dispatch(d); 88 180 return 0; … … 97 189 if (elt != -1) { 98 190 d = (owl_dispatch*)owl_list_get_element(owl_global_get_dispatchlist(&g), elt); 99 if (d-> pfunc != NULL) {100 owl_select_remove_dispatch (fd);191 if (d->cfunc == owl_perlconfig_dispatch) { 192 owl_select_remove_dispatch_at(elt); 101 193 return 0; 102 194 } … … 125 217 } 126 218 219 void owl_select_gc() 220 { 221 int i; 222 owl_list *dl; 223 224 dl = owl_global_get_dispatchlist(&g); 225 /* 226 * Count down so we aren't set off by removing items from the list 227 * during the iteration. 228 */ 229 for(i = owl_list_get_size(dl) - 1; i >= 0; i--) { 230 owl_dispatch *d = owl_list_get_element(dl, i); 231 if(d->needs_gc) { 232 owl_select_remove_dispatch_at(i); 233 } 234 } 235 } 236 127 237 void owl_select_dispatch(fd_set *fds, int max_fd) 128 238 { … … 133 243 dl = owl_global_get_dispatchlist(&g); 134 244 len = owl_select_dispatch_count(); 245 246 dispatch_active = 1; 247 135 248 for(i = 0; i < len; i++) { 136 249 d = (owl_dispatch*)owl_list_get_element(dl, i); 137 250 /* While d shouldn't normally be null, the list may be altered by 138 251 * functions we dispatch to. */ 139 if (d != NULL && FD_ISSET(d->fd, fds)) {252 if (d != NULL && !d->needs_gc && FD_ISSET(d->fd, fds)) { 140 253 if (d->cfunc != NULL) { 141 (d->cfunc)();254 d->cfunc(d); 142 255 } 143 else if (d->pfunc != NULL) {144 owl_perlconfig_do_dispatch(d);145 } 146 }147 }256 } 257 } 258 259 dispatch_active = 0; 260 owl_select_gc(); 148 261 } 149 262 … … 182 295 struct timeval timeout; 183 296 184 timeout.tv_sec = 1; 185 timeout.tv_usec = 0; 297 owl_select_process_timers(&timeout); 186 298 187 299 max_fd = owl_select_dispatch_prepare_fd_sets(&r, &e);
Note: See TracChangeset
for help on using the changeset viewer.