Changeset 4667b5c in mainline for uspace/srv/taskman/event.c


Ignore:
Timestamp:
2019-08-07T11:10:46Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
bb57a00
Parents:
130ba46
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-11-13 01:56:10)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 11:10:46)
Message:

taskman: Add method to dump events of already running tasks

It's crafted for early startup of sysman.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/taskman/event.c

    r130ba46 r4667b5c  
    4242#include "event.h"
    4343#include "task.h"
     44#include "taskman.h"
    4445
    4546/** Pending task wait structure. */
     
    8586}
    8687
    87 static void event_notify(task_t *sender)
    88 {
    89         // TODO should rlock task_hash_table?
     88static void event_notify(task_t *sender, async_sess_t *sess)
     89{
    9090        int flags = event_flags(sender);
    9191        if (flags == 0) {
     
    9393        }
    9494
     95        async_exch_t *exch = async_exchange_begin(sess);
     96        aid_t req = async_send_5(exch, TASKMAN_EV_TASK,
     97            LOWER32(sender->id),
     98            UPPER32(sender->id),
     99            flags,
     100            sender->exit,
     101            sender->retval,
     102            NULL);
     103
     104        async_exchange_end(exch);
     105
     106        /* Just send a notification and don't wait for anything */
     107        async_forget(req);
     108}
     109
     110/** Notify all registered listeners about sender's event
     111 *
     112 * @note Assumes share lock of task_hash_table is held.
     113 */
     114static void event_notify_all(task_t *sender)
     115{
     116        int flags = event_flags(sender);
     117        if (flags == 0) {
     118                return;
     119        }
     120
    95121        fibril_rwlock_read_lock(&listeners_lock);
    96122        list_foreach(listeners, listeners, task_t, t) {
    97123                assert(t->sess);
    98                 async_exch_t *exch = async_exchange_begin(t->sess);
    99                 aid_t req = async_send_5(exch, TASKMAN_EV_TASK,
    100                     LOWER32(sender->id),
    101                     UPPER32(sender->id),
    102                     flags,
    103                     sender->exit,
    104                     sender->retval,
    105                     NULL);
    106 
    107                 async_exchange_end(exch);
    108 
    109                 /* Just send a notification and don't wait for anything */
    110                 async_forget(req);
     124                event_notify(sender, t->sess);
    111125        }
    112126        fibril_rwlock_read_unlock(&listeners_lock);
     
    195209}
    196210
     211static bool dump_walker(task_t *t, void *arg)
     212{
     213        event_notify(t, arg);
     214        return true;
     215}
     216
     217void dump_events(task_id_t receiver_id, ipc_callid_t iid)
     218{
     219        int rc = EOK;
     220        /*
     221         * We have shared lock of tasks structures so that we can guarantee
     222         * that dump receiver will receive tasks correctly ordered (retval,
     223         * exit updates are serialized via exclusive lock).
     224         */
     225        fibril_rwlock_read_lock(&task_hash_table_lock);
     226
     227        task_t *receiver = task_get_by_id(receiver_id);
     228        if (receiver == NULL) {
     229                rc = ENOENT;
     230                goto finish;
     231        }
     232        if (receiver->sess == NULL) {
     233                rc = ENOENT;
     234                goto finish;
     235        }
     236
     237        /*
     238         * Answer caller first, so that they are not unnecessarily waiting
     239         * while we dump events.
     240         */
     241        async_answer_0(iid, rc);
     242        task_foreach(&dump_walker, receiver->sess);
     243
     244finish:
     245        fibril_rwlock_read_unlock(&task_hash_table_lock);
     246        if (rc != EOK) {
     247                async_answer_0(iid, rc);
     248        }
     249}
     250
    197251void wait_for_task(task_id_t id, int flags, ipc_callid_t callid,
    198252     task_id_t waiter_id)
     
    284338        t->retval_type = wait_for_exit ? RVAL_SET_EXIT : RVAL_SET;
    285339       
    286         event_notify(t);
     340        event_notify_all(t);
    287341        process_pending_wait();
    288342       
     
    313367        }
    314368
    315         event_notify(t);
    316         process_pending_wait();
    317 
    318         hash_table_remove_item(&task_hash_table, &t->link);
    319 
     369        /*
     370         * First remove terminated task from listeners and only after that
     371         * notify all others.
     372         */
    320373        fibril_rwlock_write_lock(&listeners_lock);
    321374        list_remove(&t->listeners);
    322375        fibril_rwlock_write_unlock(&listeners_lock);
     376
     377        event_notify_all(t);
     378        process_pending_wait();
     379
     380        /* Eventually, get rid of task_t. */
     381        task_remove(&t);
    323382
    324383finish:
Note: See TracChangeset for help on using the changeset viewer.