void EventHandler::_dispatch() { Display* display = _window->getXDisplay(); LBASSERT( display ); if( !display ) return; while( XPending( display )) { WindowEvent event; XEvent& xEvent = event.xEvent; XNextEvent( display, &xEvent ); event.time = _window->getConfig()->getTime(); for( EventHandlers::const_iterator i = _eventHandlers->begin(); i != _eventHandlers->end(); ++i ) { EventHandler* handler = *i; handler->_processEvent( event ); } } }
bool Window::configInitGL( const eq::uint128_t& initID ) { if( !eq::Window::configInitGL( initID )) return false; glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, 1 ); glEnable( GL_CULL_FACE ); // OPT - produces sparser images in DB mode glCullFace( GL_BACK ); LBASSERT( !_state ); _state = new VertexBufferState( getObjectManager( )); const Config* config = static_cast< const Config* >( getConfig( )); const InitData& initData = config->getInitData(); if( initData.showLogo( )) _loadLogo(); if( initData.useGLSL() ) _loadShaders(); return true; }
GPUCacheManager::GPUCacheManager( constGPUCacheIndexSPtr cacheIndex, RAMPoolSPtr ramPool, const byte bytesNum, Window* wnd ) :_iteration( 1 ) ,_cacheIndex( cacheIndex ) ,_gpuLoader( new GPUAsyncLoader( wnd )) ,_nodeIdBeingLoaded( 0 ) ,_cachePosBeingLoaded( 0 ) { LBASSERT( _cacheIndex ); _gpuLoader->start(); const GPULoadRespond respond = _gpuLoader->readLoadRespond(); if( respond.status.value != GPULoadStatus::INITIALIZED ) LBERROR << "Incorrect respond from GPU Async Loader" << std::endl; _gpuLoader->postCommand( GPUCommand::PAUSE ); _gpuLoader->initialize( ramPool, cacheIndex, bytesNum ); _resize(); LBWARN << " new GPUCacheManager, updating GPU Cache" << std::endl; _gpuLoader->postCommand( GPUCommand::UPDATE ); _gpuLoader->postCommand( GPUCommand::RESUME ); }
uint128_t FullMasterCM::commit( const uint32_t incarnation ) { LBASSERT( _version != VERSION_NONE ); if( !_object->isDirty( )) { Mutex mutex( _slaves ); _updateCommitCount( incarnation ); _obsolete(); return _version; } _maxVersion.waitGE( _version.low() + 1 ); Mutex mutex( _slaves ); #if 0 LBLOG( LOG_OBJECTS ) << "commit v" << _version << " " << command << std::endl; #endif _updateCommitCount( incarnation ); _commit(); _obsolete(); return _version; }
//=========================================================================== // ICommand handling methods //=========================================================================== void Server::handleCommands() { _running = true; while( _running ) // set to false in _cmdShutdown() { const co::ICommands& commands = _mainThreadQueue.popAll(); LBASSERT( !commands.empty( )); for( co::ICommandsCIter i = commands.begin(); i != commands.end(); ++i ) { // We want to avoid a non-const copy of commands, hence the cast... co::ICommand& command = const_cast< co::ICommand& >( *i ); if( !command( )) { LBABORT( "Error handling " << command ); } if( !_running ) break; } } _mainThreadQueue.flush(); }
bool Window::configInitSystemWindow( const uint128_t& ) { const Pipe* pipe = getPipe(); WindowSettings settings = getSettings(); const SystemWindow* sysWindow = _sharedContextWindow ? _sharedContextWindow->getSystemWindow() : 0; settings.setSharedContextWindow( sysWindow ); SystemWindow* systemWindow = pipe->getWindowSystem().createWindow( this, settings ); LBASSERT( systemWindow ); if( !systemWindow->configInit( )) { LBWARN << "System window initialization failed" << std::endl; systemWindow->configExit(); delete systemWindow; return false; } setPixelViewport( systemWindow->getPixelViewport( )); setSystemWindow( systemWindow ); return true; }
bool GLSLShaders::loadShaders(const std::string &vShader, const std::string &fShader, const GLEWContext *glewContext) { if (_shadersLoaded) return true; LBASSERT(glewContext); _glewContext = glewContext; _program = glCreateProgramObjectARB(); GLhandleARB vertexShader = _loadShader(vShader, GL_VERTEX_SHADER_ARB); if (!vertexShader) return _cleanupOnError(); glAttachObjectARB(_program, vertexShader); GLhandleARB fragmentShader = _loadShader(fShader, GL_FRAGMENT_SHADER_ARB); if (!fragmentShader) return _cleanupOnError(vertexShader); glAttachObjectARB(_program, fragmentShader); glLinkProgramARB(_program); GLint status; glGetObjectParameterivARB(_program, GL_OBJECT_LINK_STATUS_ARB, &status); if (status != GL_FALSE) { _shadersLoaded = true; return true; } _printLog(_program, "Linking"); return _cleanupOnError(vertexShader, fragmentShader); }
bool setup( lunchbox::PluginRegistry& from, const uint32_t name, const GLEWContext* gl ) { if( name == info.name ) { LBASSERT( isGood() && instance ); return true; } clear(); if( name <= EQ_COMPRESSOR_NONE ) { LBASSERT( isGood() && instance ); return true; } plugin = from.findPlugin( name ); LBASSERT( plugin ); if( !plugin ) { LBWARN << "Plugin for downloader 0x" << std::hex << name << std::dec << " not found" << std::endl; return false; } if( !gl ) LBWARN << "Can't verify plugin compatibility, no GLEWContext given" << std::endl; else if( !plugin->isCompatible( name, gl )) { LBWARN << "Plugin for downloader 0x" << std::hex << name << std::dec << " not compatible with OpenGL implementation" << std::endl; return false; } instance = plugin->newDecompressor( name ); info = plugin->findInfo( name ); LBASSERT( isGood( )); LBASSERT( instance ); LBASSERT( info.name == name ); LBLOG( LOG_PLUGIN ) << "Instantiated downloader " << info << std::endl; return instance; }
bool Client::initLocal( const int argc, char** argv ) { bool isClient = false; std::string clientOpts; if( _impl->name.empty() && argc > 0 && argv ) { const boost::filesystem::path prog = argv[0]; setName( prog.stem().string( )); } for( int i=1; i<argc; ++i ) { if( std::string( "--eq-client" ) == argv[i] ) { isClient = true; if( i < argc-1 && argv[i+1][0] != '-' ) // server-started client { clientOpts = argv[++i]; if( !deserialize( clientOpts )) LBWARN << "Failed to parse client listen port parameters" << std::endl; LBASSERT( !clientOpts.empty( )); } } else if( _isParameterOption( "--eq-layout", argc, argv, i )) _impl->activeLayouts.push_back( argv[++i] ); else if( _isParameterOption( "--eq-gpufilter" , argc, argv, i )) _impl->gpuFilter = argv[ ++i ]; else if( _isParameterOption( "--eq-modelunit", argc, argv, i )) { std::istringstream unitString( argv[++i] ); unitString >> _impl->modelUnit; } }
bool MasterConfig::init() { LBASSERT( !_objects ); _objects = new ObjectMap( *this, *getApplication( )); co::Object* initData = getInitData(); if( initData ) LBCHECK( _objects->register_( initData, OBJECTTYPE_INITDATA )); _objects->setInitData( initData ); LBCHECK( registerObject( _objects )); if( !eq::Config::init( _objects->getID( ))) { LBWARN << "Error during initialization: " << getError() << std::endl; exit(); return false; } if( getError( )) LBWARN << "Error during initialization: " << getError() << std::endl; _redraw = true; return true; }
void DataIStream::_read( void* data, uint64_t size ) { if( !_checkBuffer( )) { LBUNREACHABLE; LBERROR << "No more input data" << std::endl; return; } LBASSERT( _impl->input ); if( size > _impl->inputSize - _impl->position ) { LBERROR << "Not enough data in input buffer: need " << size << " bytes, " << _impl->inputSize - _impl->position << " left " << std::endl; LBUNREACHABLE; // TODO: Allow reads which are asymmetric to writes by reading from // multiple blocks here? return; } memcpy( data, _impl->input + _impl->position, size ); _impl->position += size; }
bool DSO::open( const std::string& fileName ) { if( _impl->dso ) { LBWARN << "DSO already open, close it first" << std::endl; return false; } if( fileName.empty( )) { #ifdef _WIN32 //_MSC_VER _impl->dso = GetModuleHandle( 0 ); LBASSERT( _impl->dso ); #else _impl->dso = RTLD_DEFAULT; #endif } else { #ifdef _WIN32 //_MSC_VER _impl->dso = LoadLibrary( fileName.c_str() ); #elif defined( RTLD_LOCAL ) _impl->dso = dlopen( fileName.c_str(), RTLD_LAZY | RTLD_LOCAL ); #else _impl->dso = dlopen( fileName.c_str(), RTLD_LAZY ); #endif if( !_impl->dso ) { LBINFO << "Can't open library " << fileName << ": " << LB_DL_ERROR << std::endl; return false; } } return true; }
bool Connection::send( const Connections& connections, Packet& packet, const void* const* items, const uint64_t* sizes, const size_t nItems ) { if( connections.empty( )) return true; packet.size -= 8; const uint64_t headerSize = packet.size; for( size_t i = 0; i < nItems; ++i ) { LBASSERT( sizes[i] > 0 ); packet.size += sizes[ i ] + sizeof( uint64_t ); } bool success = true; for( Connections::const_iterator i = connections.begin(); i < connections.end(); ++i ) { ConnectionPtr connection = *i; connection->lockSend(); if( !connection->send( &packet, headerSize, true )) success = false; for( size_t j = 0; j < nItems; ++j ) if( !connection->send( &sizes[j], sizeof(uint64_t), true ) || !connection->send( items[j], sizes[j], true )) { success = false; } connection->unlockSend(); } return success; }
bool setup(const uint32_t name) { if (plugin && info.name == name) return true; clear(); if (name <= EQ_COMPRESSOR_NONE) return true; plugin = pression::PluginRegistry::getInstance().findPlugin(name); LBASSERTINFO(plugin, "Can't find plugin for decompressor " << name); if (!plugin) return false; instance = plugin->newDecompressor(name); info = plugin->findInfo(name); LBASSERT(info.name == name); LBLOG(LOG_PLUGIN) << "Instantiated " << (instance ? "" : "empty ") << "decompressor of type 0x" << std::hex << name << std::dec << std::endl; return true; }
void Config::_switchCanvas() { const eq::Canvases& canvases = getCanvases(); if( canvases.empty( )) return; _frameData.setCurrentViewID( eq::UUID( )); if( !_currentCanvas ) { _currentCanvas = canvases.front(); return; } eq::CanvasesCIter i = stde::find( canvases, _currentCanvas ); LBASSERT( i != canvases.end( )); ++i; if( i == canvases.end( )) _currentCanvas = canvases.front(); else _currentCanvas = *i; _switchView(); // activate first view on canvas }
//--------------------------------------------------------------------------- // exit //--------------------------------------------------------------------------- bool Config::exit() { if( _state != STATE_RUNNING ) LBWARN << "Exiting non-initialized config" << std::endl; LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING ); _state = STATE_EXITING; const Canvases& canvases = getCanvases(); for( Canvases::const_iterator i = canvases.begin(); i != canvases.end(); ++i ) { Canvas* canvas = *i; canvas->exit(); } for( Compounds::const_iterator i = _compounds.begin(); i != _compounds.end(); ++i ) { Compound* compound = *i; compound->exit(); } const bool success = _updateRunning( true ); // TODO: is this needed? sender of CMD_CONFIG_EXIT is the appNode itself // which sets the running state to false anyway. Besides, this event is // not handled by the appNode because it is already in exiting procedure // and does not call handleEvents anymore // eile: May be needed for reliability? send( findApplicationNetNode(), fabric::CMD_CONFIG_EVENT ) << Event::EXIT; _needsFinish = false; _state = STATE_STOPPED; return success; }
bool Window::createTransferWindow() { LBASSERT( _systemWindow ); if( _transferWindow ) return true; // create another (shared) osWindow with no drawable WindowSettings settings = getSettings(); settings.setIAttribute( WindowSettings::IATTR_HINT_DRAWABLE, OFF ); const SystemWindow* sysWindow = _sharedContextWindow ? _sharedContextWindow->getSystemWindow() : 0; settings.setSharedContextWindow( sysWindow ); const Pipe* pipe = getPipe(); _transferWindow = pipe->getWindowSystem().createWindow( this, settings ); if( _transferWindow ) { if( !_transferWindow->configInit( )) { LBWARN << "Transfer window initialization failed" << std::endl; delete _transferWindow; _transferWindow = 0; } else makeCurrentTransfer(); // #177 } else LBERROR << "Window system " << pipe->getWindowSystem() << " not implemented or supported" << std::endl; makeCurrent(); LBVERB << "Transfer window initialization finished" << std::endl; return _transferWindow != 0; }
void StaticSlaveCM::addInstanceDatas( const ObjectDataIStreamDeque& cache, const uint128_t& /* start */ ) { LB_TS_THREAD( _rcvThread ); LBASSERT( _currentIStream ); LBASSERT( _currentIStream->getDataSize() == 0 ); LBASSERT( cache.size() == 1 ); if( cache.empty( )) return; ObjectDataIStream* stream = cache.front(); LBASSERT( stream ); LBASSERT( stream->isReady( )); LBASSERT( stream->getVersion() == VERSION_FIRST ); if( !stream->isReady() || stream->getVersion() != VERSION_FIRST ) return; LBLOG( LOG_OBJECTS ) << "Adding cached instance data" << std::endl; delete _currentIStream; _currentIStream = new ObjectDataIStream( *stream ); }
PixelViewport ROIFinder::_getObjectPVP( const PixelViewport& pvp, const uint8_t* src ) { LBASSERT( pvp.x >= 0 && pvp.x+pvp.w <= _wb && pvp.y >= 0 && pvp.y+pvp.h <= _hb ); // Calculate per-pixel histograms const uint8_t* s = src + pvp.y*_wb + pvp.x; memset( _histX, 0, pvp.w ); memset( _histY, 0, pvp.h ); for( int32_t y = 0; y < pvp.h; y++ ) { for( int32_t x = 0; x < pvp.w; x++ ) { const uint8_t val = s[ x ] & 1; _histX[ x ] += val; _histY[ y ] += val; } s += _wb; } // Find AABB based on X and Y axis historgams int32_t xMin = pvp.w; for( int32_t x = 0; x < pvp.w; x++ ) if( _histX[x] != 0 ) { xMin = x; break; } int32_t xMax = 0; for( int32_t x = pvp.w-1; x >= 0; x-- ) if( _histX[x] != 0 ) { xMax = x; break; } if( xMax < xMin ) return PixelViewport( pvp.x, pvp.y, 0, 0 ); int32_t yMin = pvp.h; for( int32_t y = 0; y < pvp.h; y++ ) if( _histY[y] != 0 ) { yMin = y; break; } int32_t yMax = 0; for( int32_t y = pvp.h-1; y >= 0; y-- ) if( _histY[y] != 0 ) { yMax = y; break; } if( yMax < yMin ) return PixelViewport( pvp.x, pvp.y, 0, 0 ); return PixelViewport( pvp.x+xMin, pvp.y+yMin, xMax-xMin+1, yMax-yMin+1 ); }
void ROIFinder::_readbackInfo( util::ObjectManager& glObjects ) { LBASSERT( glObjects.supportsEqTexture( )); LBASSERT( glObjects.supportsEqFrameBufferObject( )); PixelViewport pvp = _pvp; pvp.apply( Zoom( GRID_SIZE, GRID_SIZE )); pvp.w = LB_MIN( pvp.w+pvp.x, _pvpOriginal.w+_pvpOriginal.x ) - pvp.x; pvp.h = LB_MIN( pvp.h+pvp.y, _pvpOriginal.h+_pvpOriginal.y ) - pvp.y; LBASSERT( pvp.isValid()); // copy frame buffer to texture const void* bufferKey = _getInfoKey( ); util::Texture* texture = glObjects.obtainEqTexture( bufferKey, GL_TEXTURE_RECTANGLE_ARB ); #ifdef EQ_ROI_USE_DEPTH_TEXTURE texture->copyFromFrameBuffer( GL_DEPTH_COMPONENT, pvp ); #else texture->copyFromFrameBuffer( GL_RGBA, pvp ); #endif // draw zoomed quad into FBO const void* fboKey = _getInfoKey( ); util::FrameBufferObject* fbo = glObjects.getEqFrameBufferObject( fboKey ); if( fbo ) { LBCHECK( fbo->resize( _pvp.w, _pvp.h )); } else { fbo = glObjects.newEqFrameBufferObject( fboKey ); LBCHECK( fbo->init( _pvp.w, _pvp.h, GL_RGBA32F, 0, 0 )); } fbo->bind(); texture->bind(); // Enable & download depth texture glEnable( GL_TEXTURE_RECTANGLE_ARB ); texture->applyWrap(); texture->applyZoomFilter( FILTER_LINEAR ); // Enable shaders GLuint program = glObjects.getProgram( shaderRBInfo ); if( program == util::ObjectManager::INVALID ) { // Create fragment shader which reads depth values from // rectangular textures const GLuint shader = glObjects.newShader( shaderRBInfo, GL_FRAGMENT_SHADER ); LBASSERT( shader != util::ObjectManager::INVALID ); #ifdef EQ_ROI_USE_DEPTH_TEXTURE const GLchar* fShaderPtr = roiFragmentShader_glsl.c_str(); #else const GLchar* fShaderPtr = roiFragmentShaderRGB_glsl.c_str(); #endif EQ_GL_CALL( glShaderSource( shader, 1, &fShaderPtr, 0 )); EQ_GL_CALL( glCompileShader( shader )); GLint status; glGetShaderiv( shader, GL_COMPILE_STATUS, &status ); if( !status ) LBERROR << "Failed to compile fragment shader for ROI finder" << std::endl; program = glObjects.newProgram( shaderRBInfo ); EQ_GL_CALL( glAttachShader( program, shader )); EQ_GL_CALL( glLinkProgram( program )); glGetProgramiv( program, GL_LINK_STATUS, &status ); if( !status ) { LBWARN << "Failed to link shader program for ROI finder" << std::endl; return; } // use fragment shader and setup uniforms EQ_GL_CALL( glUseProgram( program )); GLint param = glGetUniformLocation( program, "texture" ); glUniform1i( param, 0 ); } else { // use fragment shader EQ_GL_CALL( glUseProgram( program )); } // Draw Quad glDisable( GL_LIGHTING ); glColor3f( 1.0f, 1.0f, 1.0f ); glBegin( GL_QUADS ); glVertex3i( 0, 0, 0 ); glVertex3i( _pvp.w, 0, 0 ); glVertex3i( _pvp.w, _pvp.h, 0 ); glVertex3i( 0, _pvp.h, 0 ); glEnd(); // restore state glDisable( GL_TEXTURE_RECTANGLE_ARB ); EQ_GL_CALL( glUseProgram( 0 )); fbo->unbind(); // finish readback of info LBASSERT( static_cast<int32_t>(_perBlockInfo.size()) >= _pvp.w*_pvp.h*4 ); texture = fbo->getColorTextures()[0]; LBASSERT( texture->getFormat() == GL_RGBA ); LBASSERT( texture->getType() == GL_FLOAT ); texture->download( &_perBlockInfo[0] ); }
uint8_t ROIFinder::_splitArea( Area& a ) { LBASSERT( a.hole.getArea() > 0 ); #ifndef NDEBUG _invalidateAreas( _tmpAreas, 17 ); #endif _dim.x1 = a.pvp.x; _dim.x2 = a.hole.x; _dim.x3 = a.hole.x + a.hole.w; _dim.w1 = _dim.x2 - _dim.x1; _dim.w2 = a.hole.w; _dim.w3 = a.pvp.x + a.pvp.w - _dim.x3; _dim.w4 = _dim.w1 + _dim.w2; _dim.w5 = _dim.w2 + _dim.w3; _dim.w6 = _dim.w4 + _dim.w3; _dim.y1 = a.pvp.y; _dim.y2 = a.hole.y; _dim.y3 = a.hole.y + a.hole.h; _dim.h1 = _dim.y2 - _dim.y1; _dim.h2 = a.hole.h; _dim.h3 = a.pvp.y + a.pvp.h - _dim.y3; _dim.h4 = _dim.h1 + _dim.h2; _dim.h5 = _dim.h2 + _dim.h3; _dim.h6 = _dim.h4 + _dim.h3; // other cases uint8_t type; if( a.pvp.h == a.hole.h ) // hole through the whole block { LBASSERT( a.pvp.w != a.hole.w ); type = 8; } else if( a.pvp.w == a.hole.w ) // hole through the whole block { type = 9; } else if( a.pvp.x == a.hole.x ) // left side { if( a.pvp.y == a.hole.y ) // in the lower left corner type = 0; else if( a.pvp.y + a.pvp.h == a.hole.y + a.hole.h ) // in the upper left corner type = 1; else // in the left middle type = 2; } else if( a.pvp.y == a.hole.y ) // bottom side { if( a.pvp.x + a.pvp.w == a.hole.x + a.hole.w ) // in the bottom right corner type = 3; else // in the bottom middle type = 4; } else if( a.pvp.x + a.pvp.w == a.hole.x + a.hole.w ) // right side { if( a.pvp.y + a.pvp.h == a.hole.y + a.hole.h ) // in the upper right corner type = 5; else // in the right middle type = 6; } else if( a.pvp.y + a.pvp.h == a.hole.y + a.hole.h ) // top side // in the upper middle corner type = 7; else // must be in the center type = 10; // Calculate areas of interest if( type == 10 ) // center hole position { for( uint8_t i = 1; i <= 16; i++ ) _updateSubArea( i ); } else { for( uint8_t i = 0; i < 8; i++ ) _updateSubArea( _interests[ type ][ i ] ); } // find best combinations of areas of interest const uint8_t varaintsNum = _compilNums[type][0]; const uint8_t areasPerVariant = _compilNums[type][1]; int32_t maxSum = 0; int32_t variant = 0; if( type == 10 ) // center hole { for( uint8_t i = 0; i < varaintsNum; i++ ) { int32_t sum = 0; for( uint8_t j = 0; j < areasPerVariant; j++ ) { LBASSERT( _tmpAreas[_compilations16[i][j]].valid ); sum += _tmpAreas[_compilations16[i][j]].emptySize; } if( sum > maxSum ) { maxSum = sum; variant = i; } } for( uint8_t j = 0; j < areasPerVariant; j++ ) { LBASSERT( _tmpAreas[_compilations16[variant][j]].valid ); _finalAreas[j] = _tmpAreas[_compilations16[variant][j]]; } return areasPerVariant; } // else any other hole for( uint8_t i = 0; i < varaintsNum; i++ ) { int32_t sum = 0; for( uint8_t j = 0; j < areasPerVariant; j++ ) { LBASSERT( _tmpAreas[_compilations[type][i][j]].valid ); sum += _tmpAreas[_compilations[type][i][j]].emptySize; } if( sum > maxSum ) { maxSum = sum; variant = i; } } for( uint8_t j = 0; j < areasPerVariant; j++ ) { LBASSERT( _tmpAreas[_compilations[type][variant][j]].valid ); _finalAreas[j] = _tmpAreas[_compilations[type][variant][j]]; } return areasPerVariant; }
bool ConnectionSet::_setupFDSet() { // if( !_impl->dirty ) // { //#ifndef _WIN32 // // TODO: verify that poll() really modifies _fdSet, and remove the copy // // if it doesn't. The man page seems to hint that poll changes fds. // _impl->fdSet = _impl->fdSetCopy; //#endif // return true; // } _impl->dirty = false; _impl->fdSet.setSize( 0 ); _impl->fdSetResult.setSize( 0 ); #ifdef _WIN32 // add self connection HANDLE readHandle = _impl->selfConnection->getNotifier(); LBASSERT( readHandle ); _impl->fdSet.append( readHandle ); Result res; res.connection = _impl->selfConnection.get(); _impl->fdSetResult.append( res ); // add regular connections _impl->lock.set(); for( ConnectionsCIter i = _impl->connections.begin(); i != _impl->connections.end(); ++i ) { ConnectionPtr connection = *i; if ( connection->isRead() ) continue; readHandle = connection->getNotifier(); if( !readHandle ) { LBINFO << "Cannot select connection " << connection << ", connection does not provide a read handle" << std::endl; _impl->connection = connection; _impl->lock.unset(); return false; } _impl->fdSet.append( readHandle ); Result result; result.connection = connection.get(); _impl->fdSetResult.append( result ); } for( ThreadsCIter i=_impl->threads.begin(); i != _impl->threads.end(); ++i ) { Thread* thread = *i; readHandle = thread->notifier; LBASSERT( readHandle ); _impl->fdSet.append( readHandle ); Result result; result.thread = thread; _impl->fdSetResult.append( result ); } _impl->lock.unset(); #else // _WIN32 pollfd fd; fd.events = POLLIN; // | POLLPRI; // add self 'connection' fd.fd = _impl->selfConnection->getNotifier(); LBASSERT( fd.fd > 0 ); fd.revents = 0; _impl->fdSet.append( fd ); Result result; result.connection = _impl->selfConnection.get(); _impl->fdSetResult.append( result ); // add regular connections _impl->lock.set(); for( ConnectionsCIter i = _impl->allConnections.begin(); i != _impl->allConnections.end(); ++i ) { ConnectionPtr connection = *i; if ( connection->isRead() ) continue; fd.fd = connection->getNotifier(); if( fd.fd <= 0 ) { LBINFO << "Cannot select connection " << connection << ", connection " << typeid( *connection.get( )).name() << " doesn't have a file descriptor" << std::endl; _impl->connection = connection; _impl->lock.unset(); return false; } LBVERB << "Listening on " << typeid( *connection.get( )).name() << " @" << (void*)connection.get() << std::endl; fd.revents = 0; _impl->fdSet.append( fd ); result.connection = connection.get(); _impl->fdSetResult.append( result ); } _impl->lock.unset(); _impl->fdSetCopy = _impl->fdSet; #endif return true; }
ConnectionSet::Event ConnectionSet::select( const uint32_t timeout ) { LB_TS_SCOPED( _selectThread ); while( true ) { _impl->connection = 0; _impl->error = 0; #ifdef _WIN32 if( _impl->thread ) { _impl->thread->event = EVENT_NONE; // unblock previous thread _impl->thread = 0; } #endif if( !_setupFDSet( )) return EVENT_INVALID_HANDLE; // poll for a result #ifdef _WIN32 LBASSERT( LB_TIMEOUT_INDEFINITE == INFINITE ); const DWORD ret = WaitForMultipleObjectsEx( _impl->fdSet.getSize(), _impl->fdSet.getData(), FALSE, timeout, TRUE ); #else const int pollTimeout = timeout == LB_TIMEOUT_INDEFINITE ? -1 : int( timeout ); const int ret = poll( _impl->fdSet.getData(), _impl->fdSet.getSize(), pollTimeout ); #endif switch( ret ) { case SELECT_TIMEOUT: return EVENT_TIMEOUT; case SELECT_ERROR: #ifdef _WIN32 if( !_impl->thread ) _impl->error = GetLastError(); if( _impl->error == WSA_INVALID_HANDLE ) { _impl->dirty = true; break; } #else if( errno == EINTR ) // Interrupted system call (gdb) - ignore break; _impl->error = errno; #endif LBERROR << "Error during select: " << lunchbox::sysError << std::endl; return EVENT_SELECT_ERROR; default: // SUCCESS { Event event = _getSelectResult( ret ); if( event == EVENT_NONE ) break; if( _impl->connection == _impl->selfConnection.get( )) { _impl->connection = 0; _impl->selfConnection->reset(); return EVENT_INTERRUPT; } if( event == EVENT_DATA &&_impl->connection->isListening()) event = EVENT_CONNECT; #ifdef _WIN32 if ( _isThreadMode && _needRebalance ) _rebalanceThreads(); #endif _rotateFDSet(); return event; } } } }
Window::~Window() { LBASSERT( getChannels().empty( )); }
void Window::updateFrameBuffer() const { LBASSERT( _systemWindow ); if( _systemWindow ) _systemWindow->updateFrameBuffer(); }
void Window::bindDrawFrameBuffer() const { LBASSERT( _systemWindow ); if( _systemWindow ) _systemWindow->bindDrawFrameBuffer(); }
void Window::makeCurrentTransfer( const bool useCache ) const { LBASSERT( _transferWindow ); if( _transferWindow ) _transferWindow->makeCurrent( useCache ); }
SystemPipe* Window::getSystemPipe() { Pipe* pipe = getPipe(); LBASSERT( pipe ); return pipe->getSystemPipe(); }
void Window::finish() const { LBASSERT( _systemWindow ); if( _systemWindow ) _systemWindow->finish(); }
ServerPtr Window::getServer() { Pipe* pipe = getPipe(); LBASSERT( pipe ); return ( pipe ? pipe->getServer() : 0 ); }