Line data Source code
1 :
2 : /* Copyright (c) 2010-2014, Stefan Eilemann <eile@eyescale.ch>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef EQSERVER_CONFIGUPDATESYNCVISITOR_H
19 : #define EQSERVER_CONFIGUPDATESYNCVISITOR_H
20 :
21 : #include "configVisitor.h" // base class
22 :
23 : namespace eq
24 : {
25 : namespace server
26 : {
27 : namespace
28 : {
29 : class ConfigUpdateSyncVisitor : public ConfigVisitor
30 : {
31 : public:
32 4 : ConfigUpdateSyncVisitor()
33 4 : : _runningChannels(0)
34 : , _failure(false)
35 4 : , _sync(false)
36 : {
37 4 : }
38 4 : virtual ~ConfigUpdateSyncVisitor() {}
39 4 : VisitorResult visitPre(Config*) override
40 : {
41 4 : _runningChannels = 0;
42 4 : _failure = false;
43 4 : _sync = false;
44 4 : return TRAVERSE_CONTINUE;
45 : }
46 :
47 4 : VisitorResult visitPre(Node* node) override { return _updateDown(node); }
48 4 : VisitorResult visitPost(Node* node) override
49 : {
50 4 : const VisitorResult& result = _updateUp(node);
51 4 : node->flushSendBuffer();
52 4 : return result;
53 : }
54 :
55 8 : VisitorResult visitPre(Pipe* pipe) override { return _updateDown(pipe); }
56 8 : VisitorResult visitPost(Pipe* pipe) override { return _updateUp(pipe); }
57 8 : VisitorResult visitPre(Window* window) override
58 : {
59 8 : return _updateDown(window);
60 : }
61 8 : VisitorResult visitPost(Window* window) override
62 : {
63 8 : return _updateUp(window);
64 : }
65 :
66 36 : VisitorResult visit(Channel* channel) override
67 : {
68 36 : const VisitorResult result = _updateUp(channel);
69 36 : if (channel->isRunning())
70 4 : ++_runningChannels;
71 36 : return result;
72 : }
73 :
74 4 : size_t getNumRunningChannels() const { return _runningChannels; }
75 4 : bool hadFailure() const { return _failure; }
76 4 : bool needsSync() const { return _sync; }
77 : private:
78 : size_t _runningChannels;
79 : bool _failure;
80 : bool _sync; // call again after init failure
81 :
82 : template <class T>
83 20 : VisitorResult _updateDown(T* entity) const
84 : {
85 20 : const uint32_t state = entity->getState() & ~STATE_DELETE;
86 20 : switch (state)
87 : {
88 : case STATE_INITIALIZING:
89 : case STATE_INIT_FAILED:
90 : case STATE_INIT_SUCCESS:
91 : case STATE_EXITING:
92 : case STATE_EXIT_FAILED:
93 : case STATE_EXIT_SUCCESS:
94 : case STATE_RUNNING:
95 20 : return TRAVERSE_CONTINUE;
96 :
97 : case STATE_STOPPED:
98 : case STATE_FAILED:
99 0 : return TRAVERSE_PRUNE;
100 : }
101 0 : LBUNREACHABLE;
102 0 : return TRAVERSE_PRUNE;
103 : }
104 :
105 : template <class T>
106 56 : VisitorResult _updateUp(T* entity)
107 : {
108 56 : const uint32_t state = entity->getState() & ~STATE_DELETE;
109 56 : switch (state)
110 : {
111 : case STATE_INITIALIZING:
112 : case STATE_INIT_FAILED:
113 : case STATE_INIT_SUCCESS:
114 14 : if (!entity->syncConfigInit())
115 : {
116 0 : entity->sync();
117 0 : _failure = true;
118 0 : _sync = true;
119 0 : LBWARN << lunchbox::className(entity) << " init failed"
120 0 : << std::endl;
121 : }
122 : else
123 14 : entity->sync();
124 14 : return TRAVERSE_CONTINUE;
125 :
126 : case STATE_EXITING:
127 : case STATE_EXIT_FAILED:
128 : case STATE_EXIT_SUCCESS:
129 14 : if (!entity->syncConfigExit())
130 : {
131 0 : entity->sync();
132 0 : _failure = true;
133 0 : LBWARN << lunchbox::className(entity) << " exit failed"
134 0 : << std::endl;
135 : }
136 : else
137 14 : entity->sync();
138 14 : return TRAVERSE_CONTINUE;
139 :
140 : case STATE_RUNNING:
141 : case STATE_STOPPED:
142 : case STATE_FAILED:
143 28 : return TRAVERSE_CONTINUE;
144 : }
145 0 : LBUNREACHABLE;
146 0 : return TRAVERSE_PRUNE;
147 : }
148 : };
149 : }
150 : }
151 : }
152 :
153 : #endif // EQSERVER_CONFIGUPDATESYNCVISITOR_H
|