Changeset e435c5bf61eb1f943d440e635521d9ce21e78a2d
- Timestamp:
- 05/13/08 18:14:46
(5 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1210702486 +0000
- git-parent:
[c1fcb76822fc1aa6b47a9999834cab6c2abeba47]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1210702486 +0000
- Message:
closes #14
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r4c05448 |
re435c5b |
|
| 303 | 303 | } |
|---|
| 304 | 304 | else { |
|---|
| | 305 | /* see kqueue implementation for details on the next line */ |
|---|
| | 306 | if(master_fds[fd].e == e) master_fds[fd].e = NULL; |
|---|
| 305 | 307 | eventer_free(e); |
|---|
| 306 | 308 | } |
|---|
| r4b96846 |
re435c5b |
|
| 138 | 138 | assert(e->mask); |
|---|
| 139 | 139 | ev_lock_state_t lockstate; |
|---|
| | 140 | const char *cbname; |
|---|
| | 141 | cbname = eventer_name_for_callback(e->callback); |
|---|
| 140 | 142 | |
|---|
| 141 | 143 | if(e->mask & EVENTER_ASYNCH) { |
|---|
| | 144 | noitL(eventer_deb, "debug: eventer_add asynch (%s)\n", cbname ? cbname : "???"); |
|---|
| 142 | 145 | eventer_add_asynch(NULL, e); |
|---|
| 143 | 146 | return; |
|---|
| … | … | |
| 146 | 149 | /* Recurrent delegation */ |
|---|
| 147 | 150 | if(e->mask & EVENTER_RECURRENT) { |
|---|
| | 151 | noitL(eventer_deb, "debug: eventer_add recurrent (%s)\n", cbname ? cbname : "???"); |
|---|
| 148 | 152 | eventer_add_recurrent(e); |
|---|
| 149 | 153 | return; |
|---|
| … | … | |
| 152 | 156 | /* Timed events are simple */ |
|---|
| 153 | 157 | if(e->mask & EVENTER_TIMER) { |
|---|
| | 158 | noitL(eventer_deb, "debug: eventer_add timed (%s)\n", cbname ? cbname : "???"); |
|---|
| 154 | 159 | pthread_mutex_lock(&te_lock); |
|---|
| 155 | 160 | noit_skiplist_insert(timed_events, e); |
|---|
| … | … | |
| 159 | 164 | |
|---|
| 160 | 165 | /* file descriptor event */ |
|---|
| | 166 | noitL(eventer_deb, "debug: eventer_add fd (%s,%d,0x%04x)\n", cbname ? cbname : "???", e->fd, e->mask); |
|---|
| 161 | 167 | lockstate = acquire_master_fd(e->fd); |
|---|
| 162 | 168 | master_fds[e->fd].e = e; |
|---|
| … | … | |
| 248 | 254 | pthread_setspecific(kqueue_setup_key, kqs); |
|---|
| 249 | 255 | while(1) { |
|---|
| | 256 | const char *cbname; |
|---|
| 250 | 257 | struct timeval __now, __sleeptime; |
|---|
| 251 | 258 | struct timespec __kqueue_sleeptime; |
|---|
| … | … | |
| 281 | 288 | if(timed_event == NULL) break; |
|---|
| 282 | 289 | |
|---|
| | 290 | cbname = eventer_name_for_callback(timed_event->callback); |
|---|
| | 291 | noitLT(eventer_deb, &__now, "debug: timed dispatch(%s)\n", cbname ? cbname : "???"); |
|---|
| 283 | 292 | /* Make our call */ |
|---|
| 284 | 293 | newmask = timed_event->callback(timed_event, EVENTER_TIMER, |
|---|
| … | … | |
| 344 | 353 | /* Loop a last time to process */ |
|---|
| 345 | 354 | for(idx = 0; idx < fd_cnt; idx++) { |
|---|
| 346 | | const char *cbname; |
|---|
| 347 | 355 | ev_lock_state_t lockstate; |
|---|
| 348 | 356 | struct kevent *ke; |
|---|
| … | … | |
| 392 | 400 | } |
|---|
| 393 | 401 | else { |
|---|
| | 402 | /* |
|---|
| | 403 | * Long story long: |
|---|
| | 404 | * When integrating with a few external event systems, we find |
|---|
| | 405 | * it difficult to make their use of remove+add as an update |
|---|
| | 406 | * as it can be recurrent in a single handler call and you cannot |
|---|
| | 407 | * remove completely from the event system if you are going to |
|---|
| | 408 | * just update (otherwise the eventer_t in your call stack could |
|---|
| | 409 | * be stale). What we do is perform a superficial remove, marking |
|---|
| | 410 | * the mask as 0, but not eventer_remove_fd. Then on an add, if |
|---|
| | 411 | * we already have an event, we just update the mask (as we |
|---|
| | 412 | * have not yet returned to the eventer's loop. |
|---|
| | 413 | * This leaves us in a tricky situation when a remove is called |
|---|
| | 414 | * and the add doesn't roll in, we return 0 (mask == 0) and hit |
|---|
| | 415 | * this spot. We have intended to remove the event, but it still |
|---|
| | 416 | * resides at master_fds[fd].e -- even after we free it. |
|---|
| | 417 | * So, in the evnet that we return 0 and the event that |
|---|
| | 418 | * master_fds[fd].e == the event we're about to free... we NULL |
|---|
| | 419 | * it out. |
|---|
| | 420 | */ |
|---|
| | 421 | if(master_fds[fd].e == e) master_fds[fd].e = NULL; |
|---|
| 394 | 422 | eventer_free(e); |
|---|
| 395 | 423 | } |
|---|