Changeset c77cfd8 in mainline for uspace/app/taskbar/clock.c


Ignore:
Timestamp:
2022-10-04T19:55:25Z (17 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e0e612b
Parents:
3fd38b2
Message:

Proper timer cleanup, unit tests

Destroying a timer that sets itself again (i.e., runs periodically) is
a little tricky. It requires a handshake (similar to destroying a worker
thread). Realizing that this handshake works correctly is a little bit
mind boggling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/taskbar/clock.c

    r3fd38b2 rc77cfd8  
    8989        }
    9090
     91        fibril_mutex_initialize(&clock->lock);
     92        fibril_condvar_initialize(&clock->timer_done_cv);
    9193        fibril_timer_set(clock->timer, 1000000, taskbar_clock_timer, clock);
    9294
     
    106108void taskbar_clock_destroy(taskbar_clock_t *clock)
    107109{
     110        /*
     111         * Signal to the timer that we are cleaning up. If the timer handler
     112         * misses it and sets the timer again, we will clear that active
     113         * timer and be done (and if we were even slower and the timer
     114         * fired again, it's the same situation as before.
     115         */
     116        fibril_mutex_lock(&clock->lock);
     117        clock->timer_cleanup = true;
     118        fibril_mutex_unlock(&clock->lock);
     119
     120        /* If we catch the timer while it's active, there's nothing to do. */
     121        if (fibril_timer_clear(clock->timer) != fts_active) {
     122                /* Need to wait for timer handler to finish */
     123                fibril_mutex_lock(&clock->lock);
     124                while (clock->timer_done == false)
     125                        fibril_condvar_wait(&clock->timer_done_cv, &clock->lock);
     126                fibril_mutex_unlock(&clock->lock);
     127        }
     128
    108129        fibril_timer_destroy(clock->timer);
    109130        ui_control_delete(clock->control);
     
    302323        taskbar_clock_t *clock = (taskbar_clock_t *) arg;
    303324
     325        fibril_mutex_lock(&clock->lock);
    304326        (void) taskbar_clock_paint(clock);
    305         fibril_timer_set(clock->timer, 1000000, taskbar_clock_timer, clock);
     327
     328        if (!clock->timer_cleanup) {
     329                fibril_timer_set(clock->timer, 1000000, taskbar_clock_timer,
     330                    clock);
     331        } else {
     332                /* Acknowledge timer cleanup */
     333                clock->timer_done = true;
     334                fibril_condvar_signal(&clock->timer_done_cv);
     335        }
     336
     337        fibril_mutex_unlock(&clock->lock);
    306338}
    307339
Note: See TracChangeset for help on using the changeset viewer.