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