Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision 5f97ef445e6e5648a8b8c902eb0f655d579336b4)
+++ uspace/lib/c/generic/async/client.c	(revision bec18a999fe8f0a0d11e4e8b663b60185763e1c7)
@@ -104,5 +104,4 @@
 #include <ipc/irq.h>
 #include <ipc/event.h>
-#include <futex.h>
 #include <fibril.h>
 #include <adt/hash_table.h>
@@ -128,5 +127,5 @@
 /** Message data */
 typedef struct {
-	awaiter_t wdata;
+	fibril_event_t received;
 
 	/** If reply was received. */
@@ -136,7 +135,4 @@
 	bool forget;
 
-	/** If already destroyed. */
-	bool destroyed;
-
 	/** Pointer to where the answer data is stored. */
 	ipc_call_t *dataptr;
@@ -145,50 +141,11 @@
 } amsg_t;
 
-static void to_event_initialize(to_event_t *to)
-{
-	struct timeval tv = { 0, 0 };
-
-	to->inlist = false;
-	to->occurred = false;
-	link_initialize(&to->link);
-	to->expires = tv;
-}
-
-static void wu_event_initialize(wu_event_t *wu)
-{
-	wu->inlist = false;
-	link_initialize(&wu->link);
-}
-
-void awaiter_initialize(awaiter_t *aw)
-{
-	aw->fid = 0;
-	aw->active = false;
-	to_event_initialize(&aw->to_event);
-	wu_event_initialize(&aw->wu_event);
-}
-
 static amsg_t *amsg_create(void)
 {
-	amsg_t *msg = malloc(sizeof(amsg_t));
-	if (msg) {
-		msg->done = false;
-		msg->forget = false;
-		msg->destroyed = false;
-		msg->dataptr = NULL;
-		msg->retval = EINVAL;
-		awaiter_initialize(&msg->wdata);
-	}
-
-	return msg;
+	return calloc(1, sizeof(amsg_t));
 }
 
 static void amsg_destroy(amsg_t *msg)
 {
-	if (!msg)
-		return;
-
-	assert(!msg->destroyed);
-	msg->destroyed = true;
 	free(msg);
 }
@@ -251,22 +208,14 @@
 	msg->retval = IPC_GET_RETVAL(*data);
 
-	/* Copy data after futex_down, just in case the call was detached */
+	/* Copy data inside lock, just in case the call was detached */
 	if ((msg->dataptr) && (data))
 		*msg->dataptr = *data;
 
-	write_barrier();
-
-	/* Remove message from timeout list */
-	if (msg->wdata.to_event.inlist)
-		list_remove(&msg->wdata.to_event.link);
-
 	msg->done = true;
 
 	if (msg->forget) {
-		assert(msg->wdata.active);
 		amsg_destroy(msg);
-	} else if (!msg->wdata.active) {
-		msg->wdata.active = true;
-		fibril_add_ready(msg->wdata.fid);
+	} else {
+		fibril_notify(&msg->received);
 	}
 
@@ -301,5 +250,4 @@
 
 	msg->dataptr = dataptr;
-	msg->wdata.active = true;
 
 	errno_t rc = ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3,
@@ -343,5 +291,4 @@
 
 	msg->dataptr = dataptr;
-	msg->wdata.active = true;
 
 	errno_t rc = ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3,
@@ -371,24 +318,6 @@
 
 	amsg_t *msg = (amsg_t *) amsgid;
-
-	futex_lock(&async_futex);
-
-	assert(!msg->forget);
-	assert(!msg->destroyed);
-
-	if (msg->done) {
-		futex_unlock(&async_futex);
-		goto done;
-	}
-
-	msg->wdata.fid = fibril_get_id();
-	msg->wdata.active = false;
-	msg->wdata.to_event.inlist = false;
-
-	/* Leave the async_futex locked when entering this function */
-	fibril_switch(FIBRIL_FROM_BLOCKED);
-	futex_unlock(&async_futex);
-
-done:
+	fibril_wait_for(&msg->received);
+
 	if (retval)
 		*retval = msg->retval;
@@ -420,14 +349,4 @@
 
 	amsg_t *msg = (amsg_t *) amsgid;
-
-	futex_lock(&async_futex);
-
-	assert(!msg->forget);
-	assert(!msg->destroyed);
-
-	if (msg->done) {
-		futex_unlock(&async_futex);
-		goto done;
-	}
 
 	/*
@@ -438,36 +357,12 @@
 		timeout = 0;
 
-	getuptime(&msg->wdata.to_event.expires);
-	tv_add_diff(&msg->wdata.to_event.expires, timeout);
-
-	/*
-	 * Current fibril is inserted as waiting regardless of the
-	 * "size" of the timeout.
-	 *
-	 * Checking for msg->done and immediately bailing out when
-	 * timeout == 0 would mean that the manager fibril would never
-	 * run (consider single threaded program).
-	 * Thus the IPC answer would be never retrieved from the kernel.
-	 *
-	 * Notice that the actual delay would be very small because we
-	 * - switch to manager fibril
-	 * - the manager sees expired timeout
-	 * - and thus adds us back to ready queue
-	 * - manager switches back to some ready fibril
-	 *   (prior it, it checks for incoming IPC).
-	 *
-	 */
-	msg->wdata.fid = fibril_get_id();
-	msg->wdata.active = false;
-	async_insert_timeout(&msg->wdata);
-
-	/* Leave the async_futex locked when entering this function */
-	fibril_switch(FIBRIL_FROM_BLOCKED);
-	futex_unlock(&async_futex);
-
-	if (!msg->done)
-		return ETIMEOUT;
-
-done:
+	struct timeval expires;
+	getuptime(&expires);
+	tv_add_diff(&expires, timeout);
+
+	errno_t rc = fibril_wait_timeout(&msg->received, &expires);
+	if (rc != EOK)
+		return rc;
+
 	if (retval)
 		*retval = msg->retval;
@@ -475,5 +370,5 @@
 	amsg_destroy(msg);
 
-	return 0;
+	return EOK;
 }
 
@@ -494,5 +389,4 @@
 
 	assert(!msg->forget);
-	assert(!msg->destroyed);
 
 	futex_lock(&async_futex);
@@ -506,49 +400,4 @@
 
 	futex_unlock(&async_futex);
-}
-
-/** Wait for specified time.
- *
- * The current fibril is suspended but the thread continues to execute.
- *
- * @param timeout Duration of the wait in microseconds.
- *
- */
-void fibril_usleep(suseconds_t timeout)
-{
-	awaiter_t awaiter;
-	awaiter_initialize(&awaiter);
-
-	awaiter.fid = fibril_get_id();
-
-	getuptime(&awaiter.to_event.expires);
-	tv_add_diff(&awaiter.to_event.expires, timeout);
-
-	futex_lock(&async_futex);
-
-	async_insert_timeout(&awaiter);
-
-	/* Leave the async_futex locked when entering this function */
-	fibril_switch(FIBRIL_FROM_BLOCKED);
-	futex_unlock(&async_futex);
-}
-
-/** Delay execution for the specified number of seconds
- *
- * @param sec Number of seconds to sleep
- */
-void fibril_sleep(unsigned int sec)
-{
-	/*
-	 * Sleep in 1000 second steps to support
-	 * full argument range
-	 */
-
-	while (sec > 0) {
-		unsigned int period = (sec > 1000) ? 1000 : sec;
-
-		fibril_usleep(period * 1000000);
-		sec -= period;
-	}
 }
 
@@ -716,5 +565,4 @@
 
 	msg->dataptr = &result;
-	msg->wdata.active = true;
 
 	errno_t rc = ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO,
