Hi Martin,

On Tue, Nov 23, 2010 at 5:49 AM, Martin Sustrik <sust...@250bpm.com> wrote:
> Dhammika,
>
>> I donno, may be we should simplify this.
>> Why don't we add a refcount?
>
> As a quick workaround -- yes. Do you have a patch for that kind of solution?
>
> However, thinking about it conceptually, the problem is more generic.
> Namely, object A can call object B which in turn calls object A. In such a
> scenario, the inner call on A works on inconsistent state as the outer call
> isn't yet completed. Other way round, outer call on A gets the state changed
> underneath its feet when it calls B (see seq1.png attached).
>
> The real solution, IMO, would be to use events to sequence actions on
> individual objects. That way there won't be inner and outer call, rather,
> there will be two event handlers executed one after another (see seq2.png).
>


Patch attached.
This should be ok for now, but we may want a more elegant solution.
I'm not sure about adding another event api for internal events, we already have
complains on running out of socket descriptors and stuffed mailboxes.

BTW do you guys have a separate test setup?
We really need more tests, can we pull tests from git tickets?




>From e4e1780a0b674e4539cfba9bf2ef432e400a5673 Mon Sep 17 00:00:00 2001
From: dhammika <dhamm...@gmail.com>
Date: Thu, 2 Dec 2010 22:29:57 -0800
Subject: [PATCH 1/1] fix race condition in session init


Signed-off-by: dhammika <dhamm...@gmail.com>
---
 src/i_engine.hpp   |    3 +++
 src/zmq_engine.cpp |   14 +++++++++++++-
 src/zmq_engine.hpp |    2 ++
 src/zmq_init.cpp   |    5 ++---
 4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/i_engine.hpp b/src/i_engine.hpp
index 682ee8e..c69c0cc 100644
--- a/src/i_engine.hpp
+++ b/src/i_engine.hpp
@@ -45,6 +45,9 @@ namespace zmq
         //  This method is called by the session to signalise that there
         //  are messages to send available.
         virtual void activate_out () = 0;
+
+        //  Engine is about to move to a different IO thread.
+        virtual void dispatch() = 0;
     };

 }
diff --git a/src/zmq_engine.cpp b/src/zmq_engine.cpp
index 0c1070d..f32eff5 100644
--- a/src/zmq_engine.cpp
+++ b/src/zmq_engine.cpp
@@ -41,7 +41,8 @@ zmq::zmq_engine_t::zmq_engine_t (fd_t fd_, const
options_t &options_) :
     encoder (out_batch_size),
     inout (NULL),
     options (options_),
-    plugged (false)
+    plugged (false),
+    ephemeral (false)
 {
     //  Initialise the underlying socket.
     int rc = tcp_socket.open (fd_, options.sndbuf, options.rcvbuf);
@@ -152,6 +153,12 @@ void zmq::zmq_engine_t::out_event ()

         outpos = NULL;
         encoder.get_data (&outpos, &outsize);
+
+        if (ephemeral) {
+            ephemeral = false;
+            inout->flush ();
+            return;
+        }

         //  If there is no data to send, stop polling for output.
         if (outsize == 0) {
@@ -193,6 +200,11 @@ void zmq::zmq_engine_t::activate_in ()
     in_event ();
 }

+void zmq::zmq_engine_t::dispatch ()
+{
+    ephemeral = true;
+}
+
 void zmq::zmq_engine_t::error ()
 {Patch attached

     zmq_assert (inout);
diff --git a/src/zmq_engine.hpp b/src/zmq_engine.hpp
index c5f95dc..46f9406 100644
--- a/src/zmq_engine.hpp
+++ b/src/zmq_engine.hpp
@@ -47,6 +47,7 @@ namespace zmq
         void terminate ();
         void activate_in ();
         void activate_out ();
+        void dispatch ();

         //  i_poll_events interface implementation.
         void in_event ();
@@ -73,6 +74,7 @@ namespace zmq
         options_t options;

         bool plugged;
+        bool ephemeral;

         zmq_engine_t (const zmq_engine_t&);
         void operator = (const zmq_engine_t&);
diff --git a/src/zmq_init.cpp b/src/zmq_init.cpp
index a796faa..d5cde52 100644
--- a/src/zmq_init.cpp
+++ b/src/zmq_init.cpp
@@ -64,9 +64,8 @@ bool zmq::zmq_init_t::read (::zmq_msg_t *msg_)
         options.identity.size ());
     sent = true;

-    //  If initialisation is done, pass the engine to the session and
-    //  destroy the init object.
-    finalise_initialisation ();
+    //  Initialization is done, dispatch engine.
+    engine->dispatch ();

     return true;
 }
-- 
1.7.0.4




Dhammika
_______________________________________________
zeromq-dev mailing list
zeromq-dev@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to