Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision 1f2b07ab9fedfc54da0cdadeebaa5fb7abc38ca3)
+++ uspace/lib/c/generic/fibril.c	(revision c721d26bc34f19e9ee8b606049a67bc27dc5cda4)
@@ -96,4 +96,5 @@
 	fibril->retval = fibril->func(fibril->arg);
 	
+	futex_down(&async_futex);
 	fibril_switch(FIBRIL_FROM_DEAD);
 	/* Not reached */
@@ -147,6 +148,6 @@
 /** Switch from the current fibril.
  *
- * If calling with FIBRIL_TO_MANAGER parameter, the async_futex should be
- * held.
+ * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must
+ * be held.
  *
  * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
@@ -163,5 +164,5 @@
 	
 	futex_lock(&fibril_futex);
-	
+
 	if (stype == FIBRIL_PREEMPT && list_empty(&ready_list))
 		goto ret_0;
@@ -183,4 +184,7 @@
 	/* If we are going to manager and none exists, create it */
 	if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
+		/* Make sure the async_futex is held. */
+		assert((atomic_signed_t) async_futex.val.count <= 0);
+
 		while (list_empty(&manager_list)) {
 			futex_unlock(&fibril_futex);
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 1f2b07ab9fedfc54da0cdadeebaa5fb7abc38ca3)
+++ uspace/lib/c/include/async.h	(revision c721d26bc34f19e9ee8b606049a67bc27dc5cda4)
@@ -108,5 +108,8 @@
 
 #define async_manager() \
-	fibril_switch(FIBRIL_TO_MANAGER)
+	do { \
+		futex_down(&async_futex); \
+		fibril_switch(FIBRIL_FROM_DEAD); \
+	} while (0)
 
 #define async_get_call(data) \
