Changes in uspace/lib/c/generic/fibril_synch.c [45cbcaf4:78192cc7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r45cbcaf4 r78192cc7 448 448 int rc; 449 449 450 fibril_mutex_lock(&timer->lock); 451 452 while (true) { 453 while (timer->state != fts_active && 454 timer->state != fts_cleanup) { 455 456 if (timer->state == fts_cleanup) 457 break; 458 459 fibril_condvar_wait(&timer->cv, &timer->lock); 450 fibril_mutex_lock(timer->lockp); 451 452 while (timer->state != fts_cleanup) { 453 switch (timer->state) { 454 case fts_not_set: 455 case fts_fired: 456 fibril_condvar_wait(&timer->cv, timer->lockp); 457 break; 458 case fts_active: 459 rc = fibril_condvar_wait_timeout(&timer->cv, 460 timer->lockp, timer->delay); 461 if (rc == ETIMEOUT && timer->state == fts_active) { 462 timer->state = fts_fired; 463 timer->handler_running = true; 464 fibril_mutex_unlock(timer->lockp); 465 timer->fun(timer->arg); 466 fibril_mutex_lock(timer->lockp); 467 timer->handler_running = false; 468 } 469 break; 470 case fts_cleanup: 471 case fts_clean: 472 assert(false); 473 break; 460 474 } 461 462 if (timer->state == fts_cleanup) 463 break; 464 465 rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock, 466 timer->delay); 467 if (rc == ETIMEOUT) { 468 timer->state = fts_fired; 469 fibril_mutex_unlock(&timer->lock); 470 timer->fun(timer->arg); 471 fibril_mutex_lock(&timer->lock); 472 } 473 } 474 475 fibril_mutex_unlock(&timer->lock); 475 } 476 477 /* Acknowledge timer fibril has finished cleanup. */ 478 timer->state = fts_clean; 479 fibril_mutex_unlock(timer->lockp); 480 free(timer); 481 476 482 return 0; 477 483 } … … 481 487 * @return New timer on success, @c NULL if out of memory. 482 488 */ 483 fibril_timer_t *fibril_timer_create( void)489 fibril_timer_t *fibril_timer_create(fibril_mutex_t *lock) 484 490 { 485 491 fid_t fid; … … 501 507 timer->fibril = fid; 502 508 timer->state = fts_not_set; 509 timer->lockp = (lock != NULL) ? lock : &timer->lock; 503 510 504 511 fibril_add_ready(fid); 505 506 512 return timer; 507 513 } … … 513 519 void fibril_timer_destroy(fibril_timer_t *timer) 514 520 { 515 fibril_mutex_lock(&timer->lock); 516 assert(timer->state != fts_active); 521 fibril_mutex_lock(timer->lockp); 522 assert(timer->state == fts_not_set || timer->state == fts_fired); 523 524 /* Request timer fibril to terminate. */ 517 525 timer->state = fts_cleanup; 518 526 fibril_condvar_broadcast(&timer->cv); 519 fibril_mutex_unlock( &timer->lock);527 fibril_mutex_unlock(timer->lockp); 520 528 } 521 529 … … 533 541 fibril_timer_fun_t fun, void *arg) 534 542 { 535 fibril_mutex_lock(&timer->lock); 543 fibril_mutex_lock(timer->lockp); 544 fibril_timer_set_locked(timer, delay, fun, arg); 545 fibril_mutex_unlock(timer->lockp); 546 } 547 548 /** Set locked timer. 549 * 550 * Set timer to execute a callback function after the specified 551 * interval. Must be called when the timer is locked. 552 * 553 * @param timer Timer 554 * @param delay Delay in microseconds 555 * @param fun Callback function 556 * @param arg Argument for @a fun 557 */ 558 void fibril_timer_set_locked(fibril_timer_t *timer, suseconds_t delay, 559 fibril_timer_fun_t fun, void *arg) 560 { 561 assert(fibril_mutex_is_locked(timer->lockp)); 562 assert(timer->state == fts_not_set || timer->state == fts_fired); 536 563 timer->state = fts_active; 537 564 timer->delay = delay; … … 539 566 timer->arg = arg; 540 567 fibril_condvar_broadcast(&timer->cv); 541 fibril_mutex_unlock(&timer->lock);542 568 } 543 569 … … 557 583 fibril_timer_state_t old_state; 558 584 559 fibril_mutex_lock(&timer->lock); 585 fibril_mutex_lock(timer->lockp); 586 old_state = fibril_timer_clear_locked(timer); 587 fibril_mutex_unlock(timer->lockp); 588 589 return old_state; 590 } 591 592 /** Clear locked timer. 593 * 594 * Clears (cancels) timer and returns last state of the timer. 595 * This can be one of: 596 * - fts_not_set If the timer has not been set or has been cleared 597 * - fts_active Timer was set but did not fire 598 * - fts_fired Timer fired 599 * Must be called when the timer is locked. 600 * 601 * @param timer Timer 602 * @return Last timer state 603 */ 604 fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *timer) 605 { 606 fibril_timer_state_t old_state; 607 608 assert(fibril_mutex_is_locked(timer->lockp)); 609 610 while (timer->handler_running) 611 fibril_condvar_wait(&timer->cv, timer->lockp); 612 560 613 old_state = timer->state; 561 614 timer->state = fts_not_set; … … 565 618 timer->arg = NULL; 566 619 fibril_condvar_broadcast(&timer->cv); 567 fibril_mutex_unlock(&timer->lock);568 620 569 621 return old_state;
Note:
See TracChangeset
for help on using the changeset viewer.