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 | { |