Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision 0db0df2acaf79a846301b8337ca8d67aee9c1f18)
+++ kernel/generic/src/cap/cap.c	(revision 2df21755623b239a0d57f0639a0bfcf636cd3d5b)
@@ -93,9 +93,8 @@
 
 #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;
-static slab_cache_t *kobject_cache;
 
 kobject_ops_t *kobject_ops[KOBJECT_TYPE_MAX] = {
@@ -125,8 +124,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,
 };
 
@@ -135,6 +155,4 @@
 	cap_cache = slab_cache_create("cap_t", sizeof(cap_t), 0, NULL,
 	    NULL, 0);
-	kobject_cache = slab_cache_create("kobject_t", sizeof(kobject_t), 0,
-	    NULL, NULL, 0);
 }
 
@@ -148,30 +166,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 +227,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 +347,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 +356,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 +387,4 @@
 	kobject_t *kobj = NULL;
 
-restart:
 	mutex_lock(&task->cap_info->lock);
 	cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
@@ -347,9 +393,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 +419,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,16 +457,5 @@
 	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);
-}
-
-kobject_t *kobject_alloc(unsigned int flags)
-{
-	return slab_alloc(kobject_cache, flags);
-}
-
-void kobject_free(kobject_t *kobj)
-{
-	slab_free(kobject_cache, kobj);
+	mutex_unlock(&task->cap_info->lock);
 }
 
@@ -422,9 +464,8 @@
  * @param kobj  Kernel object to initialize.
  * @param type  Type of the kernel object.
- * @param raw   Raw pointer to the encapsulated object.
- */
-void kobject_initialize(kobject_t *kobj, kobject_type_t type, void *raw)
-{
-	atomic_store(&kobj->refcnt, 1);
+ */
+void kobject_initialize(kobject_t *kobj, kobject_type_t type)
+{
+	refcount_init(&kobj->refcnt);
 
 	mutex_initialize(&kobj->caps_list_lock, MUTEX_PASSIVE);
@@ -432,5 +473,4 @@
 
 	kobj->type = type;
-	kobj->raw = raw;
 }
 
@@ -455,5 +495,5 @@
 		if (cap->kobject->type == type) {
 			kobj = cap->kobject;
-			atomic_inc(&kobj->refcnt);
+			refcount_up(&kobj->refcnt);
 		}
 	}
@@ -469,5 +509,5 @@
 void kobject_add_ref(kobject_t *kobj)
 {
-	atomic_inc(&kobj->refcnt);
+	refcount_up(&kobj->refcnt);
 }
 
@@ -481,7 +521,6 @@
 void kobject_put(kobject_t *kobj)
 {
-	if (atomic_postdec(&kobj->refcnt) == 1) {
-		KOBJECT_OP(kobj)->destroy(kobj->raw);
-		kobject_free(kobj);
+	if (refcount_down(&kobj->refcnt)) {
+		KOBJECT_OP(kobj)->destroy(kobj);
 	}
 }
