Пример #1
0
 void Connection::close()
 {
     TRACE_ENTERLEAVE();
     disable();
     
     onClose();
 }   
Пример #2
0
    Request::Request( Connection& connection )
    : m_body( NULL ), m_connection( connection )
    {
        TRACE_ENTERLEAVE( );

        m_timestamp = sys::General::getMillisecondTimestamp( );
    }
Пример #3
0
    void Listener::listen( const Base& base)
    {
        TRACE_ENTERLEAVE();

        General::setSocketNonBlocking( m_socket );

        if ( m_socket.bind( m_port ) == sys::Socket::StatusFailed )
        {
            TRACE_ERROR( "cannot bind to socket, error %d", sys::General::getLastError() );
            throw BindError;
        }
        
        if ( m_socket.listen() == sys::Socket::StatusFailed )
        {
            throw ListenError;
        }

        m_listenerEvent = event_new( base, m_socket.s(), EV_READ | EV_PERSIST, onAcceptStatic,  this );

        if ( !m_listenerEvent )
        {
            throw GeneralError;
        }

        event_add( m_listenerEvent, NULL );
    }
Пример #4
0
void LuaState::loadlibs() const
{
    TRACE_ENTERLEAVE();
            
    luaL_openlibs( m_lua );
    
 }
Пример #5
0
void LuaState::execute( const std::string& script ) const
{
    TRACE_ENTERLEAVE();
    TRACE( "%s", script.c_str() );
    
     //
    //  debug.traceback function
    //
    lua_getglobal( m_lua, "debug");
    lua_getfield( m_lua, -1, "traceback");

    luaL_loadstring( m_lua, script.c_str() ); 
    
    int res = lua_pcall( m_lua, 0, LUA_MULTRET, -2 );

    if ( res )
    {
        std::string error = lua_tostring( m_lua, -1 ); 
        lua_pop( m_lua, 3 );
        
        TRACE_ERROR( "%s", error.c_str() );
        
        throw std::runtime_error( error );
    }
    
    //
    //  pop result or error from the stack
    //
    lua_pop( m_lua, 2 );
}
Пример #6
0
    void Server::onAccept( )
    {
        TRACE_ENTERLEAVE( );

        //
        //  accept new connection and add it to connection thread
        //
        sys::Socket* socket = m_socket.accept( );
        
        if ( !socket )
        {
            TRACE_ERROR( "accept failed, error %d", sys::Socket::getLastError( ) );
            return;
        }

        //
        //  get first connection thread
        //
        ConnectionThread* thread;
        
        {
            sys::LockEnterLeave lock( m_lock );
            
            if ( m_connectionThreads.size() < m_connectionThreadCount )
            {
                thread = new ConnectionThread( *this );
            }
            else
            {
                thread = m_connectionThreads.front( );
                m_connectionThreads.pop_front( );
            }
        }
        

        //
        //  create new connection  and assign it to connection thread. it mantains referencre count and will delete itself when no longer referenced
        //

        Connection* connection = newConnection( *thread, socket );

        if ( m_storeConnections )
        {
            thread->add( connection );
        }

        //
        //  enable events processing on this connection
        //  
        connection->enable( );
        
        //
        //  add connection thread to back
        //
        {
            sys::LockEnterLeave lock( m_lock );
            m_connectionThreads.push_back( thread );
        }
        
    }
Пример #7
0
    void Connection::onWrite( )
    {
        TRACE_ENTERLEAVE( );

        if ( !m_initialized )
        {
            //
            //  set timeouts if needed
            //
            if ( m_thread.server( ).getConnectionReadTimeout( ) > 0 )
            {
                setReadTimeout( m_thread.server( ).getConnectionReadTimeout( ) );
            }

            if ( m_thread.server( ).getConnectionWriteTimeout( ) > 0 )
            {
                setWriteTimeout( m_thread.server( ).getConnectionWriteTimeout( ) );
            }
        }

        if ( m_close )
        {
            disable( );
            onClose( );
        }
    }
Пример #8
0
void LuaState::setGlobal( const std::string& name, unsigned int value )
{
    TRACE_ENTERLEAVE();
    getGlobalTable();
    lua_pushinteger( m_lua, value );
    lua_setfield( m_lua, -2, name.c_str() );
    lua_pop( m_lua, 1 );
}
Пример #9
0
    Server::~Server( )
    {
        TRACE_ENTERLEAVE( );

        stop( );

        libevent::General::shutdown( );
    }
Пример #10
0
    void Server::ConnectionThread::add( Connection* connection )
    {
        TRACE_ENTERLEAVE( );

        sys::LockEnterLeave lock( m_lock );

        m_connections[ connection->id( ) ] = connection;
    }
Пример #11
0
LuaState& LuaState::luaFromThread( const sys::Thread& thread, unsigned int threadId )
{
    TRACE_ENTERLEAVE();
    
    LuaState& lua = *( ( LuaState* ) thread.data() );
    lua.reload( threadId );
    return lua;
}
Пример #12
0
    Server::Server( unsigned int port, EventHandler& handler )
    : libevent::Listener( port ), m_connectionThreadCount( 10 ), m_connectionReadTimeout( 0 ), 
      m_connectionWriteTimeout( 0 ),  m_poolThreadCount( 25 ),  m_eventHandler( handler ), m_timerThread( NULL ), m_storeConnections( false )
    {
        TRACE_ENTERLEAVE( );

        libevent::General::initThreads( );
    }
Пример #13
0
    void Server::TimerThread::onTimer( unsigned int interval, void* data )
    {
        TRACE_ENTERLEAVE( );

        //
        //      call back
        //
        m_server.eventHandler().onTimer( interval, data );
    }
Пример #14
0
    Server::ConnectionThread::ConnectionThread( Server& server )
    : m_server( server )
    {
        TRACE_ENTERLEAVE( );

        m_stackSize = 1024 * 1024 * 2;

        start( );
    }
Пример #15
0
    void Server::ConnectionThread::routine( )
    {
        TRACE_ENTERLEAVE( );

        //
        //  start event loop
        //
        m_base.start( );
    }
Пример #16
0
    Request::~Request( )
    {
        TRACE_ENTERLEAVE( );

        if ( m_body )
        {
            delete[] m_body;
        }
    }
Пример #17
0
void LuaState::create()
{
    if ( m_lua )
    {
        return;
    }
    
    TRACE_ENTERLEAVE();
    
    //
    //  create new lua state
    //
    m_lua = luaL_newstate( );

    // //
    // //  register api functons
    // //
    static const luaL_Reg functions[] = {
        {"serverAddTimer", serverAddTimer },
        {"serverCreate", serverCreate },
        {"serverConnectionSendData", serverConnectionSendData },
        {"serverConnectionGetAddress", serverConnectionGetAddress},
        {"serverConnectionGetId", serverConnectionGetId},
        {"serverSendTo", serverSendTo},
        {"clientCreate", clientCreate },
        {"clientConnect", clientConnect },
        {"clientAddTimer", clientAddTimer },
        {"clientConnectionSendData", clientConnectionSendData },
        {"clientConnectionClose", clientConnectionClose },
        {"getpid", getpid },
        {"processorCount", processorCount},
        {"httpRequestGetUrl", httpRequestGetUrl},
        {"httpRequestGetHeaders", httpRequestGetHeaders},
        {"httpRequestGetBody", httpRequestGetBody},
        {"httpRequestGetMethod", httpRequestGetMethod},
        {"httpRequestGetAddress", httpRequestGetAddress},
        {"httpResponseSetBody", httpResponseSetBody},
        {"httpResponseSetStatus", httpResponseSetStatus},
        {"httpResponseSetHeaders", httpResponseSetHeaders},
        {"httpResponseAddHeader", httpResponseAddHeader},
        {"getVersion", getVersion},
        {"dictionaryGet", dictionaryGet},
        {"dictionarySet", dictionarySet},
        {"dictionaryRemove", dictionaryRemove},
        {"dictionaryGetKeys", dictionaryGetKeys},
        {"processStart", processStart},
        {"processWrite", processWrite},
        
        {NULL, NULL }
    };

    luaL_register( m_lua, "__api", functions );
    
    loadlibs();
        
}
Пример #18
0
    void Base::stop( ) const
    {
        TRACE_ENTERLEAVE( );

        if ( m_base )
        {
            event_base_loopexit( m_base, NULL );
        }

    }
Пример #19
0
    void Connection::setReadTimeout( unsigned int value )
    {
        TRACE_ENTERLEAVE();

        timeval timeout;
        timeout.tv_sec = ( long ) value;
        timeout.tv_usec = 0;

        bufferevent_set_timeouts( m_handle, &timeout, NULL );
    }
Пример #20
0
    Server::ConnectionThread::~ConnectionThread( )
    {
        TRACE_ENTERLEAVE( );

        m_base.stop();

        while ( !m_connections.empty( ) )
        {
            remove( m_connections.begin( )->second, true );
        }
    }
Пример #21
0
    void Server::onTaskProcess( sys::ThreadPool::Task* task, sys::ThreadPool::Worker& thread )
    {
        TRACE_ENTERLEAVE( );

        Task* serverTask = ( Task* ) task; 

        //
        //  invoke callback
        //
        eventHandler().onRequest( *serverTask->request, *serverTask->response, thread );      
        delete serverTask;
    }
Пример #22
0
 void Server::ConnectionThread::broadcast( const Message& message )
 {
     TRACE_ENTERLEAVE();
     
     sys::LockEnterLeave lock( m_lock );
     
     TRACE( "%d", m_connections.size() );
     
     for ( std::map< intptr_t, Connection* >::iterator i = m_connections.begin(); i != m_connections.end(); i++ )
     {
         i->second->write( message.contents, message.length );
     }
 }
Пример #23
0
LuaState::LuaState( const std::string& filename, const ScriptArguments* arguments  )
: m_lua( NULL ), m_close( true ), m_filename( filename )
{
    TRACE_ENTERLEAVE();
    
    if ( arguments )
    {
        m_arguments = *arguments;
    }
    
    create();
    
}
Пример #24
0
    void Connection::writeFormat( const char* format, ... )
    {
        TRACE_ENTERLEAVE();
        
        va_list args;
        va_start(args, format);

        vprintf( format, args );

        int written = evbuffer_add_vprintf( m_output, format, args );

        va_end(args);
    }
Пример #25
0
    Connection::~Connection( )
    {
        TRACE_ENTERLEAVE( );

        
        m_thread.remove( this );
        
        if ( m_request )
        {
            delete m_request;
        }
        
        
    }
Пример #26
0
void LuaState::destroy()
{
    TRACE_ENTERLEAVE();
    
    if ( m_lua && m_close )
    {
        //
        //  close lua state if it was created by this instance
        //
        lua_close( m_lua );
        
        m_lua = NULL;
    }
}
Пример #27
0
    void Server::addTimer( unsigned int interval, void* data )
    {
        TRACE_ENTERLEAVE( );
        
        //
        //  create timer thread
        //
        if ( !m_timerThread )
        {
            m_timerThread = new TimerThread( *this );
        }

        m_timerThread->add( interval, data );
    }
Пример #28
0
void LuaState::addPaths( const char* name ) const
{
    TRACE_ENTERLEAVE();
    
    //
    // modify package search path
    //
    lua_getglobal( m_lua, "package" );
    lua_getfield( m_lua, -1, name );
    
    if ( lua_isnil( m_lua, -1 ) )
    {
        TRACE( "package.%s is not set in lua", name );
        lua_pop( m_lua, 1 );
        return;
    }
    
    std::string path = lua_tostring( m_lua, -1 );
    
    std::string separator = "/";
#ifdef WIN32
    separator = "\\";
#endif
    
    std::string initName =  path.substr( path.find_last_of( separator ) );
    const char* ext = strstr( initName.c_str(), "." );
    
    for ( std::list< std::string >::const_iterator i = Leda::instance()->paths().begin( ); i != Leda::instance()->paths().end( ); i++ )
    {
        path.append( ";" );
        path.append( *i );
        path.append( separator );
        path.append( "?" );
        path.append( ext );
        
        
        path.append( ";" );
        path.append( *i );
        path.append( separator );
        path.append( "?" );
        path.append( initName );
    }

    TRACE( "%s: %s", name, path.c_str( ) );
    lua_pop( m_lua, 1 );
    lua_pushstring( m_lua, path.c_str( ) );
    lua_setfield( m_lua, -2, name );
    lua_pop( m_lua, 1 );
}
Пример #29
0
    void Connection::onError( short error )
    {
        TRACE_ENTERLEAVE();

        if ( error & BEV_EVENT_EOF || error & BEV_EVENT_ERROR)
        {
            close();
            return;
        }

        if ( error & BEV_EVENT_TIMEOUT )
        {
            close();
        }
    }
Пример #30
0
 void Server::broadcast( const Message& message )
 {
     TRACE_ENTERLEAVE();
     
     if ( !m_storeConnections || m_connectionThreads.empty() )
     {
         return;
     }
     
     sys::LockEnterLeave lock( m_lock ); 
 
     for ( std::list< ConnectionThread* >::iterator i = m_connectionThreads.begin( ); i != m_connectionThreads.end( ); i++ )
     {
         ( *i )->broadcast( message );
     }
     
 }