Changeset 1c635d6 in mainline for uspace/srv/ns/task.c


Ignore:
Timestamp:
2014-08-26T15:12:12Z (11 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
613d644
Parents:
df7f5cea
Message:

Do not hold a task's return value after it has disconnected.

Holding the task's return value meant that if nobody waited
for task's result, it polluted NS's memory. This was apparently
done because of a race between spawning a task and waiting for it.

We solve this problem in another way: ns discards the return value
as soon as the task disconnects from it. This typically happens
when the task finishes its execution. In order to avoid the race,
we send the wait request to ns while spawning the task (i.e. when
we talk to the loader), but before we allow the loaded program
to run.

Fixes #132

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/ns/task.c

    rdf7f5cea r1c635d6  
    4040#include <macros.h>
    4141#include <malloc.h>
     42#include <types/task.h>
    4243#include "task.h"
    4344#include "ns.h"
    4445
    45 
    46 /* TODO:
    47  *
    48  * As there is currently no convention that each task has to be waited
    49  * for, the NS can leak memory because of the zombie tasks.
    50  *
    51  */
    5246
    5347/** Task hash table item. */
     
    195189                }
    196190               
    197                 hash_table_remove(&task_hash_table, &pr->id);
    198191                list_remove(&pr->link);
    199192                free(pr);
     
    204197void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
    205198{
    206         sysarg_t retval;
    207         task_exit_t texit;
    208         bool remove = false;
    209        
    210199        ht_link_t *link = hash_table_find(&task_hash_table, &id);
    211200        hashed_task_t *ht = (link != NULL) ?
     
    218207        }
    219208       
    220         if (!ht->finished) {
    221                 /* Add to pending list */
    222                 pending_wait_t *pr =
    223                     (pending_wait_t *) malloc(sizeof(pending_wait_t));
    224                 if (!pr) {
    225                         retval = ENOMEM;
    226                         goto out;
    227                 }
    228                
    229                 link_initialize(&pr->link);
    230                 pr->id = id;
    231                 pr->callid = callid;
    232                 list_append(&pr->link, &pending_wait);
     209        if (ht->finished) {
     210                task_exit_t texit = ht->have_rval ? TASK_EXIT_NORMAL :
     211                    TASK_EXIT_UNEXPECTED;
     212                ipc_answer_2(callid, EOK, texit, ht->retval);
    233213                return;
    234214        }
    235215       
    236         remove = true;
    237         retval = EOK;
    238        
    239 out:
    240         if (!(callid & IPC_CALLID_NOTIFICATION)) {
    241                 texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED;
    242                 ipc_answer_2(callid, retval, texit, ht->retval);
    243         }
    244         if (remove)
    245                 hash_table_remove_item(&task_hash_table, link);
     216        /* Add to pending list */
     217        pending_wait_t *pr =
     218            (pending_wait_t *) malloc(sizeof(pending_wait_t));
     219        if (!pr) {
     220                if (!(callid & IPC_CALLID_NOTIFICATION))
     221                        ipc_answer_0(callid, ENOMEM);
     222                return;
     223        }
     224       
     225        link_initialize(&pr->link);
     226        pr->id = id;
     227        pr->callid = callid;
     228        list_append(&pr->link, &pending_wait);
    246229}
    247230
     
    314297        ht->retval = IPC_GET_ARG1(*call);
    315298       
     299        process_pending_wait();
     300       
    316301        return EOK;
    317302}
     
    336321        ht->finished = true;
    337322       
     323        process_pending_wait();
     324        hash_table_remove(&task_hash_table, &id);
     325       
    338326        return EOK;
    339327}
Note: See TracChangeset for help on using the changeset viewer.