Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/bdsh/exec.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -97,4 +97,5 @@
 {
 	task_id_t tid;
+	task_wait_t twait;
 	task_exit_t texit;
 	char *tmp;
@@ -121,5 +122,5 @@
 	file_handles_p[i] = NULL;
 
-	rc = task_spawnvf(&tid, tmp, (const char **) argv, file_handles_p);
+	rc = task_spawnvf(&tid, &twait, tmp, (const char **) argv, file_handles_p);
 	free(tmp);
 
@@ -130,5 +131,5 @@
 	}
 	
-	rc = task_wait(tid, &texit, &retval);
+	rc = task_wait(&twait, &texit, &retval);
 	if (rc != EOK) {
 		printf("%s: Failed waiting for command (%s)\n", progname,
Index: uspace/app/getterm/getterm.c
===================================================================
--- uspace/app/getterm/getterm.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/getterm/getterm.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -165,6 +165,7 @@
 	
 	task_id_t id;
+	task_wait_t twait;
 	
-	int rc = task_spawnv(&id, cmd, (const char * const *) args);
+	int rc = task_spawnv(&id, &twait, cmd, (const char * const *) args);
 	if (rc != EOK) {
 		printf("%s: Error spawning %s (%s)\n", APP_NAME, cmd,
@@ -175,5 +176,5 @@
 	task_exit_t texit;
 	int retval;
-	rc = task_wait(id, &texit, &retval);
+	rc = task_wait(&twait, &texit, &retval);
 	if (rc != EOK) {
 		printf("%s: Error waiting for %s (%s)\n", APP_NAME, cmd,
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/init/init.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -172,5 +172,6 @@
 	va_start(ap, path);
 	task_id_t id;
-	int rc = task_spawn(&id, path, cnt, ap);
+	task_wait_t wait;
+	int rc = task_spawn(&id, &wait, path, cnt, ap);
 	va_end(ap);
 	
@@ -189,5 +190,5 @@
 	task_exit_t texit;
 	int retval;
-	rc = task_wait(id, &texit, &retval);
+	rc = task_wait(&wait, &texit, &retval);
 	if (rc != EOK) {
 		printf("%s: Error waiting for %s (%s)\n", NAME, path,
@@ -253,5 +254,6 @@
 	
 	task_id_t id;
-	int rc = task_spawnl(&id, app, app, winreg, NULL);
+	task_wait_t wait;
+	int rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
 	if (rc != EOK) {
 		printf("%s: Error spawning %s %s (%s)\n", NAME, app,
@@ -262,5 +264,5 @@
 	task_exit_t texit;
 	int retval;
-	rc = task_wait(id, &texit, &retval);
+	rc = task_wait(&wait, &texit, &retval);
 	if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
 		printf("%s: Error retrieving retval from %s (%s)\n", NAME,
@@ -278,5 +280,5 @@
 		    APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
 		
-		int rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, svc,
+		int rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
 		    LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL);
 		if (rc != EOK)
@@ -287,5 +289,5 @@
 		    APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
 		
-		int rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, svc,
+		int rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
 		    LOCFS_MOUNT_POINT, "--wait", "--", app, NULL);
 		if (rc != EOK)
Index: uspace/app/redir/redir.c
===================================================================
--- uspace/app/redir/redir.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/redir/redir.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -75,5 +75,5 @@
 }
 
-static task_id_t spawn(int argc, char *argv[])
+static task_id_t spawn(task_wait_t *wait, int argc, char *argv[])
 {
 	const char **args;
@@ -93,5 +93,5 @@
 	args[argc] = NULL;
 	
-	rc = task_spawnv(&id, argv[0], args);
+	rc = task_spawnv(&id, wait, argv[0], args);
 	
 	free(args);
@@ -152,11 +152,12 @@
 	 */
 	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
-	
-	task_id_t id = spawn(argc - i, argv + i);
+
+	task_wait_t wait;	
+	task_id_t id = spawn(&wait, argc - i, argv + i);
 	
 	if (id != 0) {
 		task_exit_t texit;
 		int retval;
-		task_wait(id, &texit, &retval);
+		task_wait(&wait, &texit, &retval);
 		
 		return retval;
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/sbi/src/os/helenos.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -250,8 +250,9 @@
 {
 	task_id_t tid;
+	task_wait_t twait;
 	task_exit_t texit;
 	int rc, retval;
 
-	rc = task_spawnv(&tid, cmd[0], (char const * const *) cmd);
+	rc = task_spawnv(&tid, &twait, cmd[0], (char const * const *) cmd);
 	if (rc != EOK) {
 		printf("Error: Failed spawning '%s' (%s).\n", cmd[0],
@@ -261,5 +262,5 @@
 
 	/* XXX Handle exit status and return value. */
-	rc = task_wait(tid, &texit, &retval);
+	rc = task_wait(&twait, &texit, &retval);
 	(void) rc;
 
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/trace/trace.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -876,5 +876,5 @@
 		printf("Waiting for task to exit.\n");
 
-		rc = task_wait(task_id, &texit, &retval);
+		rc = task_wait_task_id(task_id, &texit, &retval);
 		if (rc != EOK) {
 			printf("Failed waiting for task.\n");
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/viewer/viewer.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -44,4 +44,5 @@
 #include <surface.h>
 #include <codec/tga.h>
+#include <task.h>
 
 #define NAME  "viewer"
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/app/vlaunch/vlaunch.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -94,5 +94,6 @@
 	
 	task_id_t id;
-	int rc = task_spawnl(&id, app, app, winreg, NULL);
+	task_wait_t wait;
+	int rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
 	if (rc != EOK) {
 		printf("%s: Error spawning %s %s (%s)\n", NAME, app,
@@ -103,5 +104,5 @@
 	task_exit_t texit;
 	int retval;
-	rc = task_wait(id, &texit, &retval);
+	rc = task_wait(&wait, &texit, &retval);
 	if ((rc != EOK) || (texit != TASK_EXIT_NORMAL)) {
 		printf("%s: Error retrieving retval from %s (%s)\n", NAME,
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/generic/task.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -2,4 +2,5 @@
  * Copyright (c) 2006 Jakub Jermar
  * Copyright (c) 2008 Jiri Svoboda
+ * Copyright (c) 2014 Martin Sucha
  * All rights reserved.
  *
@@ -94,4 +95,6 @@
  *
  * @param id   If not NULL, the ID of the task is stored here on success.
+ * @param wait If not NULL, setup waiting for task's return value and store
+ *             the information necessary for waiting here on success.
  * @param path Pathname of the binary to execute.
  * @param argv Command-line arguments.
@@ -100,5 +103,6 @@
  *
  */
-int task_spawnv(task_id_t *id, const char *path, const char *const args[])
+int task_spawnv(task_id_t *id, task_wait_t *wait, const char *path,
+    const char *const args[])
 {
 	/* Send default files */
@@ -125,5 +129,5 @@
 	files[3] = NULL;
 	
-	return task_spawnvf(id, path, args, files);
+	return task_spawnvf(id, wait, path, args, files);
 }
 
@@ -135,4 +139,6 @@
  *
  * @param id    If not NULL, the ID of the task is stored here on success.
+ * @param wait  If not NULL, setup waiting for task's return value and store
+ *              the information necessary for waiting here on success.
  * @param path  Pathname of the binary to execute.
  * @param argv  Command-line arguments.
@@ -142,6 +148,6 @@
  *
  */
-int task_spawnvf(task_id_t *id, const char *path, const char *const args[],
-    int *const files[])
+int task_spawnvf(task_id_t *id, task_wait_t *wait, const char *path,
+    const char *const args[], int *const files[])
 {
 	/* Connect to a program loader. */
@@ -150,4 +156,6 @@
 		return EREFUSED;
 	
+	bool wait_initialized = false;
+	
 	/* Get task ID. */
 	task_id_t task_id;
@@ -181,4 +189,12 @@
 		goto error;
 	
+	/* Setup waiting for return value if needed */
+	if (wait) {
+		rc = task_setup_wait(task_id, wait);
+		if (rc != EOK)
+			goto error;
+		wait_initialized = true;
+	}
+	
 	/* Run it. */
 	rc = loader_run(ldr);
@@ -193,4 +209,7 @@
 	
 error:
+	if (wait_initialized)
+		task_cancel_wait(wait);
+	
 	/* Error exit */
 	loader_abort(ldr);
@@ -204,4 +223,6 @@
  *
  * @param id   If not NULL, the ID of the task is stored here on success.
+ * @param wait If not NULL, setup waiting for task's return value and store
+ *             the information necessary for waiting here on success.
  * @param path Pathname of the binary to execute.
  * @param cnt  Number of arguments.
@@ -211,5 +232,6 @@
  *
  */
-int task_spawn(task_id_t *task_id, const char *path, int cnt, va_list ap)
+int task_spawn(task_id_t *task_id, task_wait_t *wait, const char *path,
+    int cnt, va_list ap)
 {
 	/* Allocate argument list. */
@@ -227,5 +249,5 @@
 	
 	/* Spawn task. */
-	int rc = task_spawnv(task_id, path, arglist);
+	int rc = task_spawnv(task_id, wait, path, arglist);
 	
 	/* Free argument list. */
@@ -240,4 +262,6 @@
  *
  * @param id   If not NULL, the ID of the task is stored here on success.
+ * @param wait If not NULL, setup waiting for task's return value and store
+ *             the information necessary for waiting here on success.
  * @param path Pathname of the binary to execute.
  * @param ...  Command-line arguments.
@@ -246,5 +270,5 @@
  *
  */
-int task_spawnl(task_id_t *task_id, const char *path, ...)
+int task_spawnl(task_id_t *task_id, task_wait_t *wait, const char *path, ...)
 {
 	/* Count the number of arguments. */
@@ -262,5 +286,5 @@
 	
 	va_start(ap, path);
-	int rc = task_spawn(task_id, path, cnt, ap);
+	int rc = task_spawn(task_id, wait, path, cnt, ap);
 	va_end(ap);
 	
@@ -268,19 +292,90 @@
 }
 
-int task_wait(task_id_t id, task_exit_t *texit, int *retval)
+/** Setup waiting for a task.
+ * 
+ * If the task finishes after this call succeeds, it is guaranteed that
+ * task_wait(wait, &texit, &retval) will return correct return value for
+ * the task.
+ *
+ * @param id   ID of the task to setup waiting for.
+ * @param wait Information necessary for the later task_wait call is stored here.
+ *
+ * @return EOK on success, else error code.
+ */
+int task_setup_wait(task_id_t id, task_wait_t *wait)
+{
+	async_exch_t *exch = async_exchange_begin(session_ns);
+	wait->aid = async_send_2(exch, NS_TASK_WAIT, LOWER32(id), UPPER32(id),
+	    &wait->result);
+	async_exchange_end(exch);
+
+	return EOK;
+}
+
+/** Cancel waiting for a task.
+ *
+ * This can be called *instead of* task_wait if the caller is not interested
+ * in waiting for the task anymore.
+ *
+ * This function cannot be called if the task_wait was already called.
+ *
+ * @param wait task_wait_t previously initialized by task_setup_wait.
+ */
+void task_cancel_wait(task_wait_t *wait) {
+	async_forget(wait->aid);
+}
+
+/** Wait for a task to finish.
+ *
+ * This function returns correct values even if the task finished in
+ * between task_setup_wait and this task_wait call.
+ *
+ * This function cannot be called more than once with the same task_wait_t
+ * (it can be reused, but must be reinitialized with task_setup_wait first)
+ *
+ * @param wait   task_wait_t previously initialized by task_setup_wait.
+ * @param texit  Store type of task exit here.
+ * @param retval Store return value of the task here.
+ * 
+ * @return EOK on success, else error code.
+ */
+int task_wait(task_wait_t *wait, task_exit_t *texit, int *retval)
 {
 	assert(texit);
 	assert(retval);
-	
-	async_exch_t *exch = async_exchange_begin(session_ns);
-	sysarg_t te, rv;
-	int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id),
-	    UPPER32(id), &te, &rv);
-	async_exchange_end(exch);
-	
-	*texit = te;
-	*retval = rv;
-	
-	return rc;
+
+	sysarg_t rc;
+	async_wait_for(wait->aid, &rc);
+
+	if (rc == EOK) {
+		*texit = IPC_GET_ARG1(wait->result);
+		*retval = IPC_GET_ARG2(wait->result);
+	}
+
+	return rc;
+}
+
+/** Wait for a task to finish by its id.
+ *
+ * Note that this will fail with ENOENT if the task id is not registered in ns
+ * (e.g. if the task finished). If you are spawning a task and need to wait
+ * for its completion, use wait parameter of the task_spawn* functions instead
+ * to prevent a race where the task exits before you may have a chance to wait
+ * wait for it.
+ *
+ * @param id ID of the task to wait for.
+ * @param texit  Store type of task exit here.
+ * @param retval Store return value of the task here.
+ * 
+ * @return EOK on success, else error code.
+ */
+int task_wait_task_id(task_id_t id, task_exit_t *texit, int *retval)
+{
+	task_wait_t wait;
+	int rc = task_setup_wait(id, &wait);
+	if (rc != EOK)
+		return rc;
+	
+	return task_wait(&wait, texit, retval);
 }
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/include/async.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -45,5 +45,5 @@
 #include <atomic.h>
 #include <stdbool.h>
-#include <task.h>
+#include <abi/proc/task.h>
 #include <abi/ddi/irq.h>
 #include <abi/ipc/event.h>
Index: uspace/lib/c/include/ipc/common.h
===================================================================
--- uspace/lib/c/include/ipc/common.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/include/ipc/common.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -39,5 +39,5 @@
 #include <abi/ipc/ipc.h>
 #include <atomic.h>
-#include <task.h>
+#include <abi/proc/task.h>
 
 #define IPC_FLAG_BLOCKING  0x01
Index: uspace/lib/c/include/ipc/ipc.h
===================================================================
--- uspace/lib/c/include/ipc/ipc.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/include/ipc/ipc.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -44,5 +44,5 @@
 #include <abi/ipc/methods.h>
 #include <abi/synch.h>
-#include <task.h>
+#include <abi/proc/task.h>
 
 typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *);
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/include/loader/loader.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -37,5 +37,5 @@
 #define LIBC_LOADER_H_
 
-#include <task.h>
+#include <abi/proc/task.h>
 
 /** Forward declararion */
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/c/include/task.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -39,9 +39,14 @@
 #include <abi/proc/task.h>
 #include <stdarg.h>
+#include <async.h>
+#include <types/task.h>
 
-typedef enum {
-	TASK_EXIT_NORMAL,
-	TASK_EXIT_UNEXPECTED
-} task_exit_t;
+typedef struct {
+	ipc_call_t result;
+	aid_t aid;
+} task_wait_t;
+
+struct _TASK;
+typedef struct _TASK task_t;
 
 extern task_id_t task_get_id(void);
@@ -49,11 +54,16 @@
 extern int task_kill(task_id_t);
 
-extern int task_spawnv(task_id_t *, const char *path, const char *const []);
-extern int task_spawnvf(task_id_t *, const char *path, const char *const [],
-    int *const []);
-extern int task_spawn(task_id_t *, const char *path, int, va_list ap);
-extern int task_spawnl(task_id_t *, const char *path, ...);
+extern int task_spawnv(task_id_t *, task_wait_t *, const char *path,
+    const char *const []);
+extern int task_spawnvf(task_id_t *, task_wait_t *, const char *path,
+    const char *const [], int *const []);
+extern int task_spawn(task_id_t *, task_wait_t *, const char *path, int,
+    va_list ap);
+extern int task_spawnl(task_id_t *, task_wait_t *, const char *path, ...);
 
-extern int task_wait(task_id_t id, task_exit_t *, int *);
+extern int task_setup_wait(task_id_t, task_wait_t *);
+extern void task_cancel_wait(task_wait_t *);
+extern int task_wait(task_wait_t *, task_exit_t *, int *);
+extern int task_wait_task_id(task_id_t, task_exit_t *, int *);
 extern int task_retval(int);
 
Index: uspace/lib/c/include/types/task.h
===================================================================
--- uspace/lib/c/include/types/task.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
+++ uspace/lib/c/include/types/task.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_TYPES_TASK_H_
+#define LIBC_TYPES_TASK_H_
+
+typedef enum {
+	TASK_EXIT_NORMAL,
+	TASK_EXIT_UNEXPECTED
+} task_exit_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/gui/terminal.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -104,6 +104,6 @@
 static void getterm(const char *svc, const char *app)
 {
-	task_spawnl(NULL, APP_GETTERM, APP_GETTERM, svc, LOCFS_MOUNT_POINT,
-	    "--msg", "--wait", "--", app, NULL);
+	task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
+	    LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL);
 }
 
Index: uspace/lib/hound/src/client.c
===================================================================
--- uspace/lib/hound/src/client.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/hound/src/client.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -42,4 +42,5 @@
 #include <stdio.h>
 #include <libarch/types.h>
+#include <task.h>
 
 #include "protocol.h"
Index: uspace/lib/posix/source/sys/wait.c
===================================================================
--- uspace/lib/posix/source/sys/wait.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/lib/posix/source/sys/wait.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -100,5 +100,5 @@
 	int retval;
 	
-	int rc = task_wait((task_id_t) pid, &texit, &retval);
+	int rc = task_wait_task_id((task_id_t) pid, &texit, &retval);
 	
 	if (rc < 0) {
Index: uspace/srv/audio/hound/main.c
===================================================================
--- uspace/srv/audio/hound/main.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/audio/hound/main.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -43,4 +43,5 @@
 #include <hound/server.h>
 #include <hound/protocol.h>
+#include <task.h>
 
 #include "hound.h"
Index: uspace/srv/bd/sata_bd/sata_bd.c
===================================================================
--- uspace/srv/bd/sata_bd/sata_bd.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/bd/sata_bd/sata_bd.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -45,4 +45,5 @@
 #include <loc.h>
 #include <macros.h>
+#include <task.h>
 
 #include <ahci_iface.h>
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/devman/driver.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -40,4 +40,5 @@
 #include <str_error.h>
 #include <stdio.h>
+#include <task.h>
 
 #include "dev.h"
@@ -290,5 +291,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "start_driver(drv=\"%s\")", drv->name);
 	
-	rc = task_spawnl(NULL, drv->binary_path, drv->binary_path, NULL);
+	rc = task_spawnl(NULL, NULL, drv->binary_path, drv->binary_path, NULL);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Spawning driver `%s' (%s) failed: %s.",
Index: uspace/srv/hid/isdv4_tablet/main.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/main.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/hid/isdv4_tablet/main.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -36,4 +36,5 @@
 #include <ipc/mouseev.h>
 #include <inttypes.h>
+#include <task.h>
 
 #include "isdv4.h"
Index: uspace/srv/hid/remcons/remcons.c
===================================================================
--- uspace/srv/hid/remcons/remcons.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/hid/remcons/remcons.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -226,5 +226,6 @@
 	
 	task_id_t task;
-	int rc = task_spawnl(&task, APP_GETTERM, APP_GETTERM, user->service_name,
+	task_wait_t wait;
+	int rc = task_spawnl(&task, &wait, APP_GETTERM, APP_GETTERM, user->service_name,
 	    "/loc", "--msg", "--", APP_SHELL, NULL);
 	if (rc != EOK) {
@@ -246,5 +247,5 @@
 	task_exit_t task_exit;
 	int task_retval;
-	task_wait(task, &task_exit, &task_retval);
+	task_wait(&wait, &task_exit, &task_retval);
 	telnet_user_log(user, "%s terminated %s, exit code %d.", APP_GETTERM,
 	    task_exit == TASK_EXIT_NORMAL ? "normally" : "unexpectedly",
Index: uspace/srv/hid/rfb/main.c
===================================================================
--- uspace/srv/hid/rfb/main.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/hid/rfb/main.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -35,4 +35,5 @@
 #include <inttypes.h>
 #include <io/log.h>
+#include <task.h>
 
 #include <abi/fb/visuals.h>
Index: uspace/srv/net/ethip/ethip.c
===================================================================
--- uspace/srv/net/ethip/ethip.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/net/ethip/ethip.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -44,4 +44,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <task.h>
 #include "arp.h"
 #include "ethip.h"
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -46,4 +46,5 @@
 #include <stdlib.h>
 #include <sys/types.h>
+#include <task.h>
 #include "addrobj.h"
 #include "icmp.h"
Index: uspace/srv/net/loopip/loopip.c
===================================================================
--- uspace/srv/net/loopip/loopip.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/net/loopip/loopip.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -44,4 +44,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <task.h>
 
 #define NAME  "loopip"
Index: uspace/srv/net/nconfsrv/nconfsrv.c
===================================================================
--- uspace/srv/net/nconfsrv/nconfsrv.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/net/nconfsrv/nconfsrv.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -48,4 +48,5 @@
 #include <stdlib.h>
 #include <sys/types.h>
+#include <task.h>
 #include "iplink.h"
 #include "nconfsrv.h"
Index: uspace/srv/net/slip/slip.c
===================================================================
--- uspace/srv/net/slip/slip.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/net/slip/slip.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -43,4 +43,5 @@
 #include <io/log.h>
 #include <errno.h>
+#include <task.h>
 
 #define NAME		"slip"
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/ns/ns.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -66,5 +66,4 @@
 	while (true) {
 		process_pending_conn();
-		process_pending_wait();
 		
 		ipc_call_t call;
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/ns/task.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -40,14 +40,8 @@
 #include <macros.h>
 #include <malloc.h>
+#include <types/task.h>
 #include "task.h"
 #include "ns.h"
 
-
-/* TODO:
- *
- * As there is currently no convention that each task has to be waited
- * for, the NS can leak memory because of the zombie tasks.
- *
- */
 
 /** Task hash table item. */
@@ -195,5 +189,4 @@
 		}
 		
-		hash_table_remove(&task_hash_table, &pr->id);
 		list_remove(&pr->link);
 		free(pr);
@@ -204,8 +197,4 @@
 void wait_for_task(task_id_t id, ipc_call_t *call, ipc_callid_t callid)
 {
-	sysarg_t retval;
-	task_exit_t texit;
-	bool remove = false;
-	
 	ht_link_t *link = hash_table_find(&task_hash_table, &id);
 	hashed_task_t *ht = (link != NULL) ?
@@ -218,30 +207,24 @@
 	}
 	
-	if (!ht->finished) {
-		/* Add to pending list */
-		pending_wait_t *pr =
-		    (pending_wait_t *) malloc(sizeof(pending_wait_t));
-		if (!pr) {
-			retval = ENOMEM;
-			goto out;
-		}
-		
-		link_initialize(&pr->link);
-		pr->id = id;
-		pr->callid = callid;
-		list_append(&pr->link, &pending_wait);
+	if (ht->finished) {
+		task_exit_t texit = ht->have_rval ? TASK_EXIT_NORMAL :
+		    TASK_EXIT_UNEXPECTED;
+		ipc_answer_2(callid, EOK, texit, ht->retval);
 		return;
 	}
 	
-	remove = true;
-	retval = EOK;
-	
-out:
-	if (!(callid & IPC_CALLID_NOTIFICATION)) {
-		texit = ht->have_rval ? TASK_EXIT_NORMAL : TASK_EXIT_UNEXPECTED;
-		ipc_answer_2(callid, retval, texit, ht->retval);
-	}
-	if (remove)
-		hash_table_remove_item(&task_hash_table, link);
+	/* Add to pending list */
+	pending_wait_t *pr =
+	    (pending_wait_t *) malloc(sizeof(pending_wait_t));
+	if (!pr) {
+		if (!(callid & IPC_CALLID_NOTIFICATION))
+			ipc_answer_0(callid, ENOMEM);
+		return;
+	}
+	
+	link_initialize(&pr->link);
+	pr->id = id;
+	pr->callid = callid;
+	list_append(&pr->link, &pending_wait);
 }
 
@@ -314,4 +297,6 @@
 	ht->retval = IPC_GET_ARG1(*call);
 	
+	process_pending_wait();
+	
 	return EOK;
 }
@@ -336,4 +321,7 @@
 	ht->finished = true;
 	
+	process_pending_wait();
+	hash_table_remove(&task_hash_table, &id);
+	
 	return EOK;
 }
Index: uspace/srv/ns/task.h
===================================================================
--- uspace/srv/ns/task.h	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/ns/task.h	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -35,5 +35,5 @@
 
 #include <ipc/common.h>
-#include <task.h>
+#include <abi/proc/task.h>
 
 extern int task_init(void);
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision cb1fd3eaf46bdb60cceaf9bcd688b0d3935dfe76)
+++ uspace/srv/taskmon/taskmon.c	(revision 613d6445032773dfb7bc4ee44f3e7a827a802fbe)
@@ -82,9 +82,9 @@
 
 		printf(NAME ": Executing %s -c %s -t %s\n", fname, dump_fname, s_taskid);
-		rc = task_spawnl(NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
+		rc = task_spawnl(NULL, NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
 		    NULL);
 	} else {
 		printf(NAME ": Executing %s -t %s\n", fname, s_taskid);
-		rc = task_spawnl(NULL, fname, fname, "-t", s_taskid, NULL);
+		rc = task_spawnl(NULL, NULL, fname, fname, "-t", s_taskid, NULL);
 	}
 
