void FullMasterCM::_checkConsistency() const { #ifndef NDEBUG EQASSERT( !_instanceDatas.empty( )); EQASSERT( _object->isAttached() ); if( _version == VERSION_NONE ) return; uint128_t version = _version; for( InstanceDataDeque::const_reverse_iterator i = _instanceDatas.rbegin(); i != _instanceDatas.rend(); ++i ) { const InstanceData* data = *i; EQASSERT( data->os.getVersion() != VERSION_NONE ); EQASSERTINFO( data->os.getVersion() == version, data->os.getVersion() << " != " << version ); if( data != _instanceDatas.front( )) { EQASSERTINFO( data->commitCount + _nVersions >= _commitCount, data->commitCount << ", " << _commitCount << " [" << _nVersions << "]" ); } --version; } #endif }
bool DataIStreamQueue::addDataPacket( const uint128_t& key, Command& command ) { EQ_TS_THREAD( _thread ); EQASSERTINFO( _pending.size() < 100, "More than 100 pending commits"); ObjectDataIStream* istream = 0; PendingStreams::iterator i = _pending.find( key ); if( i == _pending.end( )) istream = _iStreamCache.alloc(); else istream = i->second; istream->addDataPacket( command ); if( istream->isReady( )) { if( i != _pending.end( )) _pending.erase( i ); _queued.push( QueuedStream( key, istream )); EQASSERTINFO( _queued.getSize() < 100, "More than 100 queued commits" ); //EQLOG( LOG_OBJECTS ) << "Queued commit " << key << std::endl; return true; } if( i == _pending.end( )) { _pending[ key ] = istream; //EQLOG( LOG_OBJECTS ) << "New incomplete commit " << key << std::endl; return false; } //EQLOG(LOG_OBJECTS) << "Add data to incomplete commit " << key <<std::endl; return false; }
bool LocalNode::connect( NodePtr node ) { EQASSERTINFO( _state == STATE_LISTENING, _state ); if( node->_state == STATE_CONNECTED || node->_state == STATE_LISTENING ) return true; EQASSERT( node->_state == STATE_CLOSED ); // try connecting using the given descriptions const ConnectionDescriptions& cds = node->getConnectionDescriptions(); if( node->getConnectionDescriptions().empty( )) EQWARN << "Can't connect to a node with no listening connections" << std::endl; for( ConnectionDescriptions::const_iterator i = cds.begin(); i != cds.end(); ++i ) { ConnectionDescriptionPtr description = *i; if( description->type >= CONNECTIONTYPE_MULTICAST ) continue; // Don't use multicast for primary connections ConnectionPtr connection = Connection::create( description ); if( !connection || !connection->connect( )) continue; return _connect( node, connection ); } return false; }
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; }
bool LocalNode::_connect( NodePtr node, ConnectionPtr connection ) { EQASSERT( connection.isValid( )); EQASSERT( node->getNodeID() != getNodeID( )); if( !node.isValid() || _state != STATE_LISTENING || !connection->isConnected() || node->_state != STATE_CLOSED ) { return false; } _addConnection( connection ); // send connect packet to peer NodeConnectPacket packet; packet.requestID = registerRequest( node.get( )); packet.nodeID = _id; packet.nodeType = getType(); connection->send( packet, serialize( )); bool connected = false; if( !waitRequest( packet.requestID, connected, 10000 /*ms*/ )) { EQWARN << "Node connection handshake timeout - peer not a Collage node?" << std::endl; return false; } if( !connected ) return false; EQASSERT( node->_id != NodeID::ZERO ); EQASSERTINFO( node->_id != _id, _id ); EQINFO << node << " connected to " << *(Node*)this << std::endl; return true; }
void Thread::untrack() { EQASSERTINFO( std::string( "Watchdog" ) == std::string( Log::instance().getThreadName( )), "Are you sure you want to call this method?" ); --_numThreads(); }
void ObjectStore::_attachObject( Object* object, const base::UUID& id, const uint32_t inInstanceID ) { EQASSERT( object ); EQ_TS_THREAD( _receiverThread ); uint32_t instanceID = inInstanceID; if( inInstanceID == EQ_INSTANCE_INVALID ) instanceID = _genNextID( _instanceIDs ); object->attach( id, instanceID ); { base::ScopedMutex< base::SpinLock > mutex( _objects ); Objects& objects = _objects.data[ id ]; EQASSERTINFO( !object->isMaster() || objects.empty(), "Attaching master " << *object << ", " << objects.size() << " attached objects with same ID, first is: " << *objects[0] ); objects.push_back( object ); } _localNode->flushCommands(); // redispatch pending commands EQLOG( LOG_OBJECTS ) << "attached " << *object << " @" << static_cast< void* >( object ) << std::endl; }
size_t Command::alloc_( NodePtr node, LocalNodePtr localNode, const uint64_t size ) { EQ_TS_THREAD( _writeThread ); EQASSERT( _refCount == 0 ); EQASSERTINFO( !_func.isValid(), *this ); size_t allocated = 0; if( !_data ) { _dataSize = EQ_MAX( Packet::minSize, size ); _data = static_cast< Packet* >( malloc( _dataSize )); allocated = _dataSize; } else if( size > _dataSize ) { allocated = size - _dataSize; _dataSize = EQ_MAX( Packet::minSize, size ); free( _data ); _data = static_cast< Packet* >( malloc( _dataSize )); } _node = node; _localNode = localNode; _refCountMaster = 0; _func.clear(); _packet = _data; _packet->size = size; return allocated; }
/* Begin kd-tree setup, go through full range starting with x axis. */ void VertexBufferRoot::setupTree( VertexData& data ) { // data is VertexData, _data is VertexBufferData _data.clear(); const Axis axis = data.getLongestAxis( 0, data.triangles.size() ); VertexBufferNode::setupTree( data, 0, data.triangles.size(), axis, 0, _data ); VertexBufferNode::updateBoundingSphere(); VertexBufferNode::updateRange(); #if 0 // re-test all points to be in the bounding sphere Vertex center( _boundingSphere.array ); float radius = _boundingSphere.w(); float radiusSquared = radius * radius; for( size_t offset = 0; offset < _data.vertices.size(); ++offset ) { const Vertex& vertex = _data.vertices[ offset ]; const Vertex centerToPoint = vertex - center; const float distanceSquared = centerToPoint.squared_length(); EQASSERTINFO( distanceSquared <= radiusSquared, distanceSquared << " > " << radiusSquared ); } #endif }
void ROITracker::updateDelay( const PixelViewports& pvps, const uint8_t* ticket ) { EQASSERT( _needsUpdate ); EQASSERTINFO( ticket == _ticket, "Wrong ticket" ); if( ticket != _ticket ) { EQERROR << "Wrong ticket" << std::endl; return; } uint32_t totalAreaFound = 0; for( uint32_t i = 0; i < pvps.size(); i++ ) totalAreaFound += pvps[ i ].getArea(); Area& area = (*_curFrame)[ _lastStage ].areas.back(); if( totalAreaFound < area.pvp.getArea()*4/5 ) { // ROI cutted enough, reset failure statistics area.lastSkip = 0; }else { // disable ROI for next frames, if it was failing before, // increase number of frames to skip area.lastSkip = EQ_MIN( area.lastSkip*2 + 1, 64 ); area.skip = area.lastSkip; } _needsUpdate = false; }
void LoadEqualizer::_assign( Compound* compound, const Viewport& vp, const Range& range ) { EQASSERTINFO( vp == Viewport::FULL || range == Range::ALL, "Mixed 2D/DB load-balancing not implemented" ); compound->setViewport( vp ); compound->setRange( range ); EQLOG( LOG_LB2 ) << compound->getChannel()->getName() << " set " << vp << ", " << range << std::endl; // save data for later use Data data; data.vp = vp; data.range = range; data.channel = compound->getChannel(); data.taskID = compound->getTaskID(); const Compound* destCompound = getCompound(); if( destCompound->getChannel() == compound->getChannel( )) data.destTaskID = destCompound->getTaskID(); EQASSERT( data.taskID > 0 ); if( !vp.hasArea() || !range.hasData( )) // will not render data.time = 0; LBFrameData& frameData = _history.back(); LBDatas& items = frameData.second; items.push_back( data ); }
uint128_t& uint128_t::operator = ( const std::string& from ) { char* next = 0; #ifdef _MSC_VER _high = ::_strtoui64( from.c_str(), &next, 16 ); #else _high = ::strtoull( from.c_str(), &next, 16 ); #endif EQASSERT( next != from.c_str( )); if( *next == '\0' ) // short representation, high was 0 { _low = _high; _high = 0; } else { EQASSERTINFO( *next == ':', from << ", " << next ); ++next; #ifdef _MSC_VER _low = ::_strtoui64( next, 0, 16 ); #else _low = ::strtoull( next, 0, 16 ); #endif } return *this; }
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( )); } } }
MasterCM::~MasterCM() { EQASSERTINFO( _pendingDeltas.empty(), "Incomplete slave commits pending" ); EQASSERTINFO( _queuedDeltas.isEmpty(), _queuedDeltas.getSize() << " unapplied slave commits on " << typeid( *_object ).name( )); while( !_pendingDeltas.empty( )) { delete _pendingDeltas.back().second; _pendingDeltas.pop_back(); } ObjectDataIStream* is = 0; while( _queuedDeltas.tryPop( is )) delete is; _slaves.clear(); }
void Connection::setDescription( ConnectionDescriptionPtr description ) { EQASSERT( description.isValid( )); EQASSERTINFO( _description->type == description->type, "Wrong connection type in description" ); _description = description; EQASSERT( description->bandwidth > 0 ); }
void Thread::cancel() { EQASSERTINFO( !isCurrent(), "Thread::cancel called from child thread" ); EQINFO << "Canceling thread " << className( this ) << std::endl; _state = STATE_STOPPING; pthread_cancel( _id._data->pthread ); }
void Config::notifyAttached() { fabric::Object::notifyAttached(); EQASSERT( !_appNode ) EQASSERT( getAppNodeID().isGenerated() ) co::LocalNodePtr localNode = getLocalNode(); _appNode = localNode->connect( getAppNodeID( )); EQASSERTINFO( _appNode, "Connection to application node failed -- " << "misconfigured connections on appNode?" ); }
void MasterCM::_apply( ObjectDataIStream* is ) { EQASSERT( !is->hasInstanceData( )); _object->unpack( *is ); EQASSERTINFO( is->getRemainingBufferSize() == 0 && is->nRemainingBuffers()==0, "Object " << base::className( _object ) << " did not unpack all data" ); is->reset(); _iStreamCache.release( is ); }
void Thread::exit() { EQASSERTINFO( isCurrent(), "Thread::exit not called from child thread" ); EQINFO << "Exiting thread " << className( this ) << std::endl; Log::instance().forceFlush(); Log::instance().exit(); _state = STATE_STOPPING; pthread_exit( 0 ); EQUNREACHABLE; }
//--------------------------------------------------------------------------- // update //--------------------------------------------------------------------------- void Channel::_setupRenderContext( const uint128_t& frameID, RenderContext& context ) { context.frameID = frameID; context.pvp = getPixelViewport(); context.view = _view; context.vp = getViewport(); EQASSERTINFO( getNativeContext().view == context.view, getNativeContext().view << " != " << context.view << " " << getName( )); }
void MessagePump::_initReceiverQueue() { if( !_receiverQueue ) { _receiverQueue = GetCurrentEventQueue(); _needGlobalLock = ( _receiverQueue == GetMainEventQueue( )); EQASSERT( _receiverQueue ); } EQASSERTINFO( _receiverQueue == GetCurrentEventQueue(), "MessagePump::dispatch() called from two different threads" ); }
co::Object* Renderer::createObject( const uint32_t type ) { switch( type ) { case seq::OBJECTTYPE_FRAMEDATA: return new eqPly::FrameData; default: EQASSERTINFO( false, "Object type " << type << " unknown" ); return 0; } }
DataIStreamQueue::~DataIStreamQueue() { EQASSERTINFO( _pending.empty(), "Incomplete commits pending" ); EQASSERTINFO( _queued.isEmpty(), _queued.getSize() << " unapplied commits" ) for( PendingStreamsCIter i = _pending.begin(); i != _pending.end(); ++i ) delete i->second; _pending.clear(); QueuedStream stream; while( _queued.tryPop( stream )) delete stream.second; }
Command& CommandCache::alloc( NodePtr node, LocalNodePtr localNode, const uint64_t size ) { EQ_TS_THREAD( _thread ); EQASSERTINFO( size < EQ_BIT48, "Out-of-sync network stream: packet size " << size << "?" ); const Cache which = (size > Packet::minSize) ? CACHE_BIG : CACHE_SMALL; _compact( which ); Command& command = _newCommand( which ); command.alloc_( node, localNode, size ); return command; }
Object::~Object() { EQASSERTINFO( !isAttached(), "Object " << _id << " is still attached to node " << _localNode->getNodeID()); if( _localNode.isValid() ) _localNode->releaseObject( this ); _localNode = 0; if( _cm != ObjectCM::ZERO ) delete _cm; _cm = 0; }
void UnbufferedMasterCM::removeSlave( NodePtr node ) { EQ_TS_THREAD( _cmdThread ); // remove from subscribers const NodeID& nodeID = node->getNodeID(); EQASSERTINFO( _slavesCount[ nodeID ] != 0, base::className( _object )); --_slavesCount[ nodeID ]; if( _slavesCount[ nodeID ] == 0 ) { Nodes::iterator i = find( _slaves.begin(), _slaves.end(), node ); EQASSERT( i != _slaves.end( )); _slaves.erase( i ); _slavesCount.erase( nodeID ); } }
void LocalNode::_removeConnection( ConnectionPtr connection ) { EQASSERT( connection.isValid( )); _incoming.removeConnection( connection ); void* buffer( 0 ); uint64_t bytes( 0 ); connection->getRecvData( &buffer, &bytes ); EQASSERTINFO( !connection->isConnected() || buffer, *connection ); EQASSERT( !buffer || bytes == sizeof( uint64_t )); if( !connection->isClosed( )) connection->close(); // cancels pending IO's delete reinterpret_cast< uint64_t* >( buffer ); }
void LoadEqualizer::_clearTree( Node* node ) { if( !node ) return; if( node->compound ) { Channel* channel = node->compound->getChannel(); EQASSERTINFO( channel, node->compound ); channel->removeListener( this ); } else { _clearTree( node->left ); _clearTree( node->right ); } }
void Channel::_updateNearFar( const mesh::BoundingSphere& boundingSphere ) { // compute dynamic near/far plane of whole model const FrameData& frameData = _getFrameData(); const eq::Matrix4f& rotation = frameData.getCameraRotation(); const eq::Matrix4f headTransform = getHeadTransform() * rotation; eq::Matrix4f modelInv; compute_inverse( headTransform, modelInv ); const eq::Vector3f zero = modelInv * eq::Vector3f::ZERO; eq::Vector3f front = modelInv * eq::Vector3f( 0.0f, 0.0f, -1.0f ); front -= zero; front.normalize(); front *= boundingSphere.w(); const eq::Vector3f center = frameData.getCameraPosition().get_sub_vector< 3 >() - boundingSphere.get_sub_vector< 3 >(); const eq::Vector3f nearPoint = headTransform * ( center - front ); const eq::Vector3f farPoint = headTransform * ( center + front ); if( useOrtho( )) { EQASSERTINFO( fabs( farPoint.z() - nearPoint.z() ) > std::numeric_limits< float >::epsilon(), nearPoint << " == " << farPoint ); setNearFar( -nearPoint.z(), -farPoint.z() ); } else { // estimate minimal value of near plane based on frustum size const eq::Frustumf& frustum = getFrustum(); const float width = fabs( frustum.right() - frustum.left() ); const float height = fabs( frustum.top() - frustum.bottom() ); const float size = EQ_MIN( width, height ); const float minNear = frustum.near_plane() / size * .001f; const float zNear = EQ_MAX( minNear, -nearPoint.z() ); const float zFar = EQ_MAX( zNear * 2.f, -farPoint.z() ); setNearFar( zNear, zFar ); } }
void WindowSystem::_chooseImpl( const std::string& name ) { EQASSERTINFO( _stack, "no window system available" ); for( WindowSystemIF* ws = _stack; ws; ws = ws->_next ) { // TODO: maybe we should do case insesitive comparision? if( ws->getName() == name ) { _impl = ws; return; } } _impl = _stack; EQWARN << "Window system " << name << " not supported, " << "using " << _impl->getName() << " instead." << std::endl; }