Subversion Repositories HelenOS

Rev

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
{