Changeset 53f68fd in mainline


Ignore:
Timestamp:
2014-07-08T21:42:35Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8f0dc26
Parents:
df2e621c
Message:

fibril_timer_func() must examine timer state each time it reacquires timer lock after cv_wait.

Location:
uspace/lib/c
Files:
2 edited

Legend:

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

    rdf2e621c r53f68fd  
    450450        fibril_mutex_lock(&timer->lock);
    451451
    452         while (true) {
    453                 while (timer->state != fts_active &&
    454                     timer->state != fts_cleanup) {
    455 
    456                         if (timer->state == fts_cleanup)
    457                                 break;
    458 
     452        while (timer->state != fts_cleanup) {
     453                switch (timer->state) {
     454                case fts_not_set:
     455                case fts_fired:
    459456                        fibril_condvar_wait(&timer->cv, &timer->lock);
     457                        break;
     458                case fts_active:
     459                        rc = fibril_condvar_wait_timeout(&timer->cv,
     460                            &timer->lock, timer->delay);
     461                        if (rc == ETIMEOUT && timer->state == fts_active) {
     462                                timer->state = fts_fired;
     463                                fibril_mutex_unlock(&timer->lock);
     464                                timer->fun(timer->arg);
     465                                fibril_mutex_lock(&timer->lock);
     466                        }
     467                        break;
     468                case fts_cleanup:
     469                case fts_clean:
     470                        assert(false);
     471                        break;
    460472                }
    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 
     473        }
     474
     475        /* Acknowledge timer fibril has finished cleanup. */
     476        timer->state = fts_clean;
    475477        fibril_mutex_unlock(&timer->lock);
     478
    476479        return 0;
    477480}
     
    514517{
    515518        fibril_mutex_lock(&timer->lock);
    516         assert(timer->state != fts_active);
     519        assert(timer->state == fts_not_set || timer->state == fts_fired);
     520
     521        /* Request timer fibril to terminate. */
    517522        timer->state = fts_cleanup;
    518523        fibril_condvar_broadcast(&timer->cv);
     524
     525        /* Wait for timer fibril to acknowledge. */
     526        while (timer->state != fts_clean)
     527                fibril_condvar_wait(&timer->cv, &timer->lock);
     528
    519529        fibril_mutex_unlock(&timer->lock);
    520530}
     
    534544{
    535545        fibril_mutex_lock(&timer->lock);
     546        assert(timer->state == fts_not_set || timer->state == fts_fired);
    536547        timer->state = fts_active;
    537548        timer->delay = delay;
  • uspace/lib/c/include/fibril_synch.h

    rdf2e621c r53f68fd  
    116116        /** Timer has fired and has not been cleared since */
    117117        fts_fired,
    118         /** Timer is being destroyed */
    119         fts_cleanup
     118        /** Timer fibril is requested to terminate */
     119        fts_cleanup,
     120        /** Timer fibril acknowledged termination */
     121        fts_clean
    120122} fibril_timer_state_t;
    121123
Note: See TracChangeset for help on using the changeset viewer.