Index: uspace/lib/c/generic/async_sess.c
===================================================================
--- uspace/lib/c/generic/async_sess.c	(revision 80bffdb0707ffcda3727a4cbeb4ec52003630551)
+++ uspace/lib/c/generic/async_sess.c	(revision 8b5c8ae540254d0b8de85653e594938d5ada9217)
@@ -110,10 +110,11 @@
 typedef struct {
 	link_t sess_link;	/**< Link for the session list of inactive connections. */
-	link_t global_link;	/**< Link for the global list of inactive connectinos. */
+	link_t global_link;	/**< Link for the global list of inactive connections. */
 	int data_phone;		/**< Connected data phone. */
 } conn_node_t;
 
 /**
- * Mutex protecting the inactive_conn_head list and the session list.
+ * Mutex protecting the inactive_conn_head list, the session list and the
+ * avail_phone condition variable.
  */
 static fibril_mutex_t async_sess_mutex;
@@ -128,4 +129,9 @@
  */
 static LIST_INITIALIZE(session_list_head);
+
+/**
+ * Condition variable used to wait for a phone to become available.
+ */
+static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
 
 /** Initialize the async_sess subsystem.
@@ -197,4 +203,6 @@
 		free(conn);
 	}
+	
+	fibril_condvar_broadcast(&avail_phone_cv);
 }
 
@@ -256,10 +264,8 @@
 		} else {
 			/*
-			 * This is unfortunate. We failed both to find a cached
-			 * connection or to create a new one even after cleaning up
-			 * the cache. This is most likely due to too many
-			 * open sessions (connected session phones).
+			 * Wait for a phone to become available.
 			 */
-			data_phone = ELIMIT;
+			fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
+			goto retry;
 		}
 	}
@@ -279,4 +285,5 @@
 
 	fibril_mutex_lock(&async_sess_mutex);
+	fibril_condvar_signal(&avail_phone_cv);
 	conn = (conn_node_t *) malloc(sizeof(conn_node_t));
 	if (!conn) {
@@ -285,6 +292,6 @@
 		 * means that we simply hang up.
 		 */
+		ipc_hangup(data_phone);
 		fibril_mutex_unlock(&async_sess_mutex);
-		ipc_hangup(data_phone);
 		return;
 	}
