Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 63d8f43468baaa1f20964c35b3aea13f36dd3e2c)
+++ kernel/generic/src/cap/cap.c	(revision 9e875620ecd41735d8a5759a1e6986978cb55507)
@@ -35,7 +35,8 @@
 #include <cap/cap.h>
 #include <proc/task.h>
-#include <synch/spinlock.h>
+#include <synch/mutex.h>
 #include <abi/errno.h>
 #include <mm/slab.h>
+#include <adt/list.h>
 
 void cap_initialize(cap_t *cap, int handle)
@@ -44,34 +45,66 @@
 	cap->handle = handle;
 	cap->can_reclaim = NULL;
+	link_initialize(&cap->link);
 }
 
 void caps_task_alloc(task_t *task)
 {
-	task->caps = malloc(sizeof(cap_t) * MAX_CAPS, 0);
+	task->cap_info = (cap_info_t *) malloc(sizeof(cap_info_t), 0);
+	task->cap_info->caps = malloc(sizeof(cap_t) * MAX_CAPS, 0);
 }
 
 void caps_task_init(task_t *task)
 {
+	mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
+
+	for (int i = 0; i < CAP_TYPE_MAX; i++)
+		list_initialize(&task->cap_info->type_list[i]);
+
 	for (int i = 0; i < MAX_CAPS; i++)
-		cap_initialize(&task->caps[i], i);
+		cap_initialize(&task->cap_info->caps[i], i);
 }
 
 void caps_task_free(task_t *task)
 {
-	free(task->caps);
+	free(task->cap_info->caps);
+	free(task->cap_info);
+}
+
+bool caps_apply_to_all(task_t *task, cap_type_t type,
+    bool (*cb)(cap_t *, void *), void *arg)
+{
+	bool done = true;
+
+	mutex_lock(&task->cap_info->lock);
+	list_foreach_safe(task->cap_info->type_list[type], cur, next) {
+		cap_t *cap = list_get_instance(cur, cap_t, link);
+		done = cb(cap, arg);
+		if (!done)
+			break;
+	}
+	mutex_unlock(&task->cap_info->lock);
+
+	return done;
+}
+
+void caps_lock(task_t *task)
+{
+	mutex_lock(&task->cap_info->lock);
+}
+
+void caps_unlock(task_t *task)
+{
+	mutex_unlock(&task->cap_info->lock);
 }
 
 cap_t *cap_get(task_t *task, int handle, cap_type_t type)
 {
+	assert(mutex_locked(&task->cap_info->lock));
+
 	if ((handle < 0) || (handle >= MAX_CAPS))
 		return NULL;
-	if (task->caps[handle].type != type)
+	if (task->cap_info->caps[handle].type != type)
 		return NULL;
-	return &task->caps[handle];
-}
-
-cap_t *cap_get_current(int handle, cap_type_t type)
-{
-	return cap_get(TASK, handle, type);
+	return &task->cap_info->caps[handle];
 }
 
@@ -80,7 +113,7 @@
 	int handle;
 
-	irq_spinlock_lock(&task->lock, true);
+	mutex_lock(&task->cap_info->lock);
 	for (handle = 0; handle < MAX_CAPS; handle++) {
-		cap_t *cap = &task->caps[handle];
+		cap_t *cap = &task->cap_info->caps[handle];
 		if (cap->type > CAP_TYPE_ALLOCATED) {
 			if (cap->can_reclaim && cap->can_reclaim(cap))
@@ -89,11 +122,37 @@
 		if (cap->type == CAP_TYPE_INVALID) {
 			cap->type = CAP_TYPE_ALLOCATED;
-			irq_spinlock_unlock(&task->lock, true);
+			mutex_unlock(&task->cap_info->lock);
 			return handle;
 		}
 	}
-	irq_spinlock_unlock(&task->lock, true);
+	mutex_unlock(&task->cap_info->lock);
 
 	return ELIMIT;
+}
+
+void cap_publish(task_t *task, int handle, cap_type_t type, void *kobject)
+{
+	mutex_lock(&task->cap_info->lock);
+	cap_t *cap = cap_get(task, handle, CAP_TYPE_ALLOCATED);
+	assert(cap);
+	cap->type = type;
+	cap->kobject = kobject;
+	list_append(&cap->link, &task->cap_info->type_list[type]);
+	mutex_unlock(&task->cap_info->lock);
+}
+
+cap_t *cap_unpublish(task_t *task, int handle, cap_type_t type)
+{
+	cap_t *cap;
+
+	mutex_lock(&task->cap_info->lock);
+	cap = cap_get(task, handle, type);
+	if (cap) {
+		list_remove(&cap->link);
+		cap->type = CAP_TYPE_ALLOCATED;
+	}
+	mutex_unlock(&task->cap_info->lock);
+
+	return cap;
 }
 
@@ -102,9 +161,9 @@
 	assert(handle >= 0);
 	assert(handle < MAX_CAPS);
-	assert(task->caps[handle].type == CAP_TYPE_ALLOCATED);
+	assert(task->cap_info->caps[handle].type == CAP_TYPE_ALLOCATED);
 
-	irq_spinlock_lock(&task->lock, true);
-	cap_initialize(&task->caps[handle], handle);
-	irq_spinlock_unlock(&task->lock, true);
+	mutex_lock(&task->cap_info->lock);
+	cap_initialize(&task->cap_info->caps[handle], handle);
+	mutex_unlock(&task->cap_info->lock);
 }
 
