bool Config::init() { // init distributed objects EQCHECK( registerObject( &_frameData )); _frameData.setOrtho( _initData.getOrtho( )); _initData.setFrameDataID( _frameData.getID( )); _frameData.setAutoObsolete( getLatency( )); EQCHECK( registerObject( &_initData )); // init config if( !eq::Config::init( _initData.getID( ))) { _deregisterData(); return false; } const eq::Canvases& canvases = getCanvases(); if( canvases.empty( )) _currentCanvas = 0; else _currentCanvas = canvases.front(); _setMessage( "Welcome to eVolve\nPress F1 for help" ); return true; }
void Channel::unsetOutput() { EQASSERT( _view && _segment ); EQCHECK( _view->removeChannel( this )); EQCHECK( _segment->removeDestinationChannel( this )); _view = 0; _segment = 0; }
void Config::setupServerConnections( const char* connectionData ) { std::string data = connectionData; co::ConnectionDescriptions descriptions; EQCHECK( co::deserialize( data, descriptions )); EQASSERTINFO( data.empty(), data << " left from " << connectionData ); for( co::ConnectionDescriptions::const_iterator i = descriptions.begin(); i != descriptions.end(); ++i ) { co::ConnectionPtr connection = co::Connection::create( *i ); if( !connection ) { EQWARN << "Unsupported connection: " << *i << std::endl; continue; } if( connection->listen( )) { _connections.push_back( connection ); getClient()->addListener( connection ); } else { // TODO: Multi-config handling when same connections are spec'd EQASSERT( connection->isListening( )); } } }
bool Dispatcher::dispatchCommand( Command& command ) { EQVERB << "dispatch " << command << " on " << base::className( this ) << std::endl; const uint32_t which = command->command; #ifndef NDEBUG if( which >= _qTable.size( )) { EQABORT( "Command " << command << " higher than number of registered command handlers (" << _qTable.size() << ") for object of type " << base::className( this ) << std::endl ); return false; } #endif CommandQueue* queue = _qTable[which]; if( queue ) { command.setDispatchFunction( _fTable[which] ); queue->push( command ); return true; } // else EQCHECK( _fTable[which]( command )); return true; }
bool LocalNode::close() { if( _state != STATE_LISTENING ) return false; NodeStopPacket packet; send( packet ); EQCHECK( _receiverThread->join( )); _cleanup(); EQINFO << _incoming.getSize() << " connections open after close" << std::endl; #ifndef NDEBUG const Connections& connections = _incoming.getConnections(); for( Connections::const_iterator i = connections.begin(); i != connections.end(); ++i ) { EQINFO << " " << *i << std::endl; } #endif EQASSERTINFO( !hasPendingRequests(), *static_cast< base::RequestHandler* >( this )); return true; }
void Config::mapData(const uint32_t initDataID) { if( _initData.getID() == EQ_ID_INVALID ) { EQCHECK( mapObject( &_initData, initDataID )); unmapObject( &_initData ); // data was retrieved, unmap immediately } else { // appNode, _initData is registered already EQASSERT( _initData.getID() == initDataID ); } }
//--------------------------------------------------------------------------- // command handlers //--------------------------------------------------------------------------- bool Config::_cmdCreateNode( co::Command& command ) { const ConfigCreateNodePacket* packet = command.get<ConfigCreateNodePacket>(); EQVERB << "Handle create node " << packet << std::endl; Node* node = Global::getNodeFactory()->createNode( this ); EQCHECK( mapObject( node, packet->nodeID )); return true; }
void BufferConnection::sendBuffer( ConnectionPtr connection ) { if( _buffer.isEmpty( )) return; if( !connection ) { EQWARN << "NULL connection during buffer write" << std::endl; return; } EQCHECK( connection->send( _buffer.getData(), _buffer.getSize() )); _buffer.setSize( 0 ); }
bool Client::disconnectServer( ServerPtr server ) { bool success = true; // shut down process-local server (see _startLocalServer) if( server->_localServer ) { EQASSERT( server->isConnected( )); EQCHECK( server->shutdown( )); _joinLocalServer(); server->_localServer = false; server->setClient( 0 ); EQASSERT( !server->isConnected( )) }
bool LocalNode::dispatchCommand( Command& command ) { EQVERB << "dispatch " << command << " by " << _id << std::endl; EQASSERT( command.isValid( )); const uint32_t type = command->type; switch( type ) { case PACKETTYPE_CO_NODE: EQCHECK( Dispatcher::dispatchCommand( command )); return true; case PACKETTYPE_CO_OBJECT: { return _objectStore->dispatchObjectCommand( command ); } default: EQABORT( "Unknown packet type " << type << " for " << command ); return true; } }
bool LocalNode::_cmdRemoveListener( Command& command ) { NodeRemoveListenerPacket* packet = command.getModifiable< NodeRemoveListenerPacket >(); ConnectionDescriptionPtr description = new ConnectionDescription( packet->connectionData ); EQCHECK( command.getNode()->removeConnectionDescription( description )); if( command.getNode() != this ) return true; EQASSERT( packet->connection ); ConnectionPtr connection = packet->connection; packet->connection = 0; connection->unref( CO_REFERENCED_PARAM ); if( connection->getDescription()->type >= CONNECTIONTYPE_MULTICAST ) { base::ScopedMutex<> mutex( _outMulticast ); for( MCDatas::iterator i = _multicasts.begin(); i != _multicasts.end(); ++i ) { if( i->connection == connection ) { _multicasts.erase( i ); break; } } } _incoming.removeConnection( connection ); EQASSERT( _connectionNodes.find( connection ) != _connectionNodes.end( )); _connectionNodes.erase( connection ); serveRequest( packet->requestID ); return true; }
void DataOStream::_compress( void* src, const uint64_t size, const CompressorState result ) { if( _compressorState == result || _compressorState == STATE_UNCOMPRESSIBLE ) return; #ifdef EQ_INSTRUMENT_DATAOSTREAM nBytesIn += size; #endif if( !_compressor->isValid( _compressor->getName( )) || size == 0 ) { _compressorState = STATE_UNCOMPRESSED; return; } const uint64_t inDims[2] = { 0, size }; #ifdef EQ_INSTRUMENT_DATAOSTREAM base::Clock clock; #endif _compressor->compress( src, inDims ); #ifdef EQ_INSTRUMENT_DATAOSTREAM compressionTime += uint32_t( clock.getTimef() * 1000.f ); #endif const uint32_t nChunks = _compressor->getNumResults(); uint64_t compressedSize = 0; EQASSERT( nChunks > 0 ); for( uint32_t i = 0; i < nChunks; ++i ) { void* chunk; uint64_t chunkSize; _compressor->getResult( i, &chunk, &chunkSize ); compressedSize += chunkSize; } #ifdef EQ_INSTRUMENT_DATAOSTREAM nBytesOut += compressedSize; #endif if( compressedSize >= size ) { _compressorState = STATE_UNCOMPRESSIBLE; #ifndef CO_AGGRESSIVE_CACHING const uint32_t name = _compressor->getName(); _compressor->reset(); EQCHECK( _compressor->base::Compressor::initCompressor( name )); if( result == STATE_COMPLETE ) _buffer.pack(); #endif return; } _compressorState = result; #ifndef CO_AGGRESSIVE_CACHING if( result == STATE_COMPLETE ) { EQASSERT( _buffer.getSize() == _dataSize ); _buffer.clear(); } #endif }
//---------------------------------------------------------------------- // receiver thread functions //---------------------------------------------------------------------- void LocalNode::_runReceiverThread() { EQ_TS_THREAD( _rcvThread ); int nErrors = 0; while( _state == STATE_LISTENING ) { const ConnectionSet::Event result = _incoming.select(); switch( result ) { case ConnectionSet::EVENT_CONNECT: _handleConnect(); break; case ConnectionSet::EVENT_DATA: _handleData(); break; case ConnectionSet::EVENT_DISCONNECT: case ConnectionSet::EVENT_INVALID_HANDLE: _handleDisconnect(); break; case ConnectionSet::EVENT_TIMEOUT: EQINFO << "select timeout" << std::endl; break; case ConnectionSet::EVENT_ERROR: ++nErrors; EQWARN << "Connection error during select" << std::endl; if( nErrors > 100 ) { EQWARN << "Too many errors in a row, capping connection" << std::endl; _handleDisconnect(); } break; case ConnectionSet::EVENT_SELECT_ERROR: EQWARN << "Error during select" << std::endl; ++nErrors; if( nErrors > 10 ) { EQWARN << "Too many errors in a row" << std::endl; EQUNIMPLEMENTED; } break; case ConnectionSet::EVENT_INTERRUPT: _redispatchCommands(); break; default: EQUNIMPLEMENTED; } if( result != ConnectionSet::EVENT_ERROR && result != ConnectionSet::EVENT_SELECT_ERROR ) nErrors = 0; } if( !_pendingCommands.empty( )) EQWARN << _pendingCommands.size() << " commands pending while leaving command thread" << std::endl; for( CommandList::const_iterator i = _pendingCommands.begin(); i != _pendingCommands.end(); ++i ) { Command* command = *i; command->release(); } EQCHECK( _commandThread->join( )); _objectStore->clear(); _pendingCommands.clear(); _commandCache.flush(); EQINFO << "Leaving receiver thread of " << base::className( this ) << std::endl; }