mirror of
				https://github.com/zeromq/libzmq.git
				synced 2025-10-29 20:59:47 +01:00 
			
		
		
		
	couple of bugs in shutdown mechanism fixed
This commit is contained in:
		| @@ -37,11 +37,11 @@ namespace zmq | |||||||
|             stop, |             stop, | ||||||
|             plug, |             plug, | ||||||
|             own, |             own, | ||||||
|  |             attach, | ||||||
|             bind, |             bind, | ||||||
|             term_req, |             term_req, | ||||||
|             term, |             term, | ||||||
|             term_ack |             term_ack | ||||||
|  |  | ||||||
|         } type; |         } type; | ||||||
|  |  | ||||||
|         union { |         union { | ||||||
| @@ -57,9 +57,14 @@ namespace zmq | |||||||
|  |  | ||||||
|             //  Sent to socket to let it know about the newly created object. |             //  Sent to socket to let it know about the newly created object. | ||||||
|             struct { |             struct { | ||||||
|                 class object_t *object; |                 class owned_t *object; | ||||||
|             } own; |             } own; | ||||||
|  |  | ||||||
|  |             //  Attach the engine to the session. | ||||||
|  |             struct { | ||||||
|  |                 class zmq_engine_t *engine; | ||||||
|  |             } attach; | ||||||
|  |  | ||||||
|             //  Sent between objects to establish pipe(s) between them. |             //  Sent between objects to establish pipe(s) between them. | ||||||
|             struct { |             struct { | ||||||
|             } bind; |             } bind; | ||||||
| @@ -67,7 +72,7 @@ namespace zmq | |||||||
|             //  Sent by I/O object ot the socket to request the shutdown of |             //  Sent by I/O object ot the socket to request the shutdown of | ||||||
|             //  the I/O object. |             //  the I/O object. | ||||||
|             struct { |             struct { | ||||||
|                 class object_t *object; |                 class owned_t *object; | ||||||
|             } term_req; |             } term_req; | ||||||
|  |  | ||||||
|             //  Sent by socket to I/O object to start its shutdown. |             //  Sent by socket to I/O object to start its shutdown. | ||||||
|   | |||||||
| @@ -22,6 +22,10 @@ | |||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
| #include "io_thread.hpp" | #include "io_thread.hpp" | ||||||
| #include "simple_semaphore.hpp" | #include "simple_semaphore.hpp" | ||||||
|  | #include "owned.hpp" | ||||||
|  | #include "session.hpp" | ||||||
|  | #include "socket_base.hpp" | ||||||
|  | #include "zmq_engine.hpp"  //  TODO: remove this line | ||||||
|  |  | ||||||
| zmq::object_t::object_t (dispatcher_t *dispatcher_, int thread_slot_) : | zmq::object_t::object_t (dispatcher_t *dispatcher_, int thread_slot_) : | ||||||
|     dispatcher (dispatcher_), |     dispatcher (dispatcher_), | ||||||
| @@ -65,6 +69,10 @@ void zmq::object_t::process_command (command_t &cmd_) | |||||||
|         process_own (cmd_.args.own.object); |         process_own (cmd_.args.own.object); | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|  |     case command_t::attach: | ||||||
|  |         process_attach (cmd_.args.attach.engine); | ||||||
|  |         return; | ||||||
|  |  | ||||||
|     case command_t::bind: |     case command_t::bind: | ||||||
|         process_bind (); |         process_bind (); | ||||||
|         return; |         return; | ||||||
| @@ -101,15 +109,18 @@ void zmq::object_t::send_stop () | |||||||
|     dispatcher->write (thread_slot, thread_slot, cmd); |     dispatcher->write (thread_slot, thread_slot, cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_plug (object_t *destination_) | void zmq::object_t::send_plug (owned_t *destination_) | ||||||
| { | { | ||||||
|  |     //  Let the object know that it cannot shut down till it gets this command. | ||||||
|  |     destination_->inc_seqnum (); | ||||||
|  |  | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
|     cmd.destination = destination_; |     cmd.destination = destination_; | ||||||
|     cmd.type = command_t::plug; |     cmd.type = command_t::plug; | ||||||
|     send_command (cmd); |     send_command (cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_own (object_t *destination_, object_t *object_) | void zmq::object_t::send_own (socket_base_t *destination_, owned_t *object_) | ||||||
| { | { | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
|     cmd.destination = destination_; |     cmd.destination = destination_; | ||||||
| @@ -118,6 +129,18 @@ void zmq::object_t::send_own (object_t *destination_, object_t *object_) | |||||||
|     send_command (cmd); |     send_command (cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void zmq::object_t::send_attach (session_t *destination_, zmq_engine_t *engine_) | ||||||
|  | { | ||||||
|  |     //  Let the object know that it cannot shut down till it gets this command. | ||||||
|  |     destination_->inc_seqnum (); | ||||||
|  |  | ||||||
|  |     command_t cmd; | ||||||
|  |     cmd.destination = destination_; | ||||||
|  |     cmd.type = command_t::attach; | ||||||
|  |     cmd.args.attach.engine = engine_; | ||||||
|  |     send_command (cmd); | ||||||
|  | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_bind (object_t *destination_) | void zmq::object_t::send_bind (object_t *destination_) | ||||||
| { | { | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
| @@ -126,7 +149,8 @@ void zmq::object_t::send_bind (object_t *destination_) | |||||||
|     send_command (cmd); |     send_command (cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_term_req (object_t *destination_, object_t *object_) | void zmq::object_t::send_term_req (socket_base_t *destination_, | ||||||
|  |     owned_t *object_) | ||||||
| { | { | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
|     cmd.destination = destination_; |     cmd.destination = destination_; | ||||||
| @@ -135,7 +159,7 @@ void zmq::object_t::send_term_req (object_t *destination_, object_t *object_) | |||||||
|     send_command (cmd); |     send_command (cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_term (object_t *destination_) | void zmq::object_t::send_term (owned_t *destination_) | ||||||
| { | { | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
|     cmd.destination = destination_; |     cmd.destination = destination_; | ||||||
| @@ -143,7 +167,7 @@ void zmq::object_t::send_term (object_t *destination_) | |||||||
|     send_command (cmd); |     send_command (cmd); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::send_term_ack (object_t *destination_) | void zmq::object_t::send_term_ack (socket_base_t *destination_) | ||||||
| { | { | ||||||
|     command_t cmd; |     command_t cmd; | ||||||
|     cmd.destination = destination_; |     cmd.destination = destination_; | ||||||
| @@ -161,7 +185,12 @@ void zmq::object_t::process_plug () | |||||||
|     zmq_assert (false); |     zmq_assert (false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::process_own (object_t *object_) | void zmq::object_t::process_own (owned_t *object_) | ||||||
|  | { | ||||||
|  |     zmq_assert (false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zmq::object_t::process_attach (zmq_engine_t *engine_) | ||||||
| { | { | ||||||
|     zmq_assert (false); |     zmq_assert (false); | ||||||
| } | } | ||||||
| @@ -171,7 +200,7 @@ void zmq::object_t::process_bind () | |||||||
|     zmq_assert (false); |     zmq_assert (false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::object_t::process_term_req (object_t *object_) | void zmq::object_t::process_term_req (owned_t *object_) | ||||||
| { | { | ||||||
|     zmq_assert (false); |     zmq_assert (false); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -49,20 +49,25 @@ namespace zmq | |||||||
|         //  Derived object can use these functions to send commands |         //  Derived object can use these functions to send commands | ||||||
|         //  to other objects. |         //  to other objects. | ||||||
|         void send_stop (); |         void send_stop (); | ||||||
|         void send_plug (object_t *destination_); |         void send_plug (class owned_t *destination_); | ||||||
|         void send_own (object_t *destination_, object_t *object_); |         void send_own (class socket_base_t *destination_, | ||||||
|  |             class owned_t *object_); | ||||||
|  |         void send_attach (class session_t *destination_, | ||||||
|  |             class zmq_engine_t *engine_); | ||||||
|         void send_bind (object_t *destination_); |         void send_bind (object_t *destination_); | ||||||
|         void send_term_req (object_t *destination_, object_t *object_); |         void send_term_req (class socket_base_t *destination_, | ||||||
|         void send_term (object_t *destination_); |             class owned_t *object_); | ||||||
|         void send_term_ack (object_t *destination_); |         void send_term (class owned_t *destination_); | ||||||
|  |         void send_term_ack (class socket_base_t *destination_); | ||||||
|  |  | ||||||
|         //  These handlers can be overloaded by the derived objects. They are |         //  These handlers can be overloaded by the derived objects. They are | ||||||
|         //  called when command arrives from another thread. |         //  called when command arrives from another thread. | ||||||
|         virtual void process_stop (); |         virtual void process_stop (); | ||||||
|         virtual void process_plug (); |         virtual void process_plug (); | ||||||
|         virtual void process_own (object_t *object_); |         virtual void process_own (class owned_t *object_); | ||||||
|  |         virtual void process_attach (class zmq_engine_t *engine_); | ||||||
|         virtual void process_bind (); |         virtual void process_bind (); | ||||||
|         virtual void process_term_req (object_t *object_); |         virtual void process_term_req (class owned_t *object_); | ||||||
|         virtual void process_term (); |         virtual void process_term (); | ||||||
|         virtual void process_term_ack (); |         virtual void process_term_ack (); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,11 +20,12 @@ | |||||||
| #include "owned.hpp" | #include "owned.hpp" | ||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
|  |  | ||||||
| zmq::owned_t::owned_t (object_t *parent_, object_t *owner_) : | zmq::owned_t::owned_t (object_t *parent_, socket_base_t *owner_) : | ||||||
|     object_t (parent_), |     object_t (parent_), | ||||||
|     owner (owner_), |     owner (owner_), | ||||||
|     plugged_in (false), |     sent_seqnum (0), | ||||||
|     terminated (false) |     processed_seqnum (0), | ||||||
|  |     shutting_down (false) | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -32,21 +33,18 @@ zmq::owned_t::~owned_t () | |||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void zmq::owned_t::inc_seqnum () | ||||||
|  | { | ||||||
|  |     //  NB: This function may be called from a different thread! | ||||||
|  |     sent_seqnum.add (1); | ||||||
|  | } | ||||||
|  |  | ||||||
| void zmq::owned_t::process_plug () | void zmq::owned_t::process_plug () | ||||||
| { | { | ||||||
|     zmq_assert (!plugged_in); |     //  Keep track of how many commands were processed so far. | ||||||
|  |     processed_seqnum++; | ||||||
|  |  | ||||||
|     //  If termination of the object was already requested, destroy it and |     finalise_command (); | ||||||
|     //  send the termination acknowledgement. |  | ||||||
|     if (terminated) { |  | ||||||
|         send_term_ack (owner); |  | ||||||
|         delete this; |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //  Notify the generic termination mechanism (io_object_t) that the object |  | ||||||
|     //  is already plugged in. |  | ||||||
|     plugged_in = true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::owned_t::term () | void zmq::owned_t::term () | ||||||
| @@ -56,19 +54,20 @@ void zmq::owned_t::term () | |||||||
|  |  | ||||||
| void zmq::owned_t::process_term () | void zmq::owned_t::process_term () | ||||||
| { | { | ||||||
|     zmq_assert (!terminated); |     zmq_assert (!shutting_down); | ||||||
|  |     shutting_down = true; | ||||||
|  |  | ||||||
|     //  If termination request has occured even before the object was plugged in |     finalise_command (); | ||||||
|     //  wait till plugging in happens, then acknowledge the termination. | } | ||||||
|     if (!plugged_in) { |  | ||||||
|         terminated = true; |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     //  Otherwise, destroy the object and acknowledge the termination | void zmq::owned_t::finalise_command () | ||||||
|     //  straight away. | { | ||||||
|  |     //  If termination request was already received and there are no more | ||||||
|  |     //  commands to wait for, terminate the object. | ||||||
|  |     if (shutting_down && processed_seqnum == sent_seqnum.get ()) { | ||||||
|         send_term_ack (owner); |         send_term_ack (owner); | ||||||
|         process_unplug (); |         process_unplug (); | ||||||
|         delete this; |         delete this; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,7 +20,9 @@ | |||||||
| #ifndef __ZMQ_OWNED_HPP_INCLUDED__ | #ifndef __ZMQ_OWNED_HPP_INCLUDED__ | ||||||
| #define __ZMQ_OWNED_HPP_INCLUDED__ | #define __ZMQ_OWNED_HPP_INCLUDED__ | ||||||
|  |  | ||||||
| #include "object.hpp" | #include "socket_base.hpp" | ||||||
|  | #include "atomic_counter.hpp" | ||||||
|  | #include "stdint.hpp" | ||||||
|  |  | ||||||
| namespace zmq | namespace zmq | ||||||
| { | { | ||||||
| @@ -34,7 +36,12 @@ namespace zmq | |||||||
|  |  | ||||||
|         //  The object will live in parent's thread, however, its lifetime |         //  The object will live in parent's thread, however, its lifetime | ||||||
|         //  will be managed by its owner socket. |         //  will be managed by its owner socket. | ||||||
|         owned_t (object_t *parent_, object_t *owner_); |         owned_t (object_t *parent_, socket_base_t *owner_); | ||||||
|  |  | ||||||
|  |         //  When another owned object wants to send command to this object | ||||||
|  |         //  it calls this function to let it know it should not shut down | ||||||
|  |         //  before the command is delivered. | ||||||
|  |         void inc_seqnum (); | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|  |  | ||||||
| @@ -57,21 +64,27 @@ namespace zmq | |||||||
|         //  classes to ensure sane cleanup. |         //  classes to ensure sane cleanup. | ||||||
|         virtual void process_unplug () = 0; |         virtual void process_unplug () = 0; | ||||||
|  |  | ||||||
|         //  Socket owning this object. It is responsible for destroying |         //  Socket owning this object. When the socket is being closed it's | ||||||
|         //  it when it's being closed. |         //  responsible for shutting down this object. | ||||||
|         object_t *owner; |         socket_base_t *owner; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|         //  Handlers for incoming commands. |         //  Handlers for incoming commands. | ||||||
|         void process_term (); |         void process_term (); | ||||||
|  |  | ||||||
|         //  Set to true when object is plugged in. |         //  Generic command handler (to be called from all command handlers | ||||||
|         bool plugged_in; |         //  once the processing is done). | ||||||
|  |         void finalise_command (); | ||||||
|  |  | ||||||
|         //  Set to true when object was terminated before it was plugged in. |         //  Sequence number of the last command sent to this object. | ||||||
|         //  In such case destruction is delayed till 'plug' command arrives. |         atomic_counter_t sent_seqnum; | ||||||
|         bool terminated; |  | ||||||
|  |         //  Sequence number of the last command processed by this object. | ||||||
|  |         uint64_t processed_seqnum; | ||||||
|  |  | ||||||
|  |         //  If true, the object is already shutting down. | ||||||
|  |         bool shutting_down; | ||||||
|  |  | ||||||
|         owned_t (const owned_t&); |         owned_t (const owned_t&); | ||||||
|         void operator = (const owned_t&); |         void operator = (const owned_t&); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ | |||||||
| #include "zmq_engine.hpp" | #include "zmq_engine.hpp" | ||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
|  |  | ||||||
| zmq::session_t::session_t (object_t *parent_, object_t *owner_, | zmq::session_t::session_t (object_t *parent_, socket_base_t *owner_, | ||||||
|       zmq_engine_t *engine_) : |       zmq_engine_t *engine_) : | ||||||
|     owned_t (parent_, owner_), |     owned_t (parent_, owner_), | ||||||
|     engine (engine_) |     engine (engine_) | ||||||
| @@ -48,11 +48,14 @@ void zmq::session_t::flush () | |||||||
|  |  | ||||||
| void zmq::session_t::process_plug () | void zmq::session_t::process_plug () | ||||||
| { | { | ||||||
|  |     zmq_assert (engine); | ||||||
|     engine->plug (this); |     engine->plug (this); | ||||||
|     owned_t::process_plug (); |     owned_t::process_plug (); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::session_t::process_unplug () | void zmq::session_t::process_unplug () | ||||||
| { | { | ||||||
|  |     zmq_assert (engine); | ||||||
|     engine->unplug (); |     engine->unplug (); | ||||||
|  |     delete engine; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ namespace zmq | |||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|         session_t (object_t *parent_, object_t *owner_, |         session_t (object_t *parent_, socket_base_t *owner_, | ||||||
|             class zmq_engine_t *engine_); |             class zmq_engine_t *engine_); | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|   | |||||||
| @@ -27,7 +27,9 @@ | |||||||
| #include "zmq_listener.hpp" | #include "zmq_listener.hpp" | ||||||
| #include "zmq_connecter.hpp" | #include "zmq_connecter.hpp" | ||||||
| #include "io_thread.hpp" | #include "io_thread.hpp" | ||||||
|  | #include "session.hpp" | ||||||
| #include "config.hpp" | #include "config.hpp" | ||||||
|  | #include "owned.hpp" | ||||||
|  |  | ||||||
| zmq::socket_base_t::socket_base_t (app_thread_t *parent_) : | zmq::socket_base_t::socket_base_t (app_thread_t *parent_) : | ||||||
|     object_t (parent_), |     object_t (parent_), | ||||||
| @@ -60,6 +62,9 @@ zmq::socket_base_t::~socket_base_t () | |||||||
|         while (pending_term_acks) |         while (pending_term_acks) | ||||||
|             app_thread->process_commands (true); |             app_thread->process_commands (true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     //  Check whether there are no session leaks. | ||||||
|  |     zmq_assert (sessions.empty ()); | ||||||
| } | } | ||||||
|  |  | ||||||
| int zmq::socket_base_t::setsockopt (int option_, void *optval_, | int zmq::socket_base_t::setsockopt (int option_, void *optval_, | ||||||
| @@ -169,12 +174,43 @@ int zmq::socket_base_t::close () | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::socket_base_t::process_own (object_t *object_) | void zmq::socket_base_t::register_session (const char *name_, | ||||||
|  |     session_t *session_) | ||||||
|  | { | ||||||
|  |     sessions_sync.lock (); | ||||||
|  |     bool inserted = sessions.insert (std::make_pair (name_, session_)).second; | ||||||
|  |     zmq_assert (inserted); | ||||||
|  |     sessions_sync.unlock (); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zmq::socket_base_t::unregister_session (const char *name_) | ||||||
|  | { | ||||||
|  |     sessions_sync.lock (); | ||||||
|  |     sessions_t::iterator it = sessions.find (name_); | ||||||
|  |     zmq_assert (it != sessions.end ()); | ||||||
|  |     sessions.erase (it); | ||||||
|  |     sessions_sync.unlock (); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | zmq::session_t *zmq::socket_base_t::get_session (const char *name_) | ||||||
|  | { | ||||||
|  |     sessions_sync.lock (); | ||||||
|  |     sessions_t::iterator it = sessions.find (name_); | ||||||
|  |     session_t *session = NULL; | ||||||
|  |     if (it != sessions.end ()) { | ||||||
|  |         session = it->second; | ||||||
|  |         session->inc_seqnum (); | ||||||
|  |     }    | ||||||
|  |     sessions_sync.unlock (); | ||||||
|  |     return session; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void zmq::socket_base_t::process_own (owned_t *object_) | ||||||
| { | { | ||||||
|     io_objects.insert (object_); |     io_objects.insert (object_); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::socket_base_t::process_term_req (object_t *object_) | void zmq::socket_base_t::process_term_req (owned_t *object_) | ||||||
| { | { | ||||||
|     //  If I/O object is well and alive ask it to terminate. |     //  If I/O object is well and alive ask it to terminate. | ||||||
|     io_objects_t::iterator it = std::find (io_objects.begin (), |     io_objects_t::iterator it = std::find (io_objects.begin (), | ||||||
|   | |||||||
| @@ -21,9 +21,11 @@ | |||||||
| #define __ZMQ_SOCKET_BASE_HPP_INCLUDED__ | #define __ZMQ_SOCKET_BASE_HPP_INCLUDED__ | ||||||
|  |  | ||||||
| #include <set> | #include <set> | ||||||
|  | #include <map> | ||||||
| #include <string> | #include <string> | ||||||
|  |  | ||||||
| #include "object.hpp" | #include "object.hpp" | ||||||
|  | #include "mutex.hpp" | ||||||
| #include "options.hpp" | #include "options.hpp" | ||||||
| #include "stdint.hpp" | #include "stdint.hpp" | ||||||
|  |  | ||||||
| @@ -46,16 +48,26 @@ namespace zmq | |||||||
|         virtual int recv (struct zmq_msg *msg_, int flags_); |         virtual int recv (struct zmq_msg *msg_, int flags_); | ||||||
|         virtual int close (); |         virtual int close (); | ||||||
|  |  | ||||||
|  |         //  Functions that owned objects use to manipulate socket's list | ||||||
|  |         //  of existing sessions. | ||||||
|  |         //  Note that this functionality cannot be implemented via inter-thread | ||||||
|  |         //  commands as it is unacceptable to wait for the completion of the | ||||||
|  |         //  action till user application yields control of the application | ||||||
|  |         //  thread to 0MQ. | ||||||
|  |         void register_session (const char *name_, class session_t *session_); | ||||||
|  |         void unregister_session (const char *name_); | ||||||
|  |         class session_t *get_session (const char *name_); | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|         //  Handlers for incoming commands. |         //  Handlers for incoming commands. | ||||||
|         void process_own (object_t *object_); |         void process_own (class owned_t *object_); | ||||||
|         void process_term_req (object_t *object_); |         void process_term_req (class owned_t *object_); | ||||||
|         void process_term_ack (); |         void process_term_ack (); | ||||||
|  |  | ||||||
|         //  List of all I/O objects owned by this socket. The socket is |         //  List of all I/O objects owned by this socket. The socket is | ||||||
|         //  responsible for deallocating them before it quits. |         //  responsible for deallocating them before it quits. | ||||||
|         typedef std::set <object_t*> io_objects_t; |         typedef std::set <class owned_t*> io_objects_t; | ||||||
|         io_objects_t io_objects; |         io_objects_t io_objects; | ||||||
|  |  | ||||||
|         //  Number of I/O objects that were already asked to terminate |         //  Number of I/O objects that were already asked to terminate | ||||||
| @@ -68,6 +80,14 @@ namespace zmq | |||||||
|         //  Socket options. |         //  Socket options. | ||||||
|         options_t options; |         options_t options; | ||||||
|  |  | ||||||
|  |         //  List of existing sessions. This list is never referenced from within | ||||||
|  |         //  the socket, instead it is used by I/O objects owned by the session. | ||||||
|  |         //  As those objects can live in different threads, the access is | ||||||
|  |         //  synchronised using 'sessions_sync' mutex. | ||||||
|  |         typedef std::map <std::string, session_t*> sessions_t; | ||||||
|  |         sessions_t sessions; | ||||||
|  |         mutex_t sessions_sync; | ||||||
|  |  | ||||||
|         socket_base_t (const socket_base_t&); |         socket_base_t (const socket_base_t&); | ||||||
|         void operator = (const socket_base_t&); |         void operator = (const socket_base_t&); | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ | |||||||
| #include "io_thread.hpp" | #include "io_thread.hpp" | ||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
|  |  | ||||||
| zmq::zmq_connecter_t::zmq_connecter_t (io_thread_t *parent_, object_t *owner_, | zmq::zmq_connecter_t::zmq_connecter_t (io_thread_t *parent_, | ||||||
|       const options_t &options_) : |       socket_base_t *owner_, const options_t &options_) : | ||||||
|     owned_t (parent_, owner_), |     owned_t (parent_, owner_), | ||||||
|     io_object_t (parent_), |     io_object_t (parent_), | ||||||
|     handle_valid (false), |     handle_valid (false), | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ namespace zmq | |||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|         zmq_connecter_t (class io_thread_t *parent_, object_t *owner_, |         zmq_connecter_t (class io_thread_t *parent_, socket_base_t *owner_, | ||||||
|             const options_t &options_); |             const options_t &options_); | ||||||
|  |  | ||||||
|         //  Set IP address to connect to. |         //  Set IP address to connect to. | ||||||
|   | |||||||
| @@ -73,7 +73,6 @@ void zmq::zmq_engine_t::in_event () | |||||||
|  |  | ||||||
|         //  Read as much data as possible to the read buffer. |         //  Read as much data as possible to the read buffer. | ||||||
|         insize = tcp_socket.read (inbuf, in_batch_size); |         insize = tcp_socket.read (inbuf, in_batch_size); | ||||||
| printf ("%d bytes read\n", (int) insize); |  | ||||||
|         inpos = 0; |         inpos = 0; | ||||||
|  |  | ||||||
|         //  Check whether the peer has closed the connection. |         //  Check whether the peer has closed the connection. | ||||||
| @@ -132,5 +131,5 @@ void zmq::zmq_engine_t::out_event () | |||||||
|  |  | ||||||
| void zmq::zmq_engine_t::error () | void zmq::zmq_engine_t::error () | ||||||
| { | { | ||||||
|     zmq_assert (false); | //    zmq_assert (false); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ | |||||||
| #include "session.hpp" | #include "session.hpp" | ||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
|  |  | ||||||
| zmq::zmq_init_t::zmq_init_t (io_thread_t *parent_, object_t *owner_, fd_t fd_, | zmq::zmq_init_t::zmq_init_t (io_thread_t *parent_, socket_base_t *owner_, | ||||||
|       bool connected_, const options_t &options_) : |       fd_t fd_, bool connected_, const options_t &options_) : | ||||||
|     owned_t (parent_, owner_), |     owned_t (parent_, owner_), | ||||||
|     connected (connected_), |     connected (connected_), | ||||||
|     options (options_) |     options (options_) | ||||||
| @@ -81,12 +81,14 @@ void zmq::zmq_init_t::flush () | |||||||
|  |  | ||||||
| void zmq::zmq_init_t::process_plug () | void zmq::zmq_init_t::process_plug () | ||||||
| { | { | ||||||
|  |     zmq_assert (engine); | ||||||
|     engine->plug (this); |     engine->plug (this); | ||||||
|     owned_t::process_plug (); |     owned_t::process_plug (); | ||||||
| } | } | ||||||
|  |  | ||||||
| void zmq::zmq_init_t::process_unplug () | void zmq::zmq_init_t::process_unplug () | ||||||
| { | { | ||||||
|  |     if (engine) | ||||||
|         engine->unplug (); |         engine->unplug (); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ namespace zmq | |||||||
|         //  Set 'connected' to true if the connection was created by 'connect' |         //  Set 'connected' to true if the connection was created by 'connect' | ||||||
|         //  function. If it was accepted from a listening socket, set it to |         //  function. If it was accepted from a listening socket, set it to | ||||||
|         //  false. |         //  false. | ||||||
|         zmq_init_t (class io_thread_t *parent_, object_t *owner_, fd_t fd_, |         zmq_init_t (class io_thread_t *parent_, socket_base_t *owner_, fd_t fd_, | ||||||
|             bool connected_, const options_t &options); |             bool connected_, const options_t &options); | ||||||
|         ~zmq_init_t (); |         ~zmq_init_t (); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ | |||||||
| #include "io_thread.hpp" | #include "io_thread.hpp" | ||||||
| #include "err.hpp" | #include "err.hpp" | ||||||
|  |  | ||||||
| zmq::zmq_listener_t::zmq_listener_t (io_thread_t *parent_, object_t *owner_, | zmq::zmq_listener_t::zmq_listener_t (io_thread_t *parent_, | ||||||
|       const options_t &options_) : |       socket_base_t *owner_, const options_t &options_) : | ||||||
|     owned_t (parent_, owner_), |     owned_t (parent_, owner_), | ||||||
|     io_object_t (parent_), |     io_object_t (parent_), | ||||||
|     options (options_) |     options (options_) | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ namespace zmq | |||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|         zmq_listener_t (class io_thread_t *parent_, object_t *owner_, |         zmq_listener_t (class io_thread_t *parent_, socket_base_t *owner_, | ||||||
|             const options_t &options_); |             const options_t &options_); | ||||||
|  |  | ||||||
|         //  Set IP address to listen on. |         //  Set IP address to listen on. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Martin Sustrik
					Martin Sustrik