Here is a better description of the problem and a possible fix that Vlad
can use and discard, as he surely better understand this part.

Sorry for some imprecision in my previous description.

Jaybird synchronized the op_queue_events send/response.

Remote queue_events synchronizes with the *sync* port lock.

When event callback is called by the engine, before delivery the event,
remote marks it as dead (event->rvnt_iface = NULL) but using the *async*
port lock.

Even the different locks (sync / async) is not the underling problem by
the way events are marked and verified as dead.

But after event is marked as dead, que_events can concurrently reuse it,
and reuse its rvnt_id.

The problem is that the callback reads rvnt_id after mark it as dead.

So here is my proposed patch.


Adriano

diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp
index 8c5662e..e5bb59c 100644
--- a/src/remote/server/server.cpp
+++ b/src/remote/server/server.cpp
@@ -917,6 +917,8 @@ public:
 		if (!allowCancel)
 			return;
 
+		SLONG rvnt_id = event->rvnt_id;
+
 		if (event->rvnt_iface)
 		{
 			LocalStatus ls;
@@ -934,7 +936,7 @@ public:
 		p_event->p_event_database = rdb->rdb_id;
 		p_event->p_event_items.cstr_length = length;
 		p_event->p_event_items.cstr_address = items;
-		p_event->p_event_rid = event->rvnt_id;
+		p_event->p_event_rid = rvnt_id;
 
 		port->send(&packet);
 	}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to