Line data Source code
1 :
2 : /* Copyright (c) 2006-2014, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2011, Cedric Stalder <cedric.stalder@gmail.com>
4 : *
5 : * This file is part of Collage <https://github.com/Eyescale/Collage>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : #ifndef CO_BARRIER_H
22 : #define CO_BARRIER_H
23 :
24 : #include <co/object.h> // base class
25 : #include <co/types.h>
26 :
27 : namespace co
28 : {
29 : namespace detail { class Barrier; }
30 :
31 : /**
32 : * A networked, versioned barrier.
33 : *
34 : * On a given LocalNode only one instance of a given barrier can be mapped,
35 : * i.e., multiple instances of the same barrier are currently not supported by
36 : * the implementation. Not intended to be subclassed.
37 : */
38 : class Barrier : public Object
39 : {
40 : public:
41 : #ifdef COLLAGE_V1_API
42 : /** @deprecated Does not register or map barrier. */
43 : CO_API Barrier( NodePtr master = 0, const uint32_t height = 0 );
44 : #endif
45 :
46 : /**
47 : * Construct and register a new distributed barrier.
48 : *
49 : * Barriers are versioned, distributed objects. This constructor creates and
50 : * registers the barrier with its LocalNode. Other processes contributing to
51 : * the barrier use the other constructor to create and map an instance to
52 : * this master version.
53 : *
54 : * The master node will maintain the barrier state. It has to be reachable
55 : * from all other nodes participating in the barrier. If the master node
56 : * identifier is not an UUID, the local node is used as the master.
57 : *
58 : * Note that the node of the object master, i.e., the instance which is
59 : * registered through this constructor, and the barrier's master node may be
60 : * different. The barriers master node maintains the barrier state. The user
61 : * of the barrier has to ensure that the given master node has at least one
62 : * instance of the barrier.
63 : *
64 : * @param localNode the local node to register the barrier with.
65 : * @param masterNodeID the master node identifier.
66 : * @param height the initial group size for the barrier.
67 : * @sa isGood()
68 : * @version 1.1.1
69 : */
70 : CO_API Barrier( LocalNodePtr localNode,
71 : const uint128_t& masterNodeID,
72 : const uint32_t height = 0 );
73 :
74 : /**
75 : * Construct and join a distributed barrier.
76 : *
77 : * @param localNode the local node to map the barrier to
78 : * @param barrier the identifier and version of the barrier
79 : * @sa isGood()
80 : * @version 1.1.1
81 : */
82 : CO_API Barrier( LocalNodePtr localNode, const ObjectVersion& barrier );
83 :
84 : /** Destruct the barrier. @version 1.0 */
85 : CO_API virtual ~Barrier();
86 :
87 : /**
88 : * @name Data Access
89 : *
90 : * After a change, the barrier has to be committed and synced to the same
91 : * version on all nodes entering the barrier.
92 : */
93 : //@{
94 : /** @return true if the barrier was created successfully. @version 1.1.1 */
95 428 : bool isGood() const { return isAttached(); }
96 :
97 : /** Set the number of participants in the barrier. @version 1.0 */
98 : CO_API void setHeight( const uint32_t height );
99 :
100 : /** Add one participant to the barrier. @version 1.0 */
101 : CO_API void increase();
102 :
103 : /** @return the number of participants. @version 1.0 */
104 : CO_API uint32_t getHeight() const;
105 : //@}
106 :
107 : /** @name Operations */
108 : //@{
109 : /**
110 : * Enter the barrier, blocks until the barrier has been reached.
111 : *
112 : * The implementation currently assumes that the master node instance
113 : * also enters the barrier. If a timeout happens a timeout exception is
114 : * thrown.
115 : * @version 1.0
116 : */
117 : CO_API void enter( const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
118 : //@}
119 :
120 : protected:
121 : /** @internal */
122 : //@{
123 : void attach( const uint128_t& id, const uint32_t instanceID ) override;
124 31 : ChangeType getChangeType() const override { return DELTA; }
125 :
126 : void getInstanceData( DataOStream& os ) override;
127 : void applyInstanceData( DataIStream& is ) override;
128 : void pack( DataOStream& os ) override;
129 : void unpack( DataIStream& is ) override;
130 : //@}
131 :
132 : private:
133 : detail::Barrier* const _impl;
134 :
135 : void _cleanup( const uint64_t time );
136 : void _sendNotify( const uint128_t& version, NodePtr node );
137 :
138 : /* The command handlers. */
139 : bool _cmdEnter( ICommand& command );
140 : bool _cmdEnterReply( ICommand& command );
141 :
142 62 : LB_TS_VAR( _thread );
143 : };
144 : }
145 :
146 : #endif // CO_BARRIER_H
|