Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 87608a57807db334b9671e0b8c1aac5e1eadda3b)
+++ uspace/lib/c/generic/async.c	(revision 47c9a8c8f9297a115c8e45925ea8c045857037bb)
@@ -189,4 +189,10 @@
 	/** If reply was received. */
 	bool done;
+
+	/** If the message / reply should be discarded on arrival. */
+	bool forget;
+
+	/** If already destroyed. */
+	bool destroyed;
 	
 	/** Pointer to where the answer data is stored. */
@@ -240,4 +246,52 @@
 /** Identifier of the incoming connection handled by the current fibril. */
 static fibril_local connection_t *fibril_connection;
+
+static void to_event_initialize(to_event_t *to)
+{
+	struct timeval tv = { 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;
+
+	msg = malloc(sizeof(amsg_t));
+	if (msg) {
+		msg->done = false;
+		msg->forget = false;
+		msg->destroyed = false;
+		msg->dataptr = NULL;
+		msg->retval = (sysarg_t) EINVAL;
+		awaiter_initialize(&msg->wdata);
+	}
+
+	return msg;
+}
+
+static void amsg_destroy(amsg_t *msg)
+{
+	assert(!msg->destroyed);
+	msg->destroyed = true;
+	free(msg);
+}
 
 static void *default_client_data_constructor(void)
@@ -1100,9 +1154,13 @@
 	
 	msg->done = true;
-	if (!msg->wdata.active) {
+
+	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);
 	}
-	
+
 	futex_up(&async_futex);
 }
@@ -1131,17 +1189,9 @@
 		return 0;
 	
-	amsg_t *msg = malloc(sizeof(amsg_t));
+	amsg_t *msg = amsg_create();
 	if (msg == NULL)
 		return 0;
 	
-	msg->done = false;
 	msg->dataptr = dataptr;
-	
-	msg->wdata.to_event.inlist = false;
-	
-	/*
-	 * We may sleep in the next method,
-	 * but it will use its own means
-	 */
 	msg->wdata.active = true;
 	
@@ -1177,18 +1227,9 @@
 		return 0;
 	
-	amsg_t *msg = malloc(sizeof(amsg_t));
-	
+	amsg_t *msg = amsg_create();
 	if (msg == NULL)
 		return 0;
 	
-	msg->done = false;
 	msg->dataptr = dataptr;
-	
-	msg->wdata.to_event.inlist = false;
-	
-	/*
-	 * We may sleep in the next method,
-	 * but it will use its own means
-	 */
 	msg->wdata.active = true;
 	
@@ -1213,4 +1254,8 @@
 	
 	futex_down(&async_futex);
+
+	assert(!msg->forget);
+	assert(!msg->destroyed);
+
 	if (msg->done) {
 		futex_up(&async_futex);
@@ -1231,8 +1276,12 @@
 		*retval = msg->retval;
 	
-	free(msg);
+	amsg_destroy(msg);
 }
 
 /** Wait for a message sent by the async framework, timeout variant.
+ *
+ * If the wait times out, the caller may choose to either wait again by calling
+ * async_wait_for() or async_wait_timeout(), or forget the message via
+ * async_forget().
  *
  * @param amsgid  Hash of the message to wait for.
@@ -1255,4 +1304,8 @@
 	
 	futex_down(&async_futex);
+
+	assert(!msg->forget);
+	assert(!msg->destroyed);
+
 	if (msg->done) {
 		futex_up(&async_futex);
@@ -1279,8 +1332,32 @@
 		*retval = msg->retval;
 	
-	free(msg);
+	amsg_destroy(msg);
 	
 	return 0;
 }
+ 
+/** Discard the message / reply on arrival.
+ *
+ * The message will be marked to be discarded once the reply arrives in
+ * reply_received(). It is not allowed to call async_wait_for() or
+ * async_wait_timeout() on this message after a call to this function.
+ *
+ * @param amsgid  Hash of the message to forget.
+ */
+void async_forget(aid_t amsgid)
+{
+	amsg_t *msg = (amsg_t *) amsgid;
+
+	assert(msg);
+	assert(!msg->forget);
+	assert(!msg->destroyed);
+
+	futex_down(&async_futex);
+	if (msg->done)
+		amsg_destroy(msg);
+	else 
+		msg->forget = true;
+	futex_up(&async_futex);
+}
 
 /** Wait for specified time.
@@ -1293,11 +1370,9 @@
 void async_usleep(suseconds_t timeout)
 {
-	amsg_t *msg = malloc(sizeof(amsg_t));
-	
+	amsg_t *msg = amsg_create();
 	if (!msg)
 		return;
 	
 	msg->wdata.fid = fibril_get_id();
-	msg->wdata.active = false;
 	
 	gettimeofday(&msg->wdata.to_event.expires, NULL);
@@ -1313,5 +1388,5 @@
 	/* Futex is up automatically after fibril_switch() */
 	
-	free(msg);
+	amsg_destroy(msg);
 }
 
@@ -1584,6 +1659,6 @@
 	ipc_call_t result;
 	
-	amsg_t *msg = malloc(sizeof(amsg_t));
-	if (msg == NULL) {
+	amsg_t *msg = amsg_create();
+	if (!msg) {
 		free(sess);
 		errno = ENOMEM;
@@ -1591,13 +1666,5 @@
 	}
 	
-	msg->done = false;
 	msg->dataptr = &result;
-	
-	msg->wdata.to_event.inlist = false;
-	
-	/*
-	 * We may sleep in the next method,
-	 * but it will use its own means
-	 */
 	msg->wdata.active = true;
 	
@@ -1643,17 +1710,9 @@
 	ipc_call_t result;
 	
-	amsg_t *msg = malloc(sizeof(amsg_t));
-	if (msg == NULL)
+	amsg_t *msg = amsg_create();
+	if (!msg)
 		return ENOENT;
 	
-	msg->done = false;
 	msg->dataptr = &result;
-	
-	msg->wdata.to_event.inlist = false;
-	
-	/*
-	 * We may sleep in the next method,
-	 * but it will use its own means
-	 */
 	msg->wdata.active = true;
 	
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision 87608a57807db334b9671e0b8c1aac5e1eadda3b)
+++ uspace/lib/c/generic/fibril_synch.c	(revision 47c9a8c8f9297a115c8e45925ea8c045857037bb)
@@ -112,8 +112,7 @@
 		awaiter_t wdata;
 
+		awaiter_initialize(&wdata);
 		wdata.fid = fibril_get_id();
-		wdata.active = false;
 		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
 		list_append(&wdata.wu_event.link, &fm->waiters);
 		check_for_deadlock(&fm->oi);
@@ -205,8 +204,7 @@
 		awaiter_t wdata;
 
+		awaiter_initialize(&wdata);
 		wdata.fid = (fid_t) f;
-		wdata.active = false;
 		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
 		f->flags &= ~FIBRIL_WRITER;
 		list_append(&wdata.wu_event.link, &frw->waiters);
@@ -233,8 +231,7 @@
 		awaiter_t wdata;
 
+		awaiter_initialize(&wdata);
 		wdata.fid = (fid_t) f;
-		wdata.active = false;
 		wdata.wu_event.inlist = true;
-		link_initialize(&wdata.wu_event.link);
 		f->flags |= FIBRIL_WRITER;
 		list_append(&wdata.wu_event.link, &frw->waiters);
@@ -375,13 +372,8 @@
 		return ETIMEOUT;
 
+	awaiter_initialize(&wdata);
 	wdata.fid = fibril_get_id();
-	wdata.active = false;
-	
 	wdata.to_event.inlist = timeout > 0;
-	wdata.to_event.occurred = false;
-	link_initialize(&wdata.to_event.link);
-
 	wdata.wu_event.inlist = true;
-	link_initialize(&wdata.wu_event.link);
 
 	futex_down(&async_futex);
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision 87608a57807db334b9671e0b8c1aac5e1eadda3b)
+++ uspace/lib/c/generic/private/async.h	(revision 47c9a8c8f9297a115c8e45925ea8c045857037bb)
@@ -81,4 +81,6 @@
 } awaiter_t;
 
+extern void awaiter_initialize(awaiter_t *);
+
 extern void __async_init(void);
 extern void async_insert_timeout(awaiter_t *);
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 87608a57807db334b9671e0b8c1aac5e1eadda3b)
+++ uspace/lib/c/include/async.h	(revision 47c9a8c8f9297a115c8e45925ea8c045857037bb)
@@ -139,4 +139,5 @@
 extern void async_wait_for(aid_t, sysarg_t *);
 extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
+extern void async_forget(aid_t);
 
 extern fid_t async_new_connection(task_id_t, sysarg_t, ipc_callid_t,
