Line data Source code
1 :
2 : /* Copyright (c) 2006-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Daniel Nachbaur <danielnachbaur@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 : #include "iCommand.h"
22 :
23 : #include "buffer.h"
24 : #include "localNode.h"
25 : #include "node.h"
26 : #include <pression/data/CompressorInfo.h>
27 :
28 : namespace co
29 : {
30 : namespace detail
31 : {
32 5625633 : class ICommand
33 : {
34 : public:
35 1127383 : ICommand()
36 1127383 : : func(0, 0)
37 : , buffer(0)
38 : , size(0)
39 : , type(COMMANDTYPE_INVALID)
40 : , cmd(CMD_INVALID)
41 1127383 : , consumed(false)
42 : {
43 1127374 : }
44 :
45 115962 : ICommand(LocalNodePtr local_, NodePtr remote_, ConstBufferPtr buffer_)
46 115962 : : local(local_)
47 : , remote(remote_)
48 : , func(0, 0)
49 : , buffer(buffer_)
50 : , size(0)
51 : , type(COMMANDTYPE_INVALID)
52 : , cmd(CMD_INVALID)
53 115962 : , consumed(false)
54 : {
55 115962 : }
56 :
57 371713 : void clear() { *this = ICommand(); }
58 : LocalNodePtr local; //!< The node receiving the command
59 : NodePtr remote; //!< The node sending the command
60 : co::Dispatcher::Func func;
61 : ConstBufferPtr buffer;
62 : uint64_t size;
63 : uint32_t type;
64 : uint32_t cmd;
65 : bool consumed;
66 : };
67 : } // detail namespace
68 :
69 755658 : ICommand::ICommand()
70 : : DataIStream()
71 755658 : , _impl(new detail::ICommand)
72 : {
73 755661 : }
74 :
75 115962 : ICommand::ICommand(LocalNodePtr local, NodePtr remote, ConstBufferPtr buffer)
76 : : DataIStream()
77 115962 : , _impl(new detail::ICommand(local, remote, buffer))
78 : {
79 115962 : if (_impl->buffer)
80 : {
81 115961 : LBASSERT(buffer->getSize() >= sizeof(_impl->size) +
82 : sizeof(_impl->type) +
83 : sizeof(_impl->cmd));
84 :
85 115961 : *this >> _impl->size >> _impl->type >> _impl->cmd;
86 : }
87 115962 : }
88 :
89 1757903 : ICommand::ICommand(const ICommand& rhs)
90 : : DataIStream()
91 1757903 : , _impl(new detail::ICommand(*rhs._impl))
92 : {
93 1757904 : _impl->consumed = false;
94 1757904 : _skipHeader();
95 1757900 : }
96 :
97 570039 : ICommand& ICommand::operator=(const ICommand& rhs)
98 : {
99 570039 : if (this != &rhs)
100 : {
101 570045 : *_impl = *rhs._impl;
102 570060 : _impl->consumed = false;
103 570060 : _skipHeader();
104 : }
105 569951 : return *this;
106 : }
107 :
108 5177391 : ICommand::~ICommand()
109 : {
110 2551608 : delete _impl;
111 2624153 : }
112 :
113 371713 : void ICommand::clear()
114 : {
115 371713 : _impl->clear();
116 371713 : }
117 :
118 2325795 : void ICommand::_skipHeader()
119 : {
120 : const size_t headerSize =
121 2325795 : sizeof(_impl->size) + sizeof(_impl->type) + sizeof(_impl->cmd);
122 2325795 : if (isValid() && getRemainingBufferSize() >= headerSize)
123 2290633 : getRemainingBuffer(headerSize);
124 2300648 : }
125 :
126 72190 : uint32_t ICommand::getType() const
127 : {
128 72190 : return _impl->type;
129 : }
130 :
131 643752 : uint32_t ICommand::getCommand() const
132 : {
133 643752 : return _impl->cmd;
134 : }
135 :
136 638973 : uint64_t ICommand::getSize() const
137 : {
138 638973 : return _impl->size;
139 : }
140 :
141 43889 : void ICommand::setType(const CommandType type)
142 : {
143 43889 : _impl->type = type;
144 43889 : }
145 :
146 43949 : void ICommand::setCommand(const uint32_t cmd)
147 : {
148 43949 : _impl->cmd = cmd;
149 43949 : }
150 :
151 621518 : void ICommand::setDispatchFunction(const Dispatcher::Func& func)
152 : {
153 621518 : _impl->func = func;
154 621518 : }
155 :
156 0 : ConstBufferPtr ICommand::getBuffer() const
157 : {
158 0 : LBASSERT(_impl->buffer);
159 0 : return _impl->buffer;
160 : }
161 :
162 0 : size_t ICommand::nRemainingBuffers() const
163 : {
164 0 : return _impl->buffer ? 1 : 0;
165 : }
166 :
167 0 : uint128_t ICommand::getVersion() const
168 : {
169 0 : return VERSION_NONE;
170 : }
171 :
172 2390494 : bool ICommand::getNextBuffer(CompressorInfo& info, uint32_t& nChunks,
173 : const void*& chunkData, uint64_t& size)
174 : {
175 2390494 : if (_impl->consumed) // 2nd call
176 0 : _impl->buffer = 0;
177 :
178 2390494 : if (!_impl->buffer)
179 0 : return false;
180 :
181 2390403 : _impl->consumed = true;
182 2390403 : chunkData = _impl->buffer->getData();
183 2396076 : size = reinterpret_cast<const uint64_t*>(chunkData)[0];
184 2396076 : info = CompressorInfo();
185 2392329 : nChunks = 1;
186 2392329 : return true;
187 : }
188 :
189 216560 : NodePtr ICommand::getRemoteNode() const
190 : {
191 216560 : return _impl->remote;
192 : }
193 :
194 0 : LocalNodePtr ICommand::getLocalNode() const
195 : {
196 0 : return _impl->local;
197 : }
198 :
199 4021498 : bool ICommand::isValid() const
200 : {
201 12042961 : return _impl->buffer && !_impl->buffer->isEmpty() &&
202 16033559 : _impl->type != COMMANDTYPE_INVALID && _impl->cmd != CMD_INVALID &&
203 8011763 : _impl->size > 0;
204 : }
205 :
206 621467 : bool ICommand::operator()()
207 : {
208 621467 : LBASSERT(_impl->func.isValid());
209 621456 : Dispatcher::Func func = _impl->func;
210 621456 : _impl->func.clear();
211 621457 : return func(*this);
212 : }
213 :
214 0 : std::ostream& operator<<(std::ostream& os, const ICommand& command)
215 : {
216 0 : ConstBufferPtr buffer = command.getBuffer();
217 0 : if (buffer)
218 0 : os << lunchbox::disableFlush << "command< type "
219 0 : << uint32_t(command.getType()) << " cmd " << command.getCommand()
220 0 : << " size " << command.getSize() << '/' << buffer->getSize() << '/'
221 0 : << buffer->getMaxSize() << " from " << command.getNode() << " to "
222 0 : << command.getLocalNode() << " >" << lunchbox::enableFlush;
223 : else
224 0 : os << "command< empty >";
225 :
226 0 : if (command._impl->func.isValid())
227 0 : os << ' ' << command._impl->func << std::endl;
228 0 : return os;
229 : }
230 63 : }
|