1/*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28*/
29
30#ifndef __ZMQ_OWN_HPP_INCLUDED__
31#define __ZMQ_OWN_HPP_INCLUDED__
32
33#include <set>
34
35#include "object.hpp"
36#include "options.hpp"
37#include "atomic_counter.hpp"
38#include "stdint.hpp"
39
40namespace zmq
41{
42class ctx_t;
43class io_thread_t;
44
45// Base class for objects forming a part of ownership hierarchy.
46// It handles initialisation and destruction of such objects.
47
48class own_t : public object_t
49{
50 public:
51 // Note that the owner is unspecified in the constructor.
52 // It'll be supplied later on when the object is plugged in.
53
54 // The object is not living within an I/O thread. It has it's own
55 // thread outside of 0MQ infrastructure.
56 own_t (zmq::ctx_t *parent_, uint32_t tid_);
57
58 // The object is living within I/O thread.
59 own_t (zmq::io_thread_t *io_thread_, const options_t &options_);
60
61 // When another owned object wants to send command to this object
62 // it calls this function to let it know it should not shut down
63 // before the command is delivered.
64 void inc_seqnum ();
65
66 // Use following two functions to wait for arbitrary events before
67 // terminating. Just add number of events to wait for using
68 // register_tem_acks functions. When event occurs, call
69 // remove_term_ack. When number of pending acks reaches zero
70 // object will be deallocated.
71 void register_term_acks (int count_);
72 void unregister_term_ack ();
73
74 protected:
75 // Launch the supplied object and become its owner.
76 void launch_child (own_t *object_);
77
78 // Terminate owned object
79 void term_child (own_t *object_);
80
81 // Ask owner object to terminate this object. It may take a while
82 // while actual termination is started. This function should not be
83 // called more than once.
84 void terminate ();
85
86 // Returns true if the object is in process of termination.
87 bool is_terminating ();
88
89 // Derived object destroys own_t. There's no point in allowing
90 // others to invoke the destructor. At the same time, it has to be
91 // virtual so that generic own_t deallocation mechanism destroys
92 // specific type of the owned object correctly.
93 virtual ~own_t ();
94
95 // Term handler is protected rather than private so that it can
96 // be intercepted by the derived class. This is useful to add custom
97 // steps to the beginning of the termination process.
98 void process_term (int linger_);
99
100 // A place to hook in when physical destruction of the object
101 // is to be delayed.
102 virtual void process_destroy ();
103
104 // Socket options associated with this object.
105 options_t options;
106
107 private:
108 // Set owner of the object
109 void set_owner (own_t *owner_);
110
111 // Handlers for incoming commands.
112 void process_own (own_t *object_);
113 void process_term_req (own_t *object_);
114 void process_term_ack ();
115 void process_seqnum ();
116
117 // Check whether all the pending term acks were delivered.
118 // If so, deallocate this object.
119 void check_term_acks ();
120
121 // True if termination was already initiated. If so, we can destroy
122 // the object if there are no more child objects or pending term acks.
123 bool _terminating;
124
125 // Sequence number of the last command sent to this object.
126 atomic_counter_t _sent_seqnum;
127
128 // Sequence number of the last command processed by this object.
129 uint64_t _processed_seqnum;
130
131 // Socket owning this object. It's responsible for shutting down
132 // this object.
133 own_t *_owner;
134
135 // List of all objects owned by this socket. We are responsible
136 // for deallocating them before we quit.
137 typedef std::set<own_t *> owned_t;
138 owned_t _owned;
139
140 // Number of events we have to get before we can destroy the object.
141 int _term_acks;
142
143 ZMQ_NON_COPYABLE_NOR_MOVABLE (own_t)
144};
145}
146
147#endif
148