Subversion Repositories HelenOS

Rev

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)