Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision d088616132094127a4b2c38739dbbeb63290a63b)
+++ kernel/generic/src/cap/cap.c	(revision f36ac04c36e8dba660f611e4c8b71661a85dbb7a)
@@ -148,5 +148,5 @@
 void caps_task_init(task_t *task)
 {
-	mutex_initialize(&task->cap_info->lock, MUTEX_PASSIVE);
+	mutex_initialize(&task->cap_info->lock, MUTEX_RECURSIVE);
 
 	for (kobject_type_t t = 0; t < KOBJECT_TYPE_MAX; t++)
@@ -238,5 +238,5 @@
 	if (cap->state == CAP_STATE_PUBLISHED && cap->kobject->ops->reclaim &&
 	    cap->kobject->ops->reclaim(cap->kobject)) {
-		kobject_t *kobj = cap_unpublish_locked(cap->task, cap->handle,
+		kobject_t *kobj = cap_unpublish(cap->task, cap->handle,
 		    cap->kobject->type);
 		kobject_put(kobj);
@@ -318,14 +318,21 @@
 }
 
-/** @copydoc cap_unpublish()
- *
- * Can only be called internally by the capability subsytem or from a
- * caps_apply_to_kobject_type() callback.
- */
-kobject_t *
-cap_unpublish_locked(task_t *task, cap_handle_t handle, kobject_type_t type)
+/** Unpublish published capability
+ *
+ * The kernel object is moved out of the capability. In other words, the
+ * capability's reference to the objects is handed over to the kernel object
+ * pointer returned by this function. Once unpublished, the capability does not
+ * refer to any kernel object anymore.
+ *
+ * @param task    Task in which to unpublish the capability.
+ * @param handle  Capability handle.
+ * @param type    Kernel object type of the object associated with the
+ *                capability.
+ */
+kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
 {
 	kobject_t *kobj = NULL;
 
+	mutex_lock(&task->cap_info->lock);
 	cap_t *cap = cap_get(task, handle, CAP_STATE_PUBLISHED);
 	if (cap) {
@@ -338,40 +345,20 @@
 		}
 	}
+	mutex_unlock(&task->cap_info->lock);
 
 	return kobj;
 }
 
-/** Unpublish published capability
- *
- * The kernel object is moved out of the capability. In other words, the
- * capability's reference to the objects is handed over to the kernel object
- * pointer returned by this function. Once unpublished, the capability does not
- * refer to any kernel object anymore.
- *
- * @param task    Task in which to unpublish the capability.
+/** Free allocated capability
+ *
+ * @param task    Task in which to free the capability.
  * @param handle  Capability handle.
- * @param type    Kernel object type of the object associated with the
- *                capability.
- */
-kobject_t *cap_unpublish(task_t *task, cap_handle_t handle, kobject_type_t type)
-{
-
-	mutex_lock(&task->cap_info->lock);
-	kobject_t *kobj = cap_unpublish_locked(task, handle, type);
-	mutex_unlock(&task->cap_info->lock);
-
-	return kobj;
-}
-
-/** @copydoc cap_free()
- *
- * Can only be called internally by the capability subsytem or from a
- * caps_apply_to_kobject_type() callback.
- */
-void cap_free_locked(task_t *task, cap_handle_t handle)
+ */
+void cap_free(task_t *task, cap_handle_t handle)
 {
 	assert(handle >= 0);
 	assert(handle < MAX_CAPS);
 
+	mutex_lock(&task->cap_info->lock);
 	cap_t *cap = cap_get(task, handle, CAP_STATE_ALLOCATED);
 
@@ -381,15 +368,4 @@
 	ra_free(task->cap_info->handles, handle, 1);
 	slab_free(cap_slab, cap);
-}
-
-/** Free allocated capability
- *
- * @param task    Task in which to free the capability.
- * @param handle  Capability handle.
- */
-void cap_free(task_t *task, cap_handle_t handle)
-{
-	mutex_lock(&task->cap_info->lock);
-	cap_free_locked(task, handle);
 	mutex_unlock(&task->cap_info->lock);
 }
