Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/kbox.c

    r07d4271 rfafb8e5  
    9090                LOG("Join kb.thread.");
    9191                thread_join(TASK->kb.thread);
     92                thread_detach(TASK->kb.thread);
    9293                LOG("...join done.");
    9394                TASK->kb.thread = NULL;
     
    135136                /* Only detach kbox thread unless already terminating. */
    136137                if (TASK->kb.finished == false) {
    137                         /* Release kbox thread so it gets freed from memory. */
    138                         thread_put(TASK->kb.thread);
     138                        /* Detach kbox thread so it gets freed from memory. */
     139                        thread_detach(TASK->kb.thread);
    139140                        TASK->kb.thread = NULL;
    140141                }
     
    200201/** Connect phone to a task kernel-box specified by id.
    201202 *
     203 * Note that this is not completely atomic. For optimisation reasons, the task
     204 * might start cleaning up kbox after the phone has been connected and before
     205 * a kbox thread has been created. This must be taken into account in the
     206 * cleanup code.
     207 *
    202208 * @param[out] out_phone  Phone capability handle on success.
    203209 * @return Error code.
     
    206212errno_t ipc_connect_kbox(task_id_t taskid, cap_phone_handle_t *out_phone)
    207213{
     214        irq_spinlock_lock(&tasks_lock, true);
     215
    208216        task_t *task = task_find_by_id(taskid);
    209         if (!task)
     217        if (task == NULL) {
     218                irq_spinlock_unlock(&tasks_lock, true);
    210219                return ENOENT;
     220        }
     221
     222        atomic_inc(&task->refcount);
     223
     224        irq_spinlock_unlock(&tasks_lock, true);
    211225
    212226        mutex_lock(&task->kb.cleanup_lock);
     227
     228        if (atomic_predec(&task->refcount) == 0) {
     229                mutex_unlock(&task->kb.cleanup_lock);
     230                task_destroy(task);
     231                return ENOENT;
     232        }
    213233
    214234        if (task->kb.finished) {
    215235                mutex_unlock(&task->kb.cleanup_lock);
    216                 task_release(task);
    217236                return EINVAL;
    218237        }
     
    225244                if (!kb_thread) {
    226245                        mutex_unlock(&task->kb.cleanup_lock);
    227                         task_release(task);
    228246                        return ENOMEM;
    229247                }
    230248
    231249                task->kb.thread = kb_thread;
    232                 thread_start(kb_thread);
     250                thread_ready(kb_thread);
    233251        }
    234252
     
    238256        if (rc != EOK) {
    239257                mutex_unlock(&task->kb.cleanup_lock);
    240                 task_release(task);
    241258                return rc;
    242259        }
     
    249266
    250267        mutex_unlock(&task->kb.cleanup_lock);
    251         task_release(task);
    252268        *out_phone = phone_handle;
    253269        return EOK;
Note: See TracChangeset for help on using the changeset viewer.