Line data Source code
1 :
2 : /* Copyright (c) 2005-2016, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Daniel Nachbaur <danielnachbaur@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "server.h"
20 :
21 : #include "client.h"
22 : #include "config.h"
23 : #include "global.h"
24 : #include "nodeFactory.h"
25 : #include "types.h"
26 :
27 : #include <eq/fabric/commands.h>
28 : #include <eq/fabric/configParams.h>
29 :
30 : #include <co/connection.h>
31 : #include <co/iCommand.h>
32 :
33 : #include <algorithm>
34 :
35 : #pragma clang diagnostic ignored "-Wunused-private-field" // _impl is unused
36 :
37 : namespace eq
38 : {
39 : typedef co::CommandFunc<Server> CmdFunc;
40 : typedef fabric::Server<Client, Server, Config, NodeFactory, co::Node,
41 : ServerVisitor>
42 : Super;
43 :
44 1 : Server::Server()
45 : : Super(Global::getNodeFactory())
46 1 : , _impl(0)
47 : {
48 1 : }
49 :
50 2 : Server::~Server()
51 : {
52 2 : }
53 :
54 2 : void Server::setClient(ClientPtr client)
55 : {
56 2 : Super::setClient(client);
57 2 : if (!client)
58 1 : return;
59 :
60 1 : co::CommandQueue* queue = client->getMainThreadQueue();
61 1 : registerCommand(fabric::CMD_SERVER_CHOOSE_CONFIG_REPLY,
62 2 : CmdFunc(this, &Server::_cmdChooseConfigReply), queue);
63 1 : registerCommand(fabric::CMD_SERVER_RELEASE_CONFIG_REPLY,
64 2 : CmdFunc(this, &Server::_cmdReleaseConfigReply), queue);
65 1 : registerCommand(fabric::CMD_SERVER_SHUTDOWN_REPLY,
66 2 : CmdFunc(this, &Server::_cmdShutdownReply), queue);
67 : }
68 :
69 17 : co::CommandQueue* Server::getMainThreadQueue()
70 : {
71 17 : return getClient()->getMainThreadQueue();
72 : }
73 :
74 3 : co::CommandQueue* Server::getCommandThreadQueue()
75 : {
76 3 : return getClient()->getCommandThreadQueue();
77 : }
78 :
79 1 : Config* Server::chooseConfig(const fabric::ConfigParams& p)
80 : {
81 1 : if (!isConnected())
82 0 : return 0;
83 :
84 2 : ClientPtr client = getClient();
85 2 : fabric::ConfigParams params(p);
86 :
87 1 : if (params.getName().empty())
88 1 : params.setName(client->getName());
89 1 : if (params.getWorkDir().empty())
90 1 : params.setWorkDir(Global::getWorkDir());
91 1 : if (params.getRenderClient().empty())
92 1 : params.setRenderClient(Global::getProgramName());
93 1 : if (params.getRenderClientArgs().empty())
94 1 : params.setRenderClientArgs(client->getCommandLine());
95 1 : if (params.getGPUFilter().empty())
96 1 : params.setGPUFilter(client->getGPUFilter());
97 :
98 1 : if (params.getRenderClient().empty())
99 0 : LBWARN << "No render client in ConfigParams specified" << std::endl;
100 :
101 2 : lunchbox::Request<void*> request = client->registerRequest<void*>();
102 2 : send(fabric::CMD_SERVER_CHOOSE_CONFIG) << request << params
103 2 : << eq::Global::getConfig();
104 :
105 5 : while (!request.isReady())
106 2 : getClient()->processCommand();
107 :
108 1 : return static_cast<Config*>(request.wait());
109 : }
110 :
111 1 : void Server::releaseConfig(Config* config)
112 : {
113 1 : LBASSERT(isConnected());
114 2 : ClientPtr client = getClient();
115 :
116 2 : lunchbox::Request<void> request = client->registerRequest<void>();
117 1 : send(fabric::CMD_SERVER_RELEASE_CONFIG) << config->getID() << request;
118 :
119 5 : while (!request.isReady())
120 2 : client->processCommand();
121 1 : }
122 :
123 1 : bool Server::shutdown()
124 : {
125 1 : if (!isConnected())
126 0 : return false;
127 :
128 2 : ClientPtr client = getClient();
129 2 : lunchbox::Request<bool> request = client->registerRequest<bool>();
130 1 : send(fabric::CMD_SERVER_SHUTDOWN) << request;
131 :
132 3 : while (!request.isReady())
133 1 : getClient()->processCommand();
134 :
135 1 : if (!request.wait())
136 0 : return false;
137 :
138 1 : static_cast<co::LocalNode&>(*getClient()).disconnect(this);
139 1 : return true;
140 : }
141 :
142 : //---------------------------------------------------------------------------
143 : // command handlers
144 : //---------------------------------------------------------------------------
145 1 : bool Server::_cmdChooseConfigReply(co::ICommand& command)
146 : {
147 2 : co::LocalNodePtr localNode = command.getLocalNode();
148 1 : const uint128_t& configID = command.read<uint128_t>();
149 1 : const uint32_t requestID = command.read<uint32_t>();
150 :
151 1 : LBVERB << "Handle choose config reply " << command << " req " << requestID
152 1 : << " id " << configID << std::endl;
153 :
154 1 : if (configID == 0)
155 : {
156 0 : localNode->serveRequest(requestID, (void*)0);
157 0 : return true;
158 : }
159 :
160 2 : const std::string& connectionData = command.read<std::string>();
161 1 : const Configs& configs = getConfigs();
162 1 : for (Configs::const_iterator i = configs.begin(); i != configs.end(); ++i)
163 : {
164 1 : Config* config = *i;
165 1 : if (config->getID() == configID)
166 : {
167 1 : config->setupServerConnections(connectionData);
168 1 : localNode->serveRequest(requestID, config);
169 1 : return true;
170 : }
171 : }
172 :
173 0 : LBUNREACHABLE;
174 0 : localNode->serveRequest(requestID, (void*)0);
175 0 : return true;
176 : }
177 :
178 1 : bool Server::_cmdReleaseConfigReply(co::ICommand& command)
179 : {
180 2 : co::LocalNodePtr localNode = command.getLocalNode();
181 1 : localNode->serveRequest(command.read<uint32_t>());
182 2 : return true;
183 : }
184 :
185 1 : bool Server::_cmdShutdownReply(co::ICommand& command)
186 : {
187 2 : co::LocalNodePtr localNode = command.getLocalNode();
188 1 : const uint32_t requestID = command.read<uint32_t>();
189 1 : const bool result = command.read<bool>();
190 1 : localNode->serveRequest(requestID, result);
191 2 : return true;
192 : }
193 : }
194 :
195 : #include <eq/fabric/server.ipp>
196 : template class eq::fabric::Server<eq::Client, eq::Server, eq::Config,
197 : eq::NodeFactory, co::Node, eq::ServerVisitor>;
198 :
199 : /** @cond IGNORE */
200 : template EQFABRIC_API std::ostream& eq::fabric::operator<<(std::ostream&,
201 30 : const eq::Super&);
202 : /** @endcond */
|