Index: generic/src/ipc/ipc.c
===================================================================
--- generic/src/ipc/ipc.c	(revision 631ca4d04a2284ebd54da4b84fc569fab1e212a4)
+++ generic/src/ipc/ipc.c	(revision e74cb73cbab961321532b012b1090380dd325f74)
@@ -32,5 +32,6 @@
  */
 
-#include <synch/waitq.h>
+#include <synch/condvar.h>
+#include <synch/mutex.h>
 #include <ipc/ipc.h>
 #include <errno.h>
@@ -44,5 +45,6 @@
 #include <proc/thread.h>
 
-answerbox_t *ipc_central_box;
+/* Open channel that is assigned automatically to new tasks */
+answerbox_t *ipc_phone_0 = NULL;
 
 static slab_cache_t *ipc_call_slab;
@@ -64,4 +66,11 @@
 }
 
+/** Initialize allocated call */
+void ipc_call_init(call_t *call)
+{
+	call->callerbox = &TASK->answerbox;
+	call->flags = IPC_CALL_STATIC_ALLOC;
+}
+
 /** Deallocate call stracuture */
 void ipc_call_free(call_t *call)
@@ -74,6 +83,6 @@
 void ipc_answerbox_init(answerbox_t *box)
 {
-	spinlock_initialize(&box->lock, "abox_lock");
-	waitq_initialize(&box->wq);
+	mutex_initialize(&box->mutex);
+	condvar_initialize(&box->cv);
 	list_initialize(&box->connected_phones);
 	list_initialize(&box->calls);
@@ -89,7 +98,8 @@
 	
 	phone->callee = box;
-	spinlock_lock(&box->lock);
+
+	mutex_lock(&box->mutex);
 	list_append(&phone->list, &box->connected_phones);
-	spinlock_unlock(&box->lock);
+	mutex_unlock(&box->mutex);
 }
 
@@ -101,7 +111,7 @@
 	ASSERT(box);
 
-	spinlock_lock(&box->lock);
+	mutex_lock(&box->mutex);
 	list_remove(&phone->list);
-	spinlock_unlock(&box->lock);
+	mutex_unlock(&box->mutex);
 }
 
@@ -131,8 +141,8 @@
 	ASSERT(box);
 
-	spinlock_lock(&box->lock);
+	mutex_lock(&box->mutex);
 	list_append(&request->list, &box->calls);
-	spinlock_unlock(&box->lock);
-	waitq_wakeup(&box->wq, 0);
+	mutex_unlock(&box->mutex);
+	condvar_signal(&box->cv);
 }
 
@@ -148,13 +158,12 @@
 	request->flags |= IPC_CALL_ANSWERED;
 
-	spinlock_lock(&box->lock);
-	spinlock_lock(&callerbox->lock);
-
+	mutex_lock(&box->mutex);
 	list_remove(&request->list);
+	mutex_unlock(&box->mutex);
+
+	mutex_lock(&callerbox->mutex);
 	list_append(&request->list, &callerbox->answers);
-	waitq_wakeup(&callerbox->wq, 0);
-
-	spinlock_unlock(&callerbox->lock);
-	spinlock_unlock(&box->lock);
+	mutex_unlock(&callerbox->mutex);
+	condvar_signal(&callerbox->cv);
 }
 
@@ -168,28 +177,28 @@
 	call_t *request;
 
-	if ((flags & IPC_WAIT_NONBLOCKING)) {
-		if (waitq_sleep_timeout(&box->wq,SYNCH_NO_TIMEOUT,SYNCH_NON_BLOCKING) == ESYNCH_WOULD_BLOCK)
-			return 0;
-	} else {
-		waitq_sleep(&box->wq);
+	mutex_lock(&box->mutex);
+	while (1) { 
+		if (!list_empty(&box->answers)) {
+			/* Handle asynchronous answers */
+			request = list_get_instance(box->answers.next, call_t, list);
+			list_remove(&request->list);
+		} else if (!list_empty(&box->calls)) {
+			/* Handle requests */
+			request = list_get_instance(box->calls.next, call_t, list);
+			list_remove(&request->list);
+			/* Append request to dispatch queue */
+			list_append(&request->list, &box->dispatched_calls);
+		} else {
+			if (!(flags & IPC_WAIT_NONBLOCKING)) {
+				condvar_wait(&box->cv, &box->mutex);
+				continue;
+			}
+			if (condvar_trywait(&box->cv, &box->mutex) != ESYNCH_WOULD_BLOCK)
+				continue;
+			request = NULL;
+		}
+		break;
 	}
-
-
-	// TODO - might need condition variable+mutex if we want to support
-	// removing of requests from queue before dispatch
-	spinlock_lock(&box->lock);
-	/* Handle answers first */
-	if (!list_empty(&box->answers)) {
-		request = list_get_instance(box->answers.next, call_t, list);
-		list_remove(&request->list);
-	} else {
-		ASSERT (! list_empty(&box->calls));
-		request = list_get_instance(box->calls.next, call_t, list);
-		list_remove(&request->list);
-		/* Append request to dispatch queue */
-		list_append(&request->list, &box->dispatched_calls);
-	}
-	spinlock_unlock(&box->lock);
-
+	mutex_unlock(&box->mutex);
 	return request;
 }
@@ -203,31 +212,2 @@
 					  NULL, NULL, 0);
 }
-
-static void ipc_phonecompany_thread(void *data)
-{
-	call_t *call;
-
-	printf("Phone company started.\n");
-	while (1) {
-		call = ipc_wait_for_call(&TASK->answerbox, 0);
-		printf("Received phone call - %P %P\n",
-		       call->data[0], call->data[1]);
-		call->data[0] = 0xbabaaaee;;
-		call->data[1] = 0xaaaaeeee;
-		ipc_answer(&TASK->answerbox, call);
-		printf("Call answered.\n");
-	}
-}
-
-void ipc_create_phonecompany(void)
-{
-	thread_t *t;
-	
-	if ((t = thread_create(ipc_phonecompany_thread, "phonecompany", 
-			       TASK, 0)))
-		thread_ready(t);
-	else
-		panic("thread_create/phonecompany");
-
-	ipc_central_box = &TASK->answerbox;
-}
