Rev 4618 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4618 | Rev 4619 | ||
---|---|---|---|
Line 46... | Line 46... | ||
46 | 46 | ||
47 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id); |
47 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id); |
48 | 48 | ||
49 | /* TODO: |
49 | /* TODO: |
50 | * |
50 | * |
51 | * The current implementation of waiting on a task is not perfect. If somebody |
- | |
52 | * The caller has to make sure that it is not trying to wait |
- | |
53 | * before the NS has a change to receive the task creation notification. This |
- | |
54 | * can be assured by waiting for this event in task_spawn(). |
- | |
55 | * |
- | |
56 | * Finally, as there is currently no convention that each task has to be waited |
51 | * As there is currently no convention that each task has to be waited |
57 | * for, the NS can leak memory because of the zombie tasks. |
52 | * for, the NS can leak memory because of the zombie tasks. |
58 | * |
53 | * |
59 | */ |
54 | */ |
60 | 55 | ||
61 | /** Task hash table item. */ |
56 | /** Task hash table item. */ |
Line 205... | Line 200... | ||
205 | 1, &p2i_ops)) { |
200 | 1, &p2i_ops)) { |
206 | printf(NAME ": No memory available for tasks\n"); |
201 | printf(NAME ": No memory available for tasks\n"); |
207 | return ENOMEM; |
202 | return ENOMEM; |
208 | } |
203 | } |
209 | 204 | ||
210 | if (event_subscribe(EVENT_WAIT, 0) != EOK) |
- | |
211 | printf(NAME ": Error registering wait notifications\n"); |
- | |
212 | - | ||
213 | list_initialize(&pending_wait); |
205 | list_initialize(&pending_wait); |
214 | 206 | ||
215 | return EOK; |
207 | return EOK; |
216 | } |
208 | } |
217 | 209 | ||
Line 245... | Line 237... | ||
245 | free(pr); |
237 | free(pr); |
246 | goto loop; |
238 | goto loop; |
247 | } |
239 | } |
248 | } |
240 | } |
249 | 241 | ||
250 | static void fail_pending_wait(task_id_t id, int rc) |
- | |
251 | { |
- | |
252 | link_t *cur; |
- | |
253 | - | ||
254 | loop: |
- | |
255 | for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) { |
- | |
256 | pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); |
- | |
257 | - | ||
258 | if (pr->id == id) { |
- | |
259 | if (!(pr->callid & IPC_CALLID_NOTIFICATION)) |
- | |
260 | ipc_answer_0(pr->callid, rc); |
- | |
261 | - | ||
262 | list_remove(cur); |
- | |
263 | free(pr); |
- | |
264 | goto loop; |
- | |
265 | } |
- | |
266 | } |
- | |
267 | } |
- | |
268 | - | ||
269 | void wait_notification(wait_type_t et, task_id_t id) |
- | |
270 | { |
- | |
271 | unsigned long keys[2] = { |
- | |
272 | LOWER32(id), |
- | |
273 | UPPER32(id) |
- | |
274 | }; |
- | |
275 | - | ||
276 | link_t *link = hash_table_find(&task_hash_table, keys); |
- | |
277 | - | ||
278 | if (link == NULL) { |
- | |
279 | hashed_task_t *ht = |
- | |
280 | (hashed_task_t *) malloc(sizeof(hashed_task_t)); |
- | |
281 | if (ht == NULL) { |
- | |
282 | fail_pending_wait(id, ENOMEM); |
- | |
283 | return; |
- | |
284 | } |
- | |
285 | - | ||
286 | link_initialize(&ht->link); |
- | |
287 | ht->id = id; |
- | |
288 | ht->destroyed = (et == TASK_CREATE) ? false : true; |
- | |
289 | ht->retval = -1; |
- | |
290 | hash_table_insert(&task_hash_table, keys, &ht->link); |
- | |
291 | } else { |
- | |
292 | hashed_task_t *ht = |
- | |
293 | hash_table_get_instance(link, hashed_task_t, link); |
- | |
294 | ht->destroyed = (et == TASK_CREATE) ? false : true; |
- | |
295 | } |
- | |
296 | } |
- | |
297 | - | ||
298 | void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid) |
242 | void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid) |
299 | { |
243 | { |
300 | ipcarg_t retval; |
244 | ipcarg_t retval; |
301 | unsigned long keys[2] = { |
245 | unsigned long keys[2] = { |
302 | LOWER32(id), |
246 | LOWER32(id), |
Line 306... | Line 250... | ||
306 | link_t *link = hash_table_find(&task_hash_table, keys); |
250 | link_t *link = hash_table_find(&task_hash_table, keys); |
307 | hashed_task_t *ht = (link != NULL) ? |
251 | hashed_task_t *ht = (link != NULL) ? |
308 | hash_table_get_instance(link, hashed_task_t, link) : NULL; |
252 | hash_table_get_instance(link, hashed_task_t, link) : NULL; |
309 | 253 | ||
310 | if (ht == NULL) { |
254 | if (ht == NULL) { |
- | 255 | /* No such task exists. */ |
|
311 | retval = ENOENT; |
256 | retval = ENOENT; |
312 | goto out; |
257 | goto out; |
313 | } |
258 | } |
314 | 259 | ||
315 | if (!ht->destroyed) { |
260 | if (!ht->destroyed) { |
Line 336... | Line 281... | ||
336 | } |
281 | } |
337 | 282 | ||
338 | int ns_task_id_intro(ipc_call_t *call) |
283 | int ns_task_id_intro(ipc_call_t *call) |
339 | { |
284 | { |
340 | task_id_t id; |
285 | task_id_t id; |
341 | unsigned long keys[1]; |
286 | unsigned long keys[2]; |
342 | link_t *link; |
287 | link_t *link; |
343 | p2i_entry_t *e; |
288 | p2i_entry_t *e; |
- | 289 | hashed_task_t *ht; |
|
344 | 290 | ||
345 | id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); |
291 | id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); |
346 | 292 | ||
347 | keys[0] = call->in_phone_hash; |
293 | keys[0] = call->in_phone_hash; |
348 | 294 | ||
Line 352... | Line 298... | ||
352 | 298 | ||
353 | e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t)); |
299 | e = (p2i_entry_t *) malloc(sizeof(p2i_entry_t)); |
354 | if (e == NULL) |
300 | if (e == NULL) |
355 | return ENOMEM; |
301 | return ENOMEM; |
356 | 302 | ||
- | 303 | ht = (hashed_task_t *) malloc(sizeof(hashed_task_t)); |
|
- | 304 | if (ht == NULL) |
|
- | 305 | return ENOMEM; |
|
- | 306 | ||
- | 307 | /* Insert to phone-to-id map. */ |
|
- | 308 | ||
357 | link_initialize(&e->link); |
309 | link_initialize(&e->link); |
358 | e->phash = call->in_phone_hash; |
310 | e->phash = call->in_phone_hash; |
359 | e->id = id; |
311 | e->id = id; |
360 | hash_table_insert(&phone_to_id, keys, &e->link); |
312 | hash_table_insert(&phone_to_id, keys, &e->link); |
361 | 313 | ||
- | 314 | /* Insert to main table. */ |
|
- | 315 | ||
- | 316 | keys[0] = LOWER32(id); |
|
- | 317 | keys[1] = UPPER32(id); |
|
- | 318 | ||
- | 319 | link_initialize(&ht->link); |
|
- | 320 | ht->id = id; |
|
- | 321 | ht->destroyed = false; |
|
- | 322 | ht->retval = -1; |
|
- | 323 | hash_table_insert(&task_hash_table, keys, &ht->link); |
|
- | 324 | ||
362 | return EOK; |
325 | return EOK; |
363 | } |
326 | } |
364 | 327 | ||
365 | int ns_task_retval(ipc_call_t *call) |
328 | int ns_task_retval(ipc_call_t *call) |
366 | { |
329 | { |
Line 387... | Line 350... | ||
387 | return EOK; |
350 | return EOK; |
388 | } |
351 | } |
389 | 352 | ||
390 | int ns_task_disconnect(ipc_call_t *call) |
353 | int ns_task_disconnect(ipc_call_t *call) |
391 | { |
354 | { |
392 | unsigned long keys[1]; |
355 | unsigned long keys[2]; |
- | 356 | task_id_t id; |
|
- | 357 | int rc; |
|
393 | 358 | ||
- | 359 | rc = get_id_by_phone(call->in_phone_hash, &id); |
|
- | 360 | if (rc != EOK) |
|
- | 361 | return rc; |
|
- | 362 | ||
- | 363 | /* Delete from phone-to-id map. */ |
|
394 | keys[0] = call->in_phone_hash; |
364 | keys[0] = call->in_phone_hash; |
395 | hash_table_remove(&phone_to_id, keys, 1); |
365 | hash_table_remove(&phone_to_id, keys, 1); |
- | 366 | ||
- | 367 | /* Mark task as finished. */ |
|
- | 368 | keys[0] = LOWER32(id); |
|
- | 369 | keys[1] = UPPER32(id); |
|
396 | 370 | ||
- | 371 | link_t *link = hash_table_find(&task_hash_table, keys); |
|
- | 372 | hashed_task_t *ht = |
|
- | 373 | hash_table_get_instance(link, hashed_task_t, link); |
|
- | 374 | assert(ht != NULL); |
|
- | 375 | ||
- | 376 | ht->destroyed = true; |
|
- | 377 | ||
397 | return EOK; |
378 | return EOK; |
398 | } |
379 | } |
399 | 380 | ||
400 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id) |
381 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id) |
401 | { |
382 | { |