*/
mutex_lock(&reply->reply_dst->lock);
if (!list_empty(&reply->entry)) {
- if (reply->sync) {
+ kdbus_reply_unlink(reply);
+ if (reply->sync)
kdbus_sync_reply_wakeup(reply, -EPIPE);
- } else {
- list_del_init(&reply->entry);
+ else
kdbus_notify_reply_dead(conn->ep->bus,
entry->msg.src_id,
entry->msg.cookie);
- }
}
mutex_unlock(&reply->reply_dst->lock);
- kdbus_reply_unref(reply);
}
kdbus_notify_flush(conn->ep->bus);
mutex_lock(&conn_dst->lock);
r = kdbus_reply_find(conn_src, conn_dst, msg->cookie_reply);
if (r) {
- list_del_init(&r->entry);
if (r->sync)
*reply_wake = kdbus_reply_ref(r);
- else
- kdbus_reply_unref(r);
+ kdbus_reply_unlink(r);
}
mutex_unlock(&conn_dst->lock);
remote_ret = -EREMOTEIO;
kdbus_sync_reply_wakeup(reply_wake, remote_ret);
+ kdbus_reply_unlink(reply_wake);
mutex_unlock(&reply_wake->reply_dst->lock);
- kdbus_reply_unref(reply_wake);
return ret;
}
entry->reply = kdbus_reply_ref(reply);
if (reply) {
- list_add(&reply->entry, &conn_src->reply_list);
+ kdbus_reply_link(reply);
if (!reply->sync)
schedule_delayed_work(&conn_src->work, 0);
}
}
mutex_lock(&conn_src->lock);
- list_del_init(&reply_wait->entry);
reply_wait->waiting = false;
entry = reply_wait->queue_entry;
if (entry) {
kdbus_pool_slice_release(entry->slice);
kdbus_queue_entry_free(entry);
}
+ kdbus_reply_unlink(reply_wait);
mutex_unlock(&conn_src->lock);
return ret;
reply_wait = kdbus_reply_find(conn_dst, conn_src,
kmsg->msg.cookie);
if (reply_wait) {
- if (reply_wait->interrupted)
+ if (reply_wait->interrupted) {
+ kdbus_reply_ref(reply_wait);
reply_wait->interrupted = false;
- else
+ } else {
reply_wait = NULL;
+ }
}
mutex_unlock(&conn_src->lock);
exit_unref:
kdbus_reply_unref(reply_wait);
+ kdbus_reply_unref(reply_wake);
kdbus_conn_unref(conn_dst);
exit_name_unlock:
kdbus_name_unlock(bus->name_registry, name_entry);
kdbus_queue_entry_free(entry);
}
- list_for_each_entry_safe(r, r_tmp, &conn->reply_list, entry) {
- list_del_init(&r->entry);
- kdbus_reply_unref(r);
- }
+ list_for_each_entry_safe(r, r_tmp, &conn->reply_list, entry)
+ kdbus_reply_unlink(r);
mutex_unlock(&conn->lock);
/* lock order: domain -> bus -> ep -> names -> conn */
if (r->reply_src == conn) {
if (r->sync) {
kdbus_sync_reply_wakeup(r, -EPIPE);
+ kdbus_reply_unlink(r);
continue;
}
/* send a 'connection dead' notification */
kdbus_notify_reply_dead(bus, c->id, r->cookie);
-
- list_del_init(&r->entry);
- kdbus_reply_unref(r);
+ kdbus_reply_unlink(r);
}
}
mutex_unlock(&c->lock);
}
kref_init(&r->kref);
+ INIT_LIST_HEAD(&r->entry);
r->reply_src = kdbus_conn_ref(reply_src);
r->reply_dst = kdbus_conn_ref(reply_dst);
r->cookie = msg->cookie;
return NULL;
}
+/**
+ * kdbus_reply_link() - Link reply object into target connection
+ * @r: Reply to link
+ */
+void kdbus_reply_link(struct kdbus_reply *r)
+{
+ if (WARN_ON(!list_empty(&r->entry)))
+ return;
+
+ list_add(&r->entry, &r->reply_dst->reply_list);
+ kdbus_reply_ref(r);
+}
+
+/**
+ * kdbus_reply_unlink() - Unlink reply object from target connection
+ * @r: Reply to unlink
+ */
+void kdbus_reply_unlink(struct kdbus_reply *r)
+{
+ if (!list_empty(&r->entry)) {
+ list_del_init(&r->entry);
+ kdbus_reply_unref(r);
+ }
+}
+
/**
* kdbus_sync_reply_wakeup() - Wake a synchronously blocking reply
* @reply: The reply object
if (WARN_ON(!reply->sync))
return;
- list_del_init(&reply->entry);
reply->waiting = false;
reply->err = err;
wake_up_interruptible(&reply->reply_dst->wait);
kdbus_notify_reply_timeout(conn->ep->bus, conn->id,
reply->cookie);
- list_del_init(&reply->entry);
- kdbus_reply_unref(reply);
+ kdbus_reply_unlink(reply);
}
/* rearm delayed work with next timeout */