All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ] gatt-database: No multiple calls to AcquireWrite
@ 2021-06-11 12:30 Sebastian Urban
  2021-06-11 12:53 ` [BlueZ] " bluez.test.bot
  2021-06-11 22:31 ` [PATCH BlueZ] " Luiz Augusto von Dentz
  0 siblings, 2 replies; 6+ messages in thread
From: Sebastian Urban @ 2021-06-11 12:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sebastian Urban

This checks if an outstanding call to AcquireWrite is already in
progress. If so, the write request is placed into the queue, but
AcquireWrite is not called again. When a response to AcquireWrite is
received, acquire_write_reply sends all queued writes over the acquired
socket.

Making multiple simultaneous calls to AcquireWrite makes no sense,
as this would open multiple socket pairs and only the last returned
socket would be used for further writes.
---
 src/gatt-database.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/gatt-database.c b/src/gatt-database.c
index be6dfb265..071f88583 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -2447,6 +2447,7 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
 {
 	struct pending_op *op = user_data;
 	struct external_chrc *chrc;
+	struct queue *resend;
 	DBusError err;
 	int fd;
 	uint16_t mtu;
@@ -2488,18 +2489,35 @@ static void acquire_write_reply(DBusMessage *message, void *user_data)
 
 	chrc->write_io = sock_io_new(fd, chrc);
 
-	if (sock_io_send(chrc->write_io, op->data.iov_base,
-				op->data.iov_len) < 0)
-		goto retry;
+	while ((op = queue_peek_head(chrc->pending_writes)) != NULL) {
+		if (sock_io_send(chrc->write_io, op->data.iov_base,
+					op->data.iov_len) < 0)
+			goto retry;
 
-	gatt_db_attribute_write_result(op->attrib, op->id, 0);
+		gatt_db_attribute_write_result(op->attrib, op->id, 0);
+		pending_op_free(op);
+	}
 
 	return;
 
 retry:
-	send_write(op->device, op->attrib, chrc->proxy, NULL, op->id,
-				op->data.iov_base, op->data.iov_len, 0,
-				op->link_type, false, false);
+	/*
+	 * send_write pushes to chrc->pending_writes, so we need a
+	 * temporary queue to avoid an infinite loop.
+	 */
+	resend = queue_new();
+
+	while ((op = queue_pop_head(chrc->pending_writes)) != NULL)
+		queue_push_tail(resend, op);
+
+	while ((op = queue_pop_head(resend)) != NULL) {
+		send_write(op->device, op->attrib, chrc->proxy, NULL, op->id,
+					op->data.iov_base, op->data.iov_len, 0,
+					op->link_type, false, false);
+		pending_op_free(op);
+	}
+
+	queue_destroy(resend, NULL);
 }
 
 static void acquire_write_setup(DBusMessageIter *iter, void *user_data)
@@ -2527,14 +2545,18 @@ static struct pending_op *acquire_write(struct external_chrc *chrc,
 					uint8_t link_type)
 {
 	struct pending_op *op;
+	bool acquiring = !queue_isempty(chrc->pending_writes);
 
 	op = pending_write_new(device, chrc->pending_writes, attrib, id, value,
 				len, 0, link_type, false, false);
 
+	if (acquiring)
+		return op;
+
 	if (g_dbus_proxy_method_call(chrc->proxy, "AcquireWrite",
 					acquire_write_setup,
 					acquire_write_reply,
-					op, pending_op_free))
+					op, NULL))
 		return op;
 
 	pending_op_free(op);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-06-14 21:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-11 12:30 [PATCH BlueZ] gatt-database: No multiple calls to AcquireWrite Sebastian Urban
2021-06-11 12:53 ` [BlueZ] " bluez.test.bot
2021-06-11 22:31 ` [PATCH BlueZ] " Luiz Augusto von Dentz
2021-06-12  9:56   ` Sebastian Urban
2021-06-12 10:43     ` [BlueZ] " bluez.test.bot
2021-06-14 21:05       ` Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.