Line data Source code
1 :
2 : /* Copyright (c) 2005-2015, 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.getGPUFilter().empty( ))
92 2 : params.setGPUFilter( client->getGPUFilter( ));
93 :
94 2 : if( params.getRenderClient().empty( ))
95 1 : LBWARN << "No render client in ConfigParams specified" << std::endl;
96 :
97 4 : lunchbox::Request< void* > request = client->registerRequest< void* >();
98 : send( fabric::CMD_SERVER_CHOOSE_CONFIG )
99 2 : << request << params << eq::Global::getConfigFile();
100 :
101 8 : while( !request.isReady( ))
102 4 : getClient()->processCommand();
103 :
104 4 : return static_cast< Config* >( request.wait( ));
105 : }
106 :
107 12 : void Server::releaseConfig( Config* config )
108 : {
109 12 : LBASSERT( isConnected( ));
110 12 : ClientPtr client = getClient();
111 :
112 24 : lunchbox::Request< void > request = client->registerRequest< void >();
113 12 : send( fabric::CMD_SERVER_RELEASE_CONFIG ) << config->getID() << request;
114 :
115 38 : while( !request.isReady( ))
116 26 : client->processCommand();
117 12 : }
118 :
119 12 : bool Server::shutdown()
120 : {
121 12 : if( !isConnected( ))
122 0 : return false;
123 :
124 12 : ClientPtr client = getClient();
125 24 : lunchbox::Request< bool > request = client->registerRequest< bool >();
126 12 : send( fabric::CMD_SERVER_SHUTDOWN ) << request;
127 :
128 36 : while( !request.isReady( ))
129 12 : getClient()->processCommand();
130 :
131 12 : if( !request.wait( ))
132 0 : return false;
133 :
134 12 : static_cast< co::LocalNode& >( *getClient( )).disconnect( this );
135 24 : return true;
136 : }
137 :
138 : //---------------------------------------------------------------------------
139 : // command handlers
140 : //---------------------------------------------------------------------------
141 2 : bool Server::_cmdChooseConfigReply( co::ICommand& command )
142 : {
143 2 : co::LocalNodePtr localNode = command.getLocalNode();
144 2 : const uint128_t& configID = command.read< uint128_t >();
145 2 : const uint32_t requestID = command.read< uint32_t >();
146 :
147 2 : LBVERB << "Handle choose config reply " << command << " req " << requestID
148 2 : << " id " << configID << std::endl;
149 :
150 2 : if( configID == 0 )
151 : {
152 0 : localNode->serveRequest( requestID, (void*)0 );
153 0 : return true;
154 : }
155 :
156 4 : const std::string& connectionData = command.read< std::string >();
157 2 : const Configs& configs = getConfigs();
158 2 : for( Configs::const_iterator i = configs.begin(); i != configs.end(); ++i )
159 : {
160 2 : Config* config = *i;
161 2 : if( config->getID() == configID )
162 : {
163 2 : config->setupServerConnections( connectionData );
164 2 : localNode->serveRequest( requestID, config );
165 2 : return true;
166 : }
167 : }
168 :
169 0 : LBUNREACHABLE;
170 0 : localNode->serveRequest( requestID, (void*)0 );
171 2 : return true;
172 : }
173 :
174 12 : bool Server::_cmdReleaseConfigReply( co::ICommand& command )
175 : {
176 12 : co::LocalNodePtr localNode = command.getLocalNode();
177 12 : localNode->serveRequest( command.read< uint32_t >( ));
178 12 : return true;
179 : }
180 :
181 12 : bool Server::_cmdShutdownReply( co::ICommand& command )
182 : {
183 12 : co::LocalNodePtr localNode = command.getLocalNode();
184 12 : const uint32_t requestID = command.read< uint32_t >();
185 12 : const bool result = command.read< bool >();
186 12 : localNode->serveRequest( requestID, result );
187 12 : return true;
188 : }
189 : }
190 :
191 : #include <eq/fabric/server.ipp>
192 : template class eq::fabric::Server< eq::Client, eq::Server, eq::Config,
193 : eq::NodeFactory, co::Node, eq::ServerVisitor >;
194 :
195 : /** @cond IGNORE */
196 : template EQFABRIC_API std::ostream& eq::fabric::operator << ( std::ostream&,
197 42 : const eq::Super& );
198 : /** @endcond */
|