own.hpp 4.83 KB
Newer Older
1
/*
2 3
    Copyright (c) 2007-2011 iMatix Corporation
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
4 5 6 7

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
8
    the terms of the GNU Lesser General Public License as published by
9 10 11 12 13 14
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    0MQ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU Lesser General Public License for more details.
16

17
    You should have received a copy of the GNU Lesser General Public License
18 19 20 21 22 23 24 25 26 27
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __ZMQ_OWN_HPP_INCLUDED__
#define __ZMQ_OWN_HPP_INCLUDED__

#include <set>
#include <algorithm>

#include "object.hpp"
28
#include "options.hpp"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#include "atomic_counter.hpp"
#include "stdint.hpp"

namespace zmq
{

    //  Base class for objects forming a part of ownership hierarchy.
    //  It handles initialisation and destruction of such objects.

    class own_t : public object_t
    {
    public:

        //  Note that the owner is unspecified in the constructor.
        //  It'll be supplied later on when the object is plugged in.

        //  The object is not living within an I/O thread. It has it's own
        //  thread outside of 0MQ infrastructure.
Martin Sustrik's avatar
Martin Sustrik committed
47
        own_t (class ctx_t *parent_, uint32_t tid_);
48 49

        //  The object is living within I/O thread.
50
        own_t (class io_thread_t *io_thread_, const options_t &options_);
51 52 53 54 55 56

        //  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 ();

57 58 59 60 61 62 63 64
        //  Use following two functions to wait for arbitrary events before
        //  terminating. Just add number of events to wait for using
        //  register_tem_acks functions. When event occurs, call
        //  remove_term_ack. When number of pending acks reaches zero
        //  object will be deallocated.
        void register_term_acks (int count_);
        void unregister_term_ack ();

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    protected:

        //  Launch the supplied object and become its owner.
        void launch_child (own_t *object_);

        //  Launch the supplied object and make it your sibling (make your
        //  owner become its owner as well).
        void launch_sibling (own_t *object_);

        //  Ask owner object to terminate this object. It may take a while
        //  while actual termination is started. This function should not be
        //  called more than once.
        void terminate ();

        //  Derived object destroys own_t. There's no point in allowing
        //  others to invoke the destructor. At the same time, it has to be
        //  virtual so that generic own_t deallocation mechanism destroys
        //  specific type of the owned object correctly.
        virtual ~own_t ();

        //  Term handler is protocted rather than private so that it can
        //  be intercepted by the derived class. This is useful to add custom
        //  steps to the beginning of the termination process.
88
        void process_term (int linger_);
89

90 91 92 93
        //  A place to hook in when phyicallal destruction of the object
        //  is to be delayed.
        virtual void process_destroy ();

94 95 96
        //  Socket options associated with this object.
        options_t options;

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    private:

        //  Set owner of the object
        void set_owner (own_t *owner_);

        //  Handlers for incoming commands.
        void process_own (own_t *object_);
        void process_term_req (own_t *object_);
        void process_term_ack ();
        void process_seqnum ();

        //  Check whether all the peding term acks were delivered.
        //  If so, deallocate this object.
        void check_term_acks ();

        //  True if termination was already initiated. If so, we can destroy
        //  the object if there are no more child objects or pending term acks.
        bool terminating;

        //  Sequence number of the last command sent to this object.
        atomic_counter_t sent_seqnum;

        //  Sequence number of the last command processed by this object.
        uint64_t processed_seqnum;

        //  Socket owning this object. It's responsible for shutting down
        //  this object.
        own_t *owner;

        //  List of all objects owned by this socket. We are responsible
        //  for deallocating them before we quit.
        typedef std::set <own_t*> owned_t;
        owned_t owned;

        //  Number of events we have to get before we can destroy the object.
        int term_acks;

        own_t (const own_t&);
135
        const own_t &operator = (const own_t&);
136 137 138 139 140
    };

}

#endif