Changeset 33b6431b
- Timestamp:
- May 23, 2011, 10:24:49 PM (13 years ago)
- Branches:
- master, release-1.10, release-1.8, release-1.9
- Children:
- b848e30
- Parents:
- f97c1a6
- git-author:
- David Benjamin <davidben@mit.edu> (05/23/11 22:17:05)
- git-committer:
- David Benjamin <davidben@mit.edu> (05/23/11 22:24:49)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
owl.h
rf97c1a6 r33b6431b 548 548 int fd; /* FD to watch for dispatch. */ 549 549 int mode; 550 bool valid; 550 551 int needs_gc; 551 552 void (*callback)(const struct _owl_io_dispatch *, void *); /* C function to dispatch to. */ -
select.c
rf97c1a6 r33b6431b 125 125 }; 126 126 127 128 static const owl_io_dispatch *owl_select_find_io_dispatch_by_fd(const int fd)127 /* Returns the valid owl_io_dispatch for a given file descriptor. */ 128 static owl_io_dispatch *owl_select_find_valid_io_dispatch_by_fd(const int fd) 129 129 { 130 130 int i, len; … … 135 135 for(i = 0; i < len; i++) { 136 136 d = owl_list_get_element(dl, i); 137 if (d->fd == fd ) return d;137 if (d->fd == fd && d->valid) return d; 138 138 } 139 139 return NULL; … … 154 154 } 155 155 return -1; 156 } 157 158 static void owl_select_invalidate_io_dispatch(owl_io_dispatch *d) 159 { 160 if (d == NULL || !d->valid) 161 return; 162 d->valid = false; 163 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd); 156 164 } 157 165 … … 167 175 d->needs_gc = 1; 168 176 else { 177 owl_select_invalidate_io_dispatch(d); 169 178 owl_list_remove_element(dl, elt); 170 179 if (d->destroy) 171 180 d->destroy(d); 172 g_source_remove_poll(owl_io_dispatch_source, &d->pollfd);173 181 g_free(d); 174 182 } … … 195 203 } 196 204 197 /* Each FD may have at most one dispatcher.205 /* Each FD may have at most one valid dispatcher. 198 206 * If a new dispatch is added for an FD, the old one is removed. 199 207 * mode determines what types of events are watched for, and may be any combination of: … … 204 212 owl_io_dispatch *d = g_new(owl_io_dispatch, 1); 205 213 owl_list *dl = owl_global_get_io_dispatch_list(&g); 214 owl_io_dispatch *other; 206 215 207 216 d->fd = fd; 217 d->valid = true; 208 218 d->needs_gc = 0; 209 219 d->mode = mode; … … 224 234 225 235 226 owl_select_remove_io_dispatch(owl_select_find_io_dispatch_by_fd(fd)); 236 other = owl_select_find_valid_io_dispatch_by_fd(fd); 237 if (other) 238 owl_select_invalidate_io_dispatch(other); 227 239 owl_list_append_element(dl, d); 228 240 … … 242 254 len = owl_list_get_size(dl); 243 255 for(i = 0; i < len; i++) { 244 const owl_io_dispatch *d = owl_list_get_element(dl, i); 256 owl_io_dispatch *d = owl_list_get_element(dl, i); 257 if (!d->valid) continue; 258 if (d->pollfd.revents & G_IO_NVAL) { 259 owl_function_debugmsg("Pruning defunct dispatch on fd %d.", d->fd); 260 owl_select_invalidate_io_dispatch(d); 261 } 245 262 if (d->pollfd.revents & d->pollfd.events) 246 263 return TRUE; … … 258 275 for (i = 0; i < len; i++) { 259 276 owl_io_dispatch *d = owl_list_get_element(dl, i); 277 if (!d->valid) continue; 260 278 if ((d->pollfd.revents & d->pollfd.events) && d->callback != NULL) { 261 279 d->callback(d, d->data); … … 277 295 int owl_select_add_perl_io_dispatch(int fd, int mode, SV *cb) 278 296 { 279 const owl_io_dispatch *d = owl_select_find_ io_dispatch_by_fd(fd);297 const owl_io_dispatch *d = owl_select_find_valid_io_dispatch_by_fd(fd); 280 298 if (d != NULL && d->callback != owl_perlconfig_io_dispatch) { 281 299 /* Don't mess with non-perl dispatch functions from here. */ 282 300 return 1; 283 301 } 302 /* Also remove any invalidated perl dispatch functions that may have 303 * stuck around. */ 304 owl_select_remove_perl_io_dispatch(fd); 284 305 owl_select_add_io_dispatch(fd, mode, owl_perlconfig_io_dispatch, owl_perlconfig_io_dispatch_destroy, cb); 285 306 return 0; 286 307 } 287 308 309 static owl_io_dispatch *owl_select_find_perl_io_dispatch(int fd) 310 { 311 int i, len; 312 const owl_list *dl; 313 owl_io_dispatch *d; 314 dl = owl_global_get_io_dispatch_list(&g); 315 len = owl_list_get_size(dl); 316 for(i = 0; i < len; i++) { 317 d = owl_list_get_element(dl, i); 318 if (d->fd == fd && d->callback == owl_perlconfig_io_dispatch) 319 return d; 320 } 321 return NULL; 322 } 323 288 324 int owl_select_remove_perl_io_dispatch(int fd) 289 325 { 290 const owl_io_dispatch *d = owl_select_find_io_dispatch_by_fd(fd);291 if (d != NULL && d->callback == owl_perlconfig_io_dispatch) {326 owl_io_dispatch *d = owl_select_find_perl_io_dispatch(fd); 327 if (d != NULL) { 292 328 /* Only remove perl io dispatchers from here. */ 293 329 owl_select_remove_io_dispatch(d); … … 320 356 } 321 357 } 322 323 #if 0324 /* FIXME: Reimplement this check in the glib world. */325 static void owl_select_prune_bad_fds(void) {326 owl_list *dl = owl_global_get_io_dispatch_list(&g);327 int len, i;328 struct stat st;329 owl_io_dispatch *d;330 331 len = owl_list_get_size(dl);332 for (i = 0; i < len; i++) {333 d = owl_list_get_element(dl, i);334 if (fstat(d->fd, &st) < 0 && errno == EBADF) {335 owl_function_debugmsg("Pruning defunct dispatch on fd %d.", d->fd);336 d->needs_gc = 1;337 }338 }339 owl_select_io_dispatch_gc();340 }341 #endif342 358 343 359 typedef struct _owl_task { /*noproto*/
Note: See TracChangeset
for help on using the changeset viewer.