Changeset 4667b5c in mainline for uspace/srv/taskman/event.c
- Timestamp:
- 2019-08-07T11:10:46Z (5 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/taskman/event.c
r130ba46 r4667b5c 42 42 #include "event.h" 43 43 #include "task.h" 44 #include "taskman.h" 44 45 45 46 /** Pending task wait structure. */ … … 85 86 } 86 87 87 static void event_notify(task_t *sender) 88 { 89 // TODO should rlock task_hash_table? 88 static void event_notify(task_t *sender, async_sess_t *sess) 89 { 90 90 int flags = event_flags(sender); 91 91 if (flags == 0) { … … 93 93 } 94 94 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 */ 114 static void event_notify_all(task_t *sender) 115 { 116 int flags = event_flags(sender); 117 if (flags == 0) { 118 return; 119 } 120 95 121 fibril_rwlock_read_lock(&listeners_lock); 96 122 list_foreach(listeners, listeners, task_t, t) { 97 123 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); 111 125 } 112 126 fibril_rwlock_read_unlock(&listeners_lock); … … 195 209 } 196 210 211 static bool dump_walker(task_t *t, void *arg) 212 { 213 event_notify(t, arg); 214 return true; 215 } 216 217 void 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 244 finish: 245 fibril_rwlock_read_unlock(&task_hash_table_lock); 246 if (rc != EOK) { 247 async_answer_0(iid, rc); 248 } 249 } 250 197 251 void wait_for_task(task_id_t id, int flags, ipc_callid_t callid, 198 252 task_id_t waiter_id) … … 284 338 t->retval_type = wait_for_exit ? RVAL_SET_EXIT : RVAL_SET; 285 339 286 event_notify (t);340 event_notify_all(t); 287 341 process_pending_wait(); 288 342 … … 313 367 } 314 368 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 */ 320 373 fibril_rwlock_write_lock(&listeners_lock); 321 374 list_remove(&t->listeners); 322 375 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); 323 382 324 383 finish:
Note:
See TracChangeset
for help on using the changeset viewer.