Rev 4619 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4619 | Rev 4620 | ||
|---|---|---|---|
| Line 54... | Line 54... | ||
| 54 | */ |
54 | */ |
| 55 | 55 | ||
| 56 | /** Task hash table item. */ |
56 | /** Task hash table item. */ |
| 57 | typedef struct { |
57 | typedef struct { |
| 58 | link_t link; |
58 | link_t link; |
| 59 | task_id_t id; /**< Task ID. */ |
59 | task_id_t id; /**< Task ID. */ |
| 60 | int retval; |
60 | bool finished; /**< Task is done. */ |
| - | 61 | bool have_rval; /**< Task returned a value. */ |
|
| 61 | bool destroyed; |
62 | int retval; /**< The return value. */ |
| 62 | } hashed_task_t; |
63 | } hashed_task_t; |
| 63 | 64 | ||
| 64 | /** Compute hash index into task hash table. |
65 | /** Compute hash index into task hash table. |
| 65 | * |
66 | * |
| 66 | * @param key Pointer keys. However, only the first key (i.e. truncated task |
67 | * @param key Pointer keys. However, only the first key (i.e. truncated task |
| Line 209... | Line 210... | ||
| 209 | 210 | ||
| 210 | /** Process pending wait requests */ |
211 | /** Process pending wait requests */ |
| 211 | void process_pending_wait(void) |
212 | void process_pending_wait(void) |
| 212 | { |
213 | { |
| 213 | link_t *cur; |
214 | link_t *cur; |
| - | 215 | task_exit_t texit; |
|
| 214 | 216 | ||
| 215 | loop: |
217 | loop: |
| 216 | for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) { |
218 | for (cur = pending_wait.next; cur != &pending_wait; cur = cur->next) { |
| 217 | pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); |
219 | pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); |
| 218 | 220 | ||
| Line 224... | Line 226... | ||
| 224 | link_t *link = hash_table_find(&task_hash_table, keys); |
226 | link_t *link = hash_table_find(&task_hash_table, keys); |
| 225 | if (!link) |
227 | if (!link) |
| 226 | continue; |
228 | continue; |
| 227 | 229 | ||
| 228 | hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link); |
230 | hashed_task_t *ht = hash_table_get_instance(link, hashed_task_t, link); |
| 229 | if (!ht->destroyed) |
231 | if (!ht->finished) |
| 230 | continue; |
232 | continue; |
| 231 | 233 | ||
| 232 | if (!(pr->callid & IPC_CALLID_NOTIFICATION)) |
234 | if (!(pr->callid & IPC_CALLID_NOTIFICATION)) { |
| - | 235 | texit = ht->have_rval ? TASK_EXIT_NORMAL : |
|
| - | 236 | TASK_EXIT_UNEXPECTED; |
|
| 233 | ipc_answer_1(pr->callid, EOK, ht->retval); |
237 | ipc_answer_2(pr->callid, EOK, texit, |
| - | 238 | ht->retval); |
|
| 234 | 239 | } |
|
| - | 240 | ||
| 235 | hash_table_remove(&task_hash_table, keys, 2); |
241 | hash_table_remove(&task_hash_table, keys, 2); |
| 236 | list_remove(cur); |
242 | list_remove(cur); |
| 237 | free(pr); |
243 | free(pr); |
| 238 | goto loop; |
244 | goto loop; |
| 239 | } |
245 | } |
| 240 | } |
246 | } |
| 241 | 247 | ||
| 242 | void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid) |
248 | void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid) |
| 243 | { |
249 | { |
| 244 | ipcarg_t retval; |
250 | ipcarg_t retval; |
| - | 251 | task_exit_t texit; |
|
| - | 252 | ||
| 245 | unsigned long keys[2] = { |
253 | unsigned long keys[2] = { |
| 246 | LOWER32(id), |
254 | LOWER32(id), |
| 247 | UPPER32(id) |
255 | UPPER32(id) |
| 248 | }; |
256 | }; |
| 249 | 257 | ||
| Line 255... | Line 263... | ||
| 255 | /* No such task exists. */ |
263 | /* No such task exists. */ |
| 256 | retval = ENOENT; |
264 | retval = ENOENT; |
| 257 | goto out; |
265 | goto out; |
| 258 | } |
266 | } |
| 259 | 267 | ||
| 260 | if (!ht->destroyed) { |
268 | if (!ht->finished) { |
| 261 | /* Add to pending list */ |
269 | /* Add to pending list */ |
| 262 | pending_wait_t *pr = |
270 | pending_wait_t *pr = |
| 263 | (pending_wait_t *) malloc(sizeof(pending_wait_t)); |
271 | (pending_wait_t *) malloc(sizeof(pending_wait_t)); |
| 264 | if (!pr) { |
272 | if (!pr) { |
| 265 | retval = ENOMEM; |
273 | retval = ENOMEM; |
| Line 274... | Line 282... | ||
| 274 | 282 | ||
| 275 | hash_table_remove(&task_hash_table, keys, 2); |
283 | hash_table_remove(&task_hash_table, keys, 2); |
| 276 | retval = EOK; |
284 | retval = EOK; |
| 277 | 285 | ||
| 278 | out: |
286 | out: |
| 279 | if (!(callid & IPC_CALLID_NOTIFICATION)) |
287 | if (!(callid & IPC_CALLID_NOTIFICATION)) { |
| - | 288 | texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED; |
|
| 280 | ipc_answer_1(callid, retval, ht->retval); |
289 | ipc_answer_2(callid, retval, texit, ht->retval); |
| - | 290 | } |
|
| 281 | } |
291 | } |
| 282 | 292 | ||
| 283 | int ns_task_id_intro(ipc_call_t *call) |
293 | int ns_task_id_intro(ipc_call_t *call) |
| 284 | { |
294 | { |
| 285 | task_id_t id; |
295 | task_id_t id; |
| Line 316... | Line 326... | ||
| 316 | keys[0] = LOWER32(id); |
326 | keys[0] = LOWER32(id); |
| 317 | keys[1] = UPPER32(id); |
327 | keys[1] = UPPER32(id); |
| 318 | 328 | ||
| 319 | link_initialize(&ht->link); |
329 | link_initialize(&ht->link); |
| 320 | ht->id = id; |
330 | ht->id = id; |
| 321 | ht->destroyed = false; |
331 | ht->finished = false; |
| - | 332 | ht->have_rval = false; |
|
| 322 | ht->retval = -1; |
333 | ht->retval = -1; |
| 323 | hash_table_insert(&task_hash_table, keys, &ht->link); |
334 | hash_table_insert(&task_hash_table, keys, &ht->link); |
| 324 | 335 | ||
| 325 | return EOK; |
336 | return EOK; |
| 326 | } |
337 | } |
| Line 340... | Line 351... | ||
| 340 | 351 | ||
| 341 | link_t *link = hash_table_find(&task_hash_table, keys); |
352 | link_t *link = hash_table_find(&task_hash_table, keys); |
| 342 | hashed_task_t *ht = (link != NULL) ? |
353 | hashed_task_t *ht = (link != NULL) ? |
| 343 | hash_table_get_instance(link, hashed_task_t, link) : NULL; |
354 | hash_table_get_instance(link, hashed_task_t, link) : NULL; |
| 344 | 355 | ||
| 345 | if ((ht == NULL) || ht->destroyed) |
356 | if ((ht == NULL) || ht->finished) |
| 346 | return EINVAL; |
357 | return EINVAL; |
| 347 | 358 | ||
| - | 359 | ht->finished = true; |
|
| - | 360 | ht->have_rval = true; |
|
| 348 | ht->retval = IPC_GET_ARG1(*call); |
361 | ht->retval = IPC_GET_ARG1(*call); |
| 349 | 362 | ||
| 350 | return EOK; |
363 | return EOK; |
| 351 | } |
364 | } |
| 352 | 365 | ||
| Line 369... | Line 382... | ||
| 369 | keys[1] = UPPER32(id); |
382 | keys[1] = UPPER32(id); |
| 370 | 383 | ||
| 371 | link_t *link = hash_table_find(&task_hash_table, keys); |
384 | link_t *link = hash_table_find(&task_hash_table, keys); |
| 372 | hashed_task_t *ht = |
385 | hashed_task_t *ht = |
| 373 | hash_table_get_instance(link, hashed_task_t, link); |
386 | hash_table_get_instance(link, hashed_task_t, link); |
| 374 | assert(ht != NULL); |
387 | if (ht == NULL) |
| - | 388 | return EOK; |
|
| 375 | 389 | ||
| 376 | ht->destroyed = true; |
390 | ht->finished = true; |
| 377 | 391 | ||
| 378 | return EOK; |
392 | return EOK; |
| 379 | } |
393 | } |
| 380 | 394 | ||
| 381 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id) |
395 | static int get_id_by_phone(ipcarg_t phone_hash, task_id_t *id) |