Changeset 1895c29
- Timestamp:
- Dec 17, 2008, 5:13:20 PM (16 years ago)
- Branches:
- master, debian, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- cf0cc64
- Parents:
- f36cd97
- git-author:
- Nelson Elhage <nelhage@mit.edu> (12/17/08 16:58:41)
- git-committer:
- Nelson Elhage <nelhage@mit.edu> (12/17/08 17:13:20)
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
owl.h
rf36cd97 r1895c29 527 527 typedef struct _owl_dispatch { 528 528 int fd; /* FD to watch for dispatch. */ 529 int needs_gc; 529 530 void (*cfunc)(struct _owl_dispatch*); /* C function to dispatch to. */ 530 531 void (*destroy)(struct _owl_dispatch*); /* Destructor */ -
perlconfig.c
rf36cd97 r1895c29 447 447 { 448 448 SvREFCNT_dec(d->data); 449 owl_free(d); 449 450 } 450 451 -
select.c
rf36cd97 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; 4 6 5 7 int _owl_select_timer_cmp(owl_timer *t1, owl_timer *t2) { … … 96 98 } 97 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 98 113 /* Adds a new owl_dispatch to the list, replacing existing ones if needed. */ 99 114 void owl_select_add_dispatch(owl_dispatch *d) … … 101 116 int elt; 102 117 owl_list *dl; 118 119 d->needs_gc = 0; 103 120 104 121 elt = owl_select_find_dispatch(d->fd); … … 111 128 replace the old dispatch. */ 112 129 if (d_old != d) { 113 owl_list_replace_element(dl, elt, d); 114 owl_free(d_old); 115 } 116 } 117 else { 118 owl_list_append_element(dl, d); 119 } 130 owl_select_remove_dispatch_at(elt); 131 } 132 } 133 owl_list_append_element(dl, d); 120 134 } 121 135 … … 125 139 int elt; 126 140 owl_list *dl; 141 owl_dispatch *d; 127 142 128 143 elt = owl_select_find_dispatch(fd); 129 dl = owl_global_get_dispatchlist(&g); 130 131 if (elt != -1) { 132 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); 133 149 d = (owl_dispatch*)owl_list_get_element(dl, elt); 134 owl_list_remove_element(dl, elt); 135 if (d->destroy) { 136 d->destroy(d); 137 } 138 owl_free(d); 150 d->needs_gc = 1; 151 } else { 152 owl_select_remove_dispatch_at(elt); 139 153 } 140 154 } … … 176 190 d = (owl_dispatch*)owl_list_get_element(owl_global_get_dispatchlist(&g), elt); 177 191 if (d->cfunc == owl_perlconfig_dispatch) { 178 owl_select_remove_dispatch (fd);192 owl_select_remove_dispatch_at(elt); 179 193 return 0; 180 194 } … … 203 217 } 204 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 205 237 void owl_select_dispatch(fd_set *fds, int max_fd) 206 238 { … … 211 243 dl = owl_global_get_dispatchlist(&g); 212 244 len = owl_select_dispatch_count(); 245 246 dispatch_active = 1; 247 213 248 for(i = 0; i < len; i++) { 214 249 d = (owl_dispatch*)owl_list_get_element(dl, i); 215 250 /* While d shouldn't normally be null, the list may be altered by 216 251 * functions we dispatch to. */ 217 if (d != NULL && FD_ISSET(d->fd, fds)) {252 if (d != NULL && !d->needs_gc && FD_ISSET(d->fd, fds)) { 218 253 if (d->cfunc != NULL) { 219 254 d->cfunc(d); … … 221 256 } 222 257 } 258 259 dispatch_active = 0; 260 owl_select_gc(); 223 261 } 224 262
Note: See TracChangeset
for help on using the changeset viewer.