Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/app/tester/Makefile	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -68,4 +68,5 @@
 	chardev/chardev1.c \
 	proc/dummy_task.c \
+	proc/task_anywait.c \
 	proc/task_wait.c
 
Index: uspace/app/tester/proc/common.h
===================================================================
--- uspace/app/tester/proc/common.h	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/app/tester/proc/common.h	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -44,3 +44,14 @@
 #define STR_JOB_OK      "job-ok"
 
+#define DUMMY_TASK     "/root/app/tester"
+#define DUMMY_TASK_ARG "proc_dummy_task"
+
+static inline int dummy_task_spawn(task_id_t *task_id, task_wait_t *wait,
+    const char *behavior)
+{
+	return task_spawnl(task_id, wait,
+	    DUMMY_TASK, DUMMY_TASK, DUMMY_TASK_ARG, behavior,
+	    NULL);
+}
+
 #endif
Index: uspace/app/tester/proc/task_anywait.c
===================================================================
--- uspace/app/tester/proc/task_anywait.c	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
+++ uspace/app/tester/proc/task_anywait.c	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015 Michal Koutny
+ * 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.
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <task.h>
+
+#include "../tester.h"
+#include "common.h"
+
+static task_id_t task_id;
+static task_exit_t last_texit;
+static bool last_has_retval;
+static int last_retval;
+static bool handler_hit;
+
+/* Locks are listed in their locking order */
+static FIBRIL_RWLOCK_INITIALIZE(tid_lck);
+static FIBRIL_MUTEX_INITIALIZE(sync_mtx);
+
+static FIBRIL_CONDVAR_INITIALIZE(sync_cv);
+
+static void task_event_handler(task_id_t tid, int flags, task_exit_t texit,
+    int retval)
+{
+	fibril_rwlock_read_lock(&tid_lck);
+	fibril_mutex_lock(&sync_mtx);
+
+	if (task_id != tid) {
+		goto finish;
+	}
+
+	handler_hit = true;
+finish:
+	fibril_condvar_signal(&sync_cv);
+	fibril_mutex_unlock(&sync_mtx);
+	fibril_rwlock_read_unlock(&tid_lck);
+}
+
+static void reset_wait(bool purge)
+{
+	fibril_mutex_lock(&sync_mtx);
+	handler_hit = false;
+	if (purge) {
+		last_texit = TASK_EXIT_RUNNING;
+		last_has_retval = false;
+		last_retval = 255;
+	}
+	fibril_mutex_unlock(&sync_mtx);
+}
+
+static void wait_for_handler(void)
+{
+	fibril_mutex_lock(&sync_mtx);
+	while (!handler_hit) {
+		fibril_condvar_wait(&sync_cv, &sync_mtx);
+	}
+	fibril_mutex_unlock(&sync_mtx);
+}
+
+static inline int safe_dummy_task_spawn(task_id_t *task_id, task_wait_t *wait,
+    const char *behavior)
+{
+	fibril_rwlock_write_lock(&tid_lck);
+	int rc = dummy_task_spawn(task_id, wait, behavior);
+	fibril_rwlock_write_unlock(&tid_lck);
+	return rc;
+}
+
+const char *test_proc_task_anywait(void)
+{
+	const char *err = NULL;
+
+	int rc;
+
+	task_set_event_handler(task_event_handler);
+
+	TPRINTF("1 exit only\n");
+
+	reset_wait(true);
+	rc = safe_dummy_task_spawn(&task_id, NULL, STR_FAIL);
+	TASSERT(rc == EOK);
+	wait_for_handler();
+	TASSERT(last_has_retval == false);
+	TASSERT(last_texit == TASK_EXIT_UNEXPECTED);
+	/* --- */
+
+	TPRINTF("2 daemon + kill\n");
+
+	reset_wait(true);
+	rc = safe_dummy_task_spawn(&task_id, NULL, STR_DAEMON);
+	TASSERT(rc == EOK);
+	wait_for_handler();
+	TASSERT(last_has_retval == true);
+	TASSERT(last_retval == EOK);
+	TASSERT(last_texit == TASK_EXIT_RUNNING);
+
+	reset_wait(false);
+	task_kill(task_id);
+	wait_for_handler();
+	TASSERT(last_texit == TASK_EXIT_UNEXPECTED);
+	/* --- */
+
+	TPRINTF("3 successful job\n");
+
+	reset_wait(true);
+	rc = safe_dummy_task_spawn(&task_id, NULL, STR_JOB_OK);
+	TASSERT(rc == EOK);
+	wait_for_handler(); /* job is notified in a single handler call */
+	TASSERT(last_has_retval == true);
+	TASSERT(last_retval == EOK);
+	TASSERT(last_texit == TASK_EXIT_NORMAL);
+	/* --- */
+
+	TPRINTF("3 successful job with discrimination\n");
+
+	reset_wait(true);
+	rc = safe_dummy_task_spawn(&task_id, NULL, STR_JOB_OK);
+	TASSERT(rc == EOK);
+	/* spoil it with another task events */
+	rc = dummy_task_spawn(NULL, NULL, STR_JOB_OK);
+	TASSERT(rc == EOK);
+	wait_for_handler();
+	TASSERT(last_has_retval == true);
+	TASSERT(last_retval == EOK);
+	TASSERT(last_texit == TASK_EXIT_NORMAL);
+	/* --- */
+
+
+	TPRINTF("All task waiting tests finished");
+
+	return err;
+}
Index: uspace/app/tester/proc/task_anywait.def
===================================================================
--- uspace/app/tester/proc/task_anywait.def	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
+++ uspace/app/tester/proc/task_anywait.def	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -0,0 +1,6 @@
+{
+	"proc_task_anywait",
+	"Task anywait API",
+	&test_proc_task_anywait,
+	true
+},
Index: uspace/app/tester/proc/task_wait.c
===================================================================
--- uspace/app/tester/proc/task_wait.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/app/tester/proc/task_wait.c	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -36,24 +36,4 @@
 #include "common.h"
 
-#define DUMMY_TASK     "/root/app/tester"
-#define DUMMY_TASK_ARG "proc_dummy_task"
-
-#define S(x) #x
-#define S_(x) S(x)
-#define S__LINE__ S_(__LINE__)
-
-#define TASSERT(expr) \
-	do { \
-		if (!(expr)) \
-			return "Failed " #expr " " __FILE__ ":" S__LINE__ ; \
-	} while (0)
-
-static int dummy_task_spawn(task_id_t *task_id, task_wait_t *wait,
-    const char *behavior)
-{
-	return task_spawnl(task_id, wait,
-	    DUMMY_TASK, DUMMY_TASK, DUMMY_TASK_ARG, behavior,
-	    NULL);
-}
 
 const char *test_proc_task_wait(void)
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/app/tester/tester.c	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -79,4 +79,5 @@
 #include "chardev/chardev1.def"
 #include "proc/dummy_task.def"
+#include "proc/task_anywait.def"
 #include "proc/task_wait.def"
 	{NULL, NULL, NULL, false}
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/app/tester/tester.h	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -70,4 +70,15 @@
 	} while (0)
 
+#define S(x) #x
+#define S_(x) S(x)
+#define S__LINE__ S_(__LINE__)
+
+#define TASSERT(expr) \
+	do { \
+		if (!(expr)) \
+			return "Failed " #expr " " __FILE__ ":" S__LINE__ ; \
+	} while (0)
+
+
 typedef const char *(*test_entry_t)(void);
 
@@ -112,4 +123,5 @@
 extern const char *test_chardev1(void);
 extern const char *test_proc_dummy_task(void);
+extern const char *test_proc_task_anywait(void);
 extern const char *test_proc_task_wait(void);
 
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/lib/c/generic/task.c	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -3,4 +3,5 @@
  * Copyright (c) 2008 Jiri Svoboda
  * Copyright (c) 2014 Martin Sucha
+ * Copyright (c) 2015 Michal Koutny
  * All rights reserved.
  *
@@ -53,4 +54,5 @@
 
 static async_sess_t *session_taskman = NULL;
+static task_event_handler_t task_event_handler = NULL;
 
 task_id_t task_get_id(void)
@@ -470,4 +472,9 @@
 }
 
+void task_set_event_handler(task_event_handler_t handler)
+{
+	task_event_handler = handler;
+	// TODO implement logic for calling the handler
+}
 
 void __task_init(async_sess_t *sess)
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/lib/c/include/task.h	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -46,11 +46,4 @@
 #define TASK_WAIT_BOTH   0x4
 
-typedef struct {
-	int flags;
-	ipc_call_t result;
-	aid_t aid;
-	task_id_t tid;
-} task_wait_t;
-
 static inline void task_wait_set(task_wait_t *wait, int flags)
 {
@@ -76,19 +69,11 @@
     __attribute__((sentinel));
 
-// if there is possibility for further wait, modify task_wait
 extern errno_t task_wait(task_wait_t *, task_exit_t *, int *);
 extern errno_t task_wait_task_id(task_id_t, int, task_exit_t *, int *);
-// similar to listen and socket duplication
-extern errno_t task_wait_any(task_wait_t *, task_id_t *, task_exit_t *, int *,
-    task_wait_t *);
-
-//extern int task_wait_any(int, task_exit_t *, int *);
-// alternative
-// task_wait_t is output param, actual result is obtained via task_wait call
-//extern int task_wait_any(task_wait_t *, int);
 
 extern void task_cancel_wait(task_wait_t *);
 
 extern errno_t task_retval(int);
+extern void task_set_event_handler(task_event_handler_t);
 
 #endif
Index: uspace/lib/c/include/types/task.h
===================================================================
--- uspace/lib/c/include/types/task.h	(revision 5cd2290e54788397fcad0ed05bb178890e1989a6)
+++ uspace/lib/c/include/types/task.h	(revision b22b0a94b341e922fce473e92cec4901af1e7086)
@@ -42,4 +42,13 @@
 } task_exit_t;
 
+typedef struct {
+	int flags;
+	ipc_call_t result;
+	aid_t aid;
+	task_id_t tid;
+} task_wait_t;
+
+typedef void (* task_event_handler_t)(task_id_t, int, task_exit_t, int);
+
 #endif
 
