Changeset 2a3214e in mainline for uspace/lib/c/generic/fibril_synch.c


Ignore:
Timestamp:
2011-10-26T16:50:52Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8218b6b
Parents:
6e88fea
Message:

Fibril timer primitive.
TCP Time-Wait timeout.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril_synch.c

    r6e88fea r2a3214e  
    447447}
    448448
     449/** Timer fibril.
     450 *
     451 * @param arg   Timer
     452 */
     453static int fibril_timer_func(void *arg)
     454{
     455        fibril_timer_t *timer = (fibril_timer_t *) arg;
     456        int rc;
     457
     458        fibril_mutex_lock(&timer->lock);
     459
     460        while (true) {
     461                while (timer->state != fts_active &&
     462                    timer->state != fts_cleanup) {
     463
     464                        if (timer->state == fts_cleanup)
     465                                break;
     466
     467                        fibril_condvar_wait(&timer->cv, &timer->lock);
     468                }
     469
     470                if (timer->state == fts_cleanup)
     471                        break;
     472
     473                rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock,
     474                    timer->delay);
     475                if (rc == ETIMEOUT) {
     476                        timer->fun(timer->arg);
     477                        timer->state = fts_fired;
     478                }
     479        }
     480
     481        fibril_mutex_unlock(&timer->lock);
     482        return 0;
     483}
     484
     485/** Create new timer.
     486 *
     487 * @return              New timer on success, @c NULL if out of memory.
     488 */
     489fibril_timer_t *fibril_timer_create(void)
     490{
     491        fid_t fid;
     492        fibril_timer_t *timer;
     493
     494        timer = calloc(1, sizeof(fibril_timer_t));
     495        if (timer == NULL)
     496                return NULL;
     497
     498        fid = fibril_create(fibril_timer_func, (void *) timer);
     499        if (fid == 0) {
     500                free(timer);
     501                return NULL;
     502        }
     503
     504        fibril_mutex_initialize(&timer->lock);
     505        fibril_condvar_initialize(&timer->cv);
     506
     507        timer->fibril = fid;
     508        timer->state = fts_not_set;
     509
     510        fibril_add_ready(fid);
     511
     512        return timer;
     513}
     514
     515/** Destroy timer.
     516 *
     517 * @param timer         Timer, must not be active or accessed by other threads.
     518 */
     519void fibril_timer_destroy(fibril_timer_t *timer)
     520{
     521        fibril_mutex_lock(&timer->lock);
     522        assert(timer->state != fts_active);
     523        timer->state = fts_cleanup;
     524        fibril_condvar_broadcast(&timer->cv);
     525        fibril_mutex_unlock(&timer->lock);
     526}
     527
     528/** Set timer.
     529 *
     530 * Set timer to execute a callback function after the specified
     531 * interval.
     532 *
     533 * @param timer         Timer
     534 * @param delay         Delay in microseconds
     535 * @param fun           Callback function
     536 * @param arg           Argument for @a fun
     537 */
     538void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay,
     539    fibril_timer_fun_t fun, void *arg)
     540{
     541        fibril_mutex_lock(&timer->lock);
     542        timer->state = fts_active;
     543        timer->delay = delay;
     544        timer->fun = fun;
     545        timer->arg = arg;
     546        fibril_condvar_broadcast(&timer->cv);
     547        fibril_mutex_unlock(&timer->lock);
     548}
     549
     550/** Clear timer.
     551 *
     552 * Clears (cancels) timer and returns last state of the timer.
     553 * This can be one of:
     554 *    - fts_not_set     If the timer has not been set or has been cleared
     555 *    - fts_active      Timer was set but did not fire
     556 *    - fts_fired       Timer fired
     557 *
     558 * @param timer         Timer
     559 * @return              Last timer state
     560 */
     561fibril_timer_state_t fibril_timer_clear(fibril_timer_t *timer)
     562{
     563        fibril_timer_state_t old_state;
     564
     565        fibril_mutex_lock(&timer->lock);
     566        old_state = timer->state;
     567        timer->state = fts_not_set;
     568
     569        timer->delay = 0;
     570        timer->fun = NULL;
     571        timer->arg = NULL;
     572        fibril_condvar_broadcast(&timer->cv);
     573        fibril_mutex_unlock(&timer->lock);
     574
     575        return old_state;
     576}
     577
    449578/** @}
    450579 */
Note: See TracChangeset for help on using the changeset viewer.