lib/client/server.cpp

00001 
00002 /* Copyright (c) 2005-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "server.h"
00019 
00020 #include "client.h"
00021 #include "config.h"
00022 #include "configParams.h"
00023 #include "global.h"
00024 #include "node.h"
00025 #include "nodeFactory.h"
00026 #include "packets.h"
00027 #include "types.h"
00028 
00029 #include <eq/net/command.h>
00030 #include <eq/net/connection.h>
00031 
00032 using namespace eq::base;
00033 using namespace std;
00034 using eq::net::CommandFunc;
00035 using eq::net::NodePtr;
00036 
00037 namespace eq
00038 {
00039 Server::Server()
00040         : _localServer( false )
00041 {
00042     EQINFO << "New server at " << (void*)this << endl;
00043 }
00044 
00045 Server::~Server()
00046 {
00047     EQINFO << "Delete server at " << (void*)this << endl;
00048     _client = 0;
00049 }
00050 
00051 void Server::setClient( ClientPtr client )
00052 {
00053     _client = client;
00054     if( !client )
00055         return;
00056 
00057     net::CommandQueue* queue = client->getNodeThreadQueue();
00058 
00059     registerCommand( CMD_SERVER_CREATE_CONFIG, 
00060                      CommandFunc<Server>( this, &Server::_cmdCreateConfig ),
00061                      queue );
00062     registerCommand( CMD_SERVER_DESTROY_CONFIG, 
00063                      CommandFunc<Server>( this, &Server::_cmdDestroyConfig ),
00064                      queue );
00065     registerCommand( CMD_SERVER_CHOOSE_CONFIG_REPLY, 
00066                     CommandFunc<Server>( this, &Server::_cmdChooseConfigReply ),
00067                      queue );
00068     registerCommand( CMD_SERVER_RELEASE_CONFIG_REPLY, 
00069                    CommandFunc<Server>( this, &Server::_cmdReleaseConfigReply ),
00070                      queue );
00071     registerCommand( CMD_SERVER_SHUTDOWN_REPLY, 
00072                      CommandFunc<Server>( this, &Server::_cmdShutdownReply ),
00073                      queue );
00074 }
00075 
00076 net::CommandQueue* Server::getNodeThreadQueue() 
00077 {
00078     return _client->getNodeThreadQueue();
00079 }
00080 
00081 net::CommandQueue* Server::getCommandThreadQueue() 
00082 {
00083     return _client->getCommandThreadQueue();
00084 }
00085 
00086 Config* Server::chooseConfig( const ConfigParams& parameters )
00087 {
00088     if( !isConnected( ))
00089         return 0;
00090 
00091     const string& renderClient = parameters.getRenderClient();
00092     if( renderClient.empty( ))
00093     {
00094         EQWARN << "No render client in ConfigParams specified" << endl;
00095         return 0;
00096     }
00097 
00098     ServerChooseConfigPacket packet;
00099     const string& workDir = parameters.getWorkDir();
00100 
00101     packet.requestID      = _requestHandler.registerRequest();
00102     string rendererInfo   = workDir + '#' + renderClient;
00103 #ifdef WIN32 // replace dir delimiters since '\' is often used as escape char
00104     for( size_t i=0; i<rendererInfo.length(); ++i )
00105         if( rendererInfo[i] == '\\' )
00106             rendererInfo[i] = '/';
00107 #endif
00108     send( packet, rendererInfo );
00109 
00110     while( !_requestHandler.isServed( packet.requestID ))
00111         _client->processCommand();
00112 
00113     void* ptr = 0;
00114     _requestHandler.waitRequest( packet.requestID, ptr );
00115     return static_cast<Config*>( ptr );
00116 }
00117 
00118 Config* Server::useConfig( const ConfigParams& parameters, 
00119                            const std::string& config )
00120 {
00121     if( !isConnected( ))
00122         return 0;
00123 
00124     const string& renderClient = parameters.getRenderClient();
00125     if( renderClient.empty( ))
00126     {
00127         EQWARN << "No render client in ConfigParams specified" << endl;
00128         return 0;
00129     }
00130 
00131     ServerUseConfigPacket packet;
00132     const string& workDir = parameters.getWorkDir();
00133 
00134     packet.requestID  = _requestHandler.registerRequest();
00135     string configInfo = workDir + '#' + renderClient;
00136 #ifdef WIN32 // replace dir delimiters since '\' is often used as escape char
00137     for( size_t i=0; i<configInfo.length(); ++i )
00138         if( configInfo[i] == '\\' )
00139             configInfo[i] = '/';
00140 #endif
00141 
00142     configInfo += '#' + config;
00143     send( packet, configInfo );
00144 
00145     while( !_requestHandler.isServed( packet.requestID ))
00146         _client->processCommand();
00147 
00148     void* ptr = 0;
00149     _requestHandler.waitRequest( packet.requestID, ptr );
00150     return static_cast<Config*>( ptr );
00151 }
00152 
00153 void Server::releaseConfig( Config* config )
00154 {
00155     EQASSERT( isConnected( ));
00156 
00157     ServerReleaseConfigPacket packet;
00158     packet.requestID = _requestHandler.registerRequest();
00159     packet.configID  = config->getID();
00160     send( packet );
00161 
00162     while( !_requestHandler.isServed( packet.requestID ))
00163         _client->processCommand();
00164 
00165     _requestHandler.waitRequest( packet.requestID );
00166 }
00167 
00168 bool Server::shutdown()
00169 {
00170     if( !isConnected( ))
00171         return false;
00172 
00173     ServerShutdownPacket packet;
00174     packet.requestID = _requestHandler.registerRequest();
00175     send( packet );
00176 
00177     while( !_requestHandler.isServed( packet.requestID ))
00178         _client->processCommand();
00179 
00180     bool result = false;
00181     _requestHandler.waitRequest( packet.requestID, result );
00182 
00183     if( result )
00184         _client->disconnect( this );
00185 
00186     return result;
00187 }
00188 
00189 //---------------------------------------------------------------------------
00190 // command handlers
00191 //---------------------------------------------------------------------------
00192 net::CommandResult Server::_cmdCreateConfig( net::Command& command )
00193 {
00194     const ServerCreateConfigPacket* packet = 
00195         command.getPacket<ServerCreateConfigPacket>();
00196     EQINFO << "Handle create config " << packet << ", name " << packet->name 
00197            << endl;
00198     
00199     NodePtr localNode = command.getLocalNode();
00200     Config* config    = Global::getNodeFactory()->createConfig( this );
00201 
00202     config->_name      = packet->name;
00203     config->_appNodeID = packet->appNodeID;
00204     config->_appNodeID.convertToHost();
00205 
00206     localNode->mapSession( command.getNode(), config, packet->configID );
00207 
00208     if( packet->objectID != EQ_ID_INVALID )
00209         config->_initAppNode( packet->objectID );
00210 
00211     if( packet->requestID != EQ_ID_INVALID )
00212     {
00213         ConfigCreateReplyPacket reply( packet );
00214         command.getNode()->send( reply );
00215     }
00216 
00217     return net::COMMAND_HANDLED;
00218 }
00219 
00220 net::CommandResult Server::_cmdDestroyConfig( net::Command& command )
00221 {
00222     const ServerDestroyConfigPacket* packet = 
00223         command.getPacket<ServerDestroyConfigPacket>();
00224     EQINFO << "Handle destroy config " << packet << endl;
00225     
00226     NodePtr       localNode  = command.getLocalNode();
00227     net::Session* session    = localNode->getSession( packet->configID );
00228 
00229     EQASSERTINFO( dynamic_cast<Config*>( session ), typeid(*session).name( ));
00230     Config* config = static_cast<Config*>( session );
00231 
00232     EQCHECK( localNode->unmapSession( config ));
00233     Global::getNodeFactory()->releaseConfig( config );
00234 
00235     return net::COMMAND_HANDLED;
00236 }
00237 
00238 net::CommandResult Server::_cmdChooseConfigReply( net::Command& command )
00239 {
00240     const ServerChooseConfigReplyPacket* packet = 
00241         command.getPacket<ServerChooseConfigReplyPacket>();
00242     EQINFO << "Handle choose config reply " << packet << endl;
00243 
00244     if( packet->configID == EQ_ID_INVALID )
00245     {
00246         _requestHandler.serveRequest( packet->requestID, (void*)0 );
00247         return net::COMMAND_HANDLED;
00248     }
00249 
00250     NodePtr       localNode = command.getLocalNode();
00251     net::Session* session   = localNode->getSession( packet->configID );
00252     Config*       config    = static_cast< Config* >( session );
00253     EQASSERTINFO( dynamic_cast< Config* >( session ), 
00254                   "Session id " << packet->configID << " @" << (void*)session );
00255 
00256     _requestHandler.serveRequest( packet->requestID, config );
00257     return net::COMMAND_HANDLED;
00258 }
00259 
00260 net::CommandResult Server::_cmdReleaseConfigReply( net::Command& command )
00261 {
00262     const ServerReleaseConfigReplyPacket* packet = 
00263         command.getPacket<ServerReleaseConfigReplyPacket>();
00264 
00265     _requestHandler.serveRequest( packet->requestID );
00266     return net::COMMAND_HANDLED;
00267 }
00268 
00269 net::CommandResult Server::_cmdShutdownReply( net::Command& command )
00270 {
00271     const ServerShutdownReplyPacket* packet = 
00272         command.getPacket<ServerShutdownReplyPacket>();
00273     EQINFO << "Handle shutdown reply " << packet << endl;
00274 
00275     _requestHandler.serveRequest( packet->requestID, packet->result );
00276     return net::COMMAND_HANDLED;
00277 }
00278 }
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8