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/iCommand.h>
31 : #include <co/connection.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 > Super;
42 :
43 12 : Server::Server()
44 : : Super( Global::getNodeFactory( ))
45 12 : , _impl( 0 )
46 12 : {}
47 :
48 4 : Server::~Server()
49 : {
50 4 : }
51 :
52 24 : void Server::setClient( ClientPtr client )
53 : {
54 24 : Super::setClient( client );
55 24 : if( !client )
56 36 : return;
57 :
58 12 : co::CommandQueue* queue = client->getMainThreadQueue();
59 : registerCommand( fabric::CMD_SERVER_CHOOSE_CONFIG_REPLY,
60 12 : CmdFunc( this, &Server::_cmdChooseConfigReply ), queue );
61 : registerCommand( fabric::CMD_SERVER_RELEASE_CONFIG_REPLY,
62 12 : CmdFunc( this, &Server::_cmdReleaseConfigReply ), queue );
63 : registerCommand( fabric::CMD_SERVER_SHUTDOWN_REPLY,
64 12 : CmdFunc( this, &Server::_cmdShutdownReply ), queue );
65 : }
66 :
67 23 : co::CommandQueue* Server::getMainThreadQueue()
68 : {
69 23 : return getClient()->getMainThreadQueue();
70 : }
71 :
72 2 : co::CommandQueue* Server::getCommandThreadQueue()
73 : {
74 2 : return getClient()->getCommandThreadQueue();
75 : }
76 :
77 2 : Config* Server::chooseConfig( const fabric::ConfigParams& p )
78 : {
79 2 : if( !isConnected( ))
80 0 : return 0;
81 :
82 2 : ClientPtr client = getClient();
83 4 : fabric::ConfigParams params( p );
84 :
85 2 : if( params.getName().empty( ))
86 2 : params.setName( client->getName( ));
87 2 : if( params.getWorkDir().empty( ))
88 2 : params.setWorkDir( Global::getWorkDir( ));
89 2 : if( params.getRenderClient().empty( ))
90 2 : params.setRenderClient( Global::getProgramName( ));
91 2 : if( params.getRenderClientArgs().empty( ))
92 2 : params.setRenderClientArgs( client->getCommandLine( ));
93 2 : if( params.getGPUFilter().empty( ))
94 2 : params.setGPUFilter( client->getGPUFilter( ));
95 :
96 2 : if( params.getRenderClient().empty( ))
97 1 : LBWARN << "No render client in ConfigParams specified" << std::endl;
98 :
99 4 : lunchbox::Request< void* > request = client->registerRequest< void* >();
100 : send( fabric::CMD_SERVER_CHOOSE_CONFIG )
101 2 : << request << params << eq::Global::getConfig();
102 :
103 8 : while( !request.isReady( ))
104 4 : getClient()->processCommand();
105 :
106 4 : return static_cast< Config* >( request.wait( ));
107 : }
108 :
109 12 : void Server::releaseConfig( Config* config )
110 : {
111 12 : LBASSERT( isConnected( ));
112 12 : ClientPtr client = getClient();
113 :
114 24 : lunchbox::Request< void > request = client->registerRequest< void >();
115 12 : send( fabric::CMD_SERVER_RELEASE_CONFIG ) << config->getID() << request;
116 :
117 38 : while( !request.isReady( ))
118 26 : client->processCommand();
119 12 : }
120 :
121 12 : bool Server::shutdown()
122 : {
123 12 : if( !isConnected( ))
124 0 : return false;
125 :
126 12 : ClientPtr client = getClient();
127 24 : lunchbox::Request< bool > request = client->registerRequest< bool >();
128 12 : send( fabric::CMD_SERVER_SHUTDOWN ) << request;
129 :
130 36 : while( !request.isReady( ))
131 12 : getClient()->processCommand();
132 :
133 12 : if( !request.wait( ))
134 0 : return false;
135 :
136 12 : static_cast< co::LocalNode& >( *getClient( )).disconnect( this );
137 24 : return true;
138 : }
139 :
140 : //---------------------------------------------------------------------------
141 : // command handlers
142 : //---------------------------------------------------------------------------
143 2 : bool Server::_cmdChooseConfigReply( co::ICommand& command )
144 : {
145 2 : co::LocalNodePtr localNode = command.getLocalNode();
146 2 : const uint128_t& configID = command.read< uint128_t >();
147 2 : const uint32_t requestID = command.read< uint32_t >();
148 :
149 2 : LBVERB << "Handle choose config reply " << command << " req " << requestID
150 2 : << " id " << configID << std::endl;
151 :
152 2 : if( configID == 0 )
153 : {
154 0 : localNode->serveRequest( requestID, (void*)0 );
155 0 : return true;
156 : }
157 :
158 4 : const std::string& connectionData = command.read< std::string >();
159 2 : const Configs& configs = getConfigs();
160 2 : for( Configs::const_iterator i = configs.begin(); i != configs.end(); ++i )
161 : {
162 2 : Config* config = *i;
163 2 : if( config->getID() == configID )
164 : {
165 2 : config->setupServerConnections( connectionData );
166 2 : localNode->serveRequest( requestID, config );
167 2 : return true;
168 : }
169 : }
170 :
171 0 : LBUNREACHABLE;
172 0 : localNode->serveRequest( requestID, (void*)0 );
173 2 : return true;
174 : }
175 :
176 12 : bool Server::_cmdReleaseConfigReply( co::ICommand& command )
177 : {
178 12 : co::LocalNodePtr localNode = command.getLocalNode();
179 12 : localNode->serveRequest( command.read< uint32_t >( ));
180 12 : return true;
181 : }
182 :
183 12 : bool Server::_cmdShutdownReply( co::ICommand& command )
184 : {
185 12 : co::LocalNodePtr localNode = command.getLocalNode();
186 12 : const uint32_t requestID = command.read< uint32_t >();
187 12 : const bool result = command.read< bool >();
188 12 : localNode->serveRequest( requestID, result );
189 12 : return true;
190 : }
191 : }
192 :
193 : #include <eq/fabric/server.ipp>
194 : template class eq::fabric::Server< eq::Client, eq::Server, eq::Config,
195 : eq::NodeFactory, co::Node, eq::ServerVisitor >;
196 :
197 : /** @cond IGNORE */
198 : template EQFABRIC_API std::ostream& eq::fabric::operator << ( std::ostream&,
199 42 : const eq::Super& );
200 : /** @endcond */
|