Changeset 73f7c4e in mainline


Ignore:
Timestamp:
2019-08-06T18:29:02Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
c2d50c8
Parents:
c1b2084
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-05-24 09:32:10)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-06 18:29:02)
Message:

sysman: Create tests for job control

  • units are mocked by patching virtual methods table
  • sysman_process_queue to enforce emptying event queue

Conflicts:

.bzrignore
boot/Makefile.common

Location:
uspace/srv/sysman
Files:
5 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/sysman/Makefile

    rc1b2084 r73f7c4e  
    3737STATIC_NEEDED = y
    3838
    39 SOURCES = \
     39SYSMAN_SOURCES = \
    4040        configuration.c \
    4141        connection_broker.c \
     
    4343        dep.c \
    4444        job.c \
    45         main.c \
    4645        sysman.c \
    4746        unit.c \
     
    5251        util.c
    5352
     53SOURCES = \
     54        main.c \
     55        $(SYSMAN_SOURCES)
     56
     57TEST_SOURCES = \
     58        $(SYSMAN_SOURCES) \
     59        test/job_closure.c \
     60        test/job_queue.c \
     61        test/mock_unit.c \
     62        test/main.c
     63
    5464include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/sysman/main.c

    rc1b2084 r73f7c4e  
    5959#define UNIT_CFG_INITRD "init.cfg"
    6060
     61
    6162static const char *target_sequence[] = {
    6263        TARGET_INIT,
     
    192193        }
    193194
    194         int rc = sysman_queue_job(tgt, STATE_STARTED, &sequence_job_handler,
     195        int rc = sysman_run_job(tgt, STATE_STARTED, &sequence_job_handler,
    195196            target_name_ptr);
    196197
  • uspace/srv/sysman/sysman.c

    rc1b2084 r73f7c4e  
    6262static LIST_INITIALIZE(event_queue);
    6363static fibril_mutex_t event_queue_mtx;
    64 static fibril_condvar_t event_queue_cv;
     64static fibril_condvar_t event_queue_nonempty_cv;
     65static fibril_condvar_t event_queue_empty_cv;
    6566
    6667static hash_table_t observed_objects;
     
    123124{
    124125        fibril_mutex_initialize(&event_queue_mtx);
    125         fibril_condvar_initialize(&event_queue_cv);
     126        fibril_condvar_initialize(&event_queue_nonempty_cv);
     127        fibril_condvar_initialize(&event_queue_empty_cv);
    126128
    127129        bool table =
     
    141143                fibril_mutex_lock(&event_queue_mtx);
    142144                while (list_empty(&event_queue)) {
    143                         fibril_condvar_wait(&event_queue_cv, &event_queue_mtx);
     145                        fibril_condvar_signal(&event_queue_empty_cv);
     146                        fibril_condvar_wait(&event_queue_nonempty_cv,
     147                            &event_queue_mtx);
    144148                }
    145149
     
    160164/** Create and queue job for unit
    161165 *
     166 * If unit already has the same job assigned callback is set to it.
     167 *
    162168 * @param[in]  callback  (optional) callback must explicitly delete reference
    163  *                       to job
    164  */
    165 int sysman_queue_job(unit_t *unit, unit_state_t target_state,
     169 *                       to job, void callback(void *job, void *callback_arg)
     170 *
     171 * return EBUSY  unit already has a job assigned of different type
     172 */
     173int sysman_run_job(unit_t *unit, unit_state_t target_state,
    166174    callback_handler_t callback, void *callback_arg)
    167175{
    168         job_t *job = job_create(unit, target_state);
    169         if (job == NULL) {
    170                 return ENOMEM;
     176        job_t *job;
     177
     178        if (unit->job != NULL) {
     179                assert(unit->job->state != JOB_UNQUEUED);
     180
     181                if (unit->job->target_state != target_state) {
     182                        return EBUSY;
     183                }
     184                job = unit->job;
     185        } else {
     186                job = job_create(unit, target_state);
     187                if (job == NULL) {
     188                        return ENOMEM;
     189                }
     190                /* Reference in unit is enough */
     191                job_del_ref(&job);
    171192        }
    172193
     
    176197        }
    177198
    178         job_add_ref(job);
    179         sysman_raise_event(&sysman_event_job_process, job);
    180 
    181         job_del_ref(&job);
     199        if (job->state == JOB_UNQUEUED) {
     200                job_add_ref(job);
     201                sysman_raise_event(&sysman_event_job_process, job);
     202        }
     203
    182204        return EOK;
    183205}
     
    199221        list_append(&event->event_queue, &event_queue);
    200222        /* There's only single event loop, broadcast is unnecessary */
    201         fibril_condvar_signal(&event_queue_cv);
     223        fibril_condvar_signal(&event_queue_nonempty_cv);
     224        fibril_mutex_unlock(&event_queue_mtx);
     225}
     226
     227/** Empty current content of event queue
     228 *
     229 * This is potentially blocking call and as long as fibrils are cooperatively
     230 * scheduled, queue will be empty upon return from this function.
     231 */
     232void sysman_process_queue(void)
     233{
     234        fibril_mutex_lock(&event_queue_mtx);
     235        while (!list_empty(&event_queue)) {
     236                fibril_condvar_wait(&event_queue_empty_cv, &event_queue_mtx);
     237        }
    202238        fibril_mutex_unlock(&event_queue_mtx);
    203239}
  • uspace/srv/sysman/sysman.h

    rc1b2084 r73f7c4e  
    3838extern void sysman_events_init(void);
    3939extern int sysman_events_loop(void *);
    40 extern int sysman_queue_job(unit_t *, unit_state_t, callback_handler_t, void *);
     40extern int sysman_run_job(unit_t *, unit_state_t, callback_handler_t, void *);
    4141
    4242
    4343extern void sysman_raise_event(event_handler_t, void *);
     44extern void sysman_process_queue(void);
    4445extern int sysman_object_observer(void *, callback_handler_t, void *);
    4546
Note: See TracChangeset for help on using the changeset viewer.