Index: generic/src/ipc/ipc.c
===================================================================
--- generic/src/ipc/ipc.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/ipc/ipc.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
@@ -244,2 +244,12 @@
 					  NULL, NULL, 0);
 }
+
+/** Cleans up all IPC communication of the given task
+ *
+ *
+ */
+void ipc_cleanup(task_t *task)
+{
+	/* Cancel all calls in my dispatch queue */
+	
+}
Index: generic/src/ipc/ipcrsc.c
===================================================================
--- generic/src/ipc/ipcrsc.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
+++ generic/src/ipc/ipcrsc.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* IPC resources management
+ *
+ * The goal of this source code is to properly manage IPC resources
+ * and allow straight and clean clean-up procedure upon task termination.
+ *
+ * The pattern of usage of the resources is:
+ * - allocate empty phone slot, connect | deallocate slot
+ * - disconnect connected phone (some messages might be on the fly)
+ * - find phone in slot and send a message using phone
+ * - answer message to phone
+ * 
+ * 
+ */
+
+#include <synch/spinlock.h>
+#include <ipc/ipc.h>
+#include <arch.h>
+#include <proc/task.h>
+#include <ipc/ipcrsc.h>
+#include <debug.h>
+
+/** Find call_t * in call table according to callid
+ *
+ * @return NULL on not found, otherwise pointer to call structure
+ */
+call_t * get_call(__native callid)
+{
+	/* TODO: Traverse list of dispatched calls and find one */
+	/* TODO: locking of call, ripping it from dispatched calls etc.  */
+	return (call_t *) callid;
+}
+
+/** Return pointer to phone identified by phoneid or NULL if non-existent */
+phone_t * get_phone_and_lock(__native phoneid)
+{
+	phone_t *phone;
+
+	if (phoneid >= IPC_MAX_PHONES)
+		return NULL;
+
+	phone = &TASK->phones[phoneid];
+	spinlock_lock(&phone->lock);
+	if (!phone->callee) {
+		spinlock_unlock(&phone->lock);
+		return NULL;
+	}
+	return phone;
+}
+
+/** Allocate new phone slot in current TASK structure */
+int phone_alloc(void)
+{
+	int i;
+
+	spinlock_lock(&TASK->lock);
+	
+	for (i=0; i < IPC_MAX_PHONES; i++) {
+		if (!TASK->phones[i].busy) {
+			TASK->phones[i].busy = 1;
+			break;
+		}
+	}
+	spinlock_unlock(&TASK->lock);
+
+	if (i >= IPC_MAX_PHONES)
+		return -1;
+	return i;
+}
+
+/** Disconnect phone */
+void phone_dealloc(int phoneid)
+{
+	spinlock_lock(&TASK->lock);
+
+	ASSERT(TASK->phones[phoneid].busy);
+
+	if (TASK->phones[phoneid].callee)
+		ipc_phone_destroy(&TASK->phones[phoneid]);
+
+	TASK->phones[phoneid].busy = 0;
+	spinlock_unlock(&TASK->lock);
+}
+
+void phone_connect(int phoneid, answerbox_t *box)
+{
+	phone_t *phone = &TASK->phones[phoneid];
+	
+	ipc_phone_connect(phone, box);
+}
Index: generic/src/ipc/sysipc.c
===================================================================
--- generic/src/ipc/sysipc.c	(revision 93165be1285f3a50e69871962061a2e2fcfb9ae6)
+++ generic/src/ipc/sysipc.c	(revision bd72b475cd50bcd70a4ba176ff6b1bb17225c6ca)
@@ -36,4 +36,5 @@
 #include <ipc/ipc.h>
 #include <ipc/sysipc.h>
+#include <ipc/ipcrsc.h>
 
 
@@ -63,70 +64,4 @@
 {
 	return 1;
-}
-
-/** Find call_t * in call table according to callid
- *
- * @return NULL on not found, otherwise pointer to call structure
- */
-static inline call_t * get_call(__native callid)
-{
-	/* TODO: Traverse list of dispatched calls and find one */
-	/* TODO: locking of call, ripping it from dispatched calls etc.  */
-	return (call_t *) callid;
-}
-
-/** Return pointer to phone identified by phoneid or NULL if non-existent */
-static phone_t * get_phone(__native phoneid)
-{
-	phone_t *phone;
-
-	if (phoneid >= IPC_MAX_PHONES)
-		return NULL;
-
-	phone = &TASK->phones[phoneid];
-	if (!phone->callee)
-		return NULL;
-	return phone;
-}
-
-/** Allocate new phone slot in current TASK structure */
-static int phone_alloc(void)
-{
-	int i;
-
-	spinlock_lock(&TASK->lock);
-	
-	for (i=0; i < IPC_MAX_PHONES; i++) {
-		if (!TASK->phones[i].busy) {
-			TASK->phones[i].busy = 1;
-			break;
-		}
-	}
-	spinlock_unlock(&TASK->lock);
-
-	if (i >= IPC_MAX_PHONES)
-		return -1;
-	return i;
-}
-
-/** Disconnect phone */
-static void phone_dealloc(int phoneid)
-{
-	spinlock_lock(&TASK->lock);
-
-	ASSERT(TASK->phones[phoneid].busy);
-
-	if (TASK->phones[phoneid].callee)
-		ipc_phone_destroy(&TASK->phones[phoneid]);
-
-	TASK->phones[phoneid].busy = 0;
-	spinlock_unlock(&TASK->lock);
-}
-
-static void phone_connect(int phoneid, answerbox_t *box)
-{
-	phone_t *phone = &TASK->phones[phoneid];
-	
-	ipc_phone_connect(phone, box);
 }
 
@@ -213,10 +148,10 @@
 	phone_t *phone;
 
-	phone = get_phone(phoneid);
-	if (!phone)
-		return ENOENT;
-
 	if (is_system_method(method))
 		return EPERM;
+
+	phone = get_phone_and_lock(phoneid);
+	if (!phone)
+		return ENOENT;
 
 	ipc_call_init(&call);
@@ -238,8 +173,4 @@
 	phone_t *phone;
 
-	phone = get_phone(phoneid);
-	if (!phone)
-		return ENOENT;
-
 	ipc_call_init(&call);
 	copy_from_uspace(&call.data, question, sizeof(call.data));
@@ -248,4 +179,8 @@
 		return EPERM;
 	
+	phone = get_phone_and_lock(phoneid);
+	if (!phone)
+		return ENOENT;
+
 	ipc_call_sync(phone, &call);
 
@@ -279,8 +214,4 @@
 	phone_t *phone;
 
-	phone = get_phone(phoneid);
-	if (!phone)
-		return IPC_CALLRET_FATAL;
-
 	if (is_system_method(method))
 		return IPC_CALLRET_FATAL;
@@ -288,4 +219,8 @@
 	if (check_call_limit())
 		return IPC_CALLRET_TEMPORARY;
+
+	phone = get_phone_and_lock(phoneid);
+	if (!phone)
+		return IPC_CALLRET_FATAL;
 
 	call = ipc_call_alloc();
@@ -308,10 +243,10 @@
 	phone_t *phone;
 
-	phone = get_phone(phoneid);
-	if (!phone)
-		return IPC_CALLRET_FATAL;
-
 	if (check_call_limit())
 		return IPC_CALLRET_TEMPORARY;
+
+	phone = get_phone_and_lock(phoneid);
+	if (!phone)
+		return IPC_CALLRET_FATAL;
 
 	call = ipc_call_alloc();
@@ -345,5 +280,5 @@
 		return ENOENT;
 
-	phone = get_phone(phoneid);
+	phone = get_phone_and_lock(phoneid);
 	if (!phone) {
 		IPC_SET_RETVAL(call->data, EFORWARD);
@@ -437,8 +372,4 @@
 	phone_t *phone;
 
-	phone = get_phone(phoneid);
-	if (!phone)
-		return ENOENT;
-
 	ipc_call_init(&call);
 	IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME);
@@ -446,4 +377,8 @@
 	IPC_SET_ARG2(call.data, arg2);
 	
+	phone = get_phone_and_lock(phoneid);
+	if (!phone)
+		return ENOENT;
+
 	ipc_call_sync(phone, &call);
 
@@ -467,5 +402,5 @@
 	int newphid;
 
-	phone = get_phone(phoneid);
+	phone = get_phone_and_lock(phoneid);
 	if (!phone)
 		return ENOENT;
