Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 96368f565247d6ba58d979678be6335fa4499937)
+++ kernel/generic/src/cap/cap.c	(revision fa3ed5b2ad5250dbbe32d35a1db4cf866f983ba6)
@@ -93,6 +93,6 @@
 
 #define CAPS_START	((intptr_t) CAP_NIL + 1)
-#define CAPS_SIZE	(INT_MAX - (int) CAPS_START)
-#define CAPS_LAST	(CAPS_SIZE - 1)
+#define CAPS_LAST	((intptr_t) INT_MAX - 1)
+#define CAPS_SIZE	(CAPS_LAST - CAPS_START + 1)
 
 static slab_cache_t *cap_cache;
@@ -125,8 +125,29 @@
 }
 
+static void caps_remove_callback(ht_link_t *item)
+{
+	cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
+
+	if (cap->kobject) {
+		kobject_t *kobj = cap->kobject;
+
+		mutex_lock(&kobj->caps_list_lock);
+		cap->kobject = NULL;
+		list_remove(&cap->kobj_link);
+		mutex_unlock(&kobj->caps_list_lock);
+
+		kobject_put(kobj);
+	}
+
+	list_remove(&cap->type_link);
+
+	slab_free(cap_cache, cap);
+}
+
 static const hash_table_ops_t caps_ops = {
 	.hash = caps_hash,
 	.key_hash = caps_key_hash,
-	.key_equal = caps_key_equal
+	.key_equal = caps_key_equal,
+	.remove_callback = caps_remove_callback,
 };
 
@@ -148,30 +169,56 @@
 	if (!task->cap_info)
 		return ENOMEM;
+
+	if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) {
+		free(task->cap_info);
+		return ENOMEM;
+	}
+
+	mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
+
+	task->cap_info->handles = NULL;
+
+	for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
+		list_initialize(&task->cap_info->type_list[t]);
+
+	return EOK;
+}
+
+/** Initialize the capability info structure
+ *
+ * @param task  Task for which to initialize the info structure.
+ */
+errno_t caps_task_init(task_t *task)
+{
+	assert(task->cap_info);
+	assert(!task->cap_info->handles);
+
 	task->cap_info->handles = ra_arena_create();
 	if (!task->cap_info->handles)
-		goto error_handles;
-	if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE))
-		goto error_span;
-	if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops))
-		goto error_span;
+		return ENOMEM;
+
+	if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE)) {
+		ra_arena_destroy(task->cap_info->handles);
+		return ENOMEM;
+	}
+
 	return EOK;
-
-error_span:
-	ra_arena_destroy(task->cap_info->handles);
-error_handles:
-	free(task->cap_info);
-	return ENOMEM;
-}
-
-/** Initialize the capability info structure
- *
- * @param task  Task for which to initialize the info structure.
- */
-void caps_task_init(task_t *task)
-{
-	mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
+}
+
+void caps_task_clear(task_t *task)
+{
+	mutex_lock(&task->cap_info->lock);
+
+	hash_table_clear(&task->cap_info->caps);
+
+	if (task->cap_info->handles) {
+		ra_arena_destroy(task->cap_info->handles);
+		task->cap_info->handles = NULL;
+	}
 
 	for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
 		list_initialize(&task->cap_info->type_list[t]);
+
+	mutex_unlock(&task->cap_info->lock);
 }
 
@@ -183,5 +230,8 @@
 {
 	hash_table_destroy(&task->cap_info->caps);
-	ra_arena_destroy(task->cap_info->handles);
+
+	if (task->cap_info->handles)
+		ra_arena_destroy(task->cap_info->handles);
+
 	free(task->cap_info);
 }
@@ -300,6 +350,6 @@
 cap_publish(task_t *task, cap_handle_t handle, kobject_t *kobj)
 {
+	mutex_lock(&task->cap_info->lock);
 	mutex_lock(&kobj->caps_list_lock);
-	mutex_lock(&task->cap_info->lock);
 	cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
 	assert(cap);
@@ -309,6 +359,6 @@
 	list_append(&cap->kobj_link, &kobj->caps_list);
 	list_append(&cap->type_link, &task->cap_info->type_list[kobj->type]);
-	mutex_unlock(&task->cap_info->lock);
 	mutex_unlock(&kobj->caps_list_lock);
+	mutex_unlock(&task->cap_info->lock);
 }
 
@@ -340,5 +390,4 @@
 	kobject_t *kobj = NULL;
 
-restart:
 	mutex_lock(&task->cap_info->lock);
 	cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
@@ -347,9 +396,6 @@
 			/* Hand over cap's reference to kobj */
 			kobj = cap->kobject;
-			if (mutex_trylock(&kobj->caps_list_lock) != EOK) {
-				mutex_unlock(&task->cap_info->lock);
-				kobj = NULL;
-				goto restart;
-			}
+
+			mutex_lock(&kobj->caps_list_lock);
 			cap_unpublish_unsafe(cap);
 			mutex_unlock(&kobj->caps_list_lock);
@@ -376,12 +422,22 @@
 {
 	mutex_lock(&kobj->caps_list_lock);
-	list_foreach_safe(kobj->caps_list, cur, hlp) {
-		cap_t *cap = list_get_instance(cur, cap_t, kobj_link);
-		mutex_lock(&cap->task->cap_info->lock);
+
+	while (!list_empty(&kobj->caps_list)) {
+		cap_t *cap = list_get_instance(list_first(&kobj->caps_list), cap_t, kobj_link);
+
+		/* We're trying to acquire the two locks in reverse order. */
+		if (mutex_trylock(&cap->task->cap_info->lock) != EOK) {
+			mutex_unlock(&kobj->caps_list_lock);
+			mutex_lock(&kobj->caps_list_lock);
+			continue;
+		}
+
 		cap_unpublish_unsafe(cap);
 		/* Drop the reference for the unpublished capability */
 		kobject_put(kobj);
+
 		mutex_unlock(&cap->task->cap_info->lock);
 	}
+
 	mutex_unlock(&kobj->caps_list_lock);
 }
@@ -404,5 +460,4 @@
 	hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
 	ra_free(task->cap_info->handles, cap_handle_raw(handle), 1);
-	slab_free(cap_cache, cap);
 	mutex_unlock(&task->cap_info->lock);
 }
