Esempio n. 1
0
int32_t _shutdowns_direct( uint8_t index, struct session_manager * manager, struct sidlist * ids )
{
    uint32_t i = 0;
    int32_t count = 0;

    for ( i = 0; i < sidlist_count(ids); ++i )
    {
        sid_t id = sidlist_get(ids, i);

        if ( SID_INDEX(id) != index )
        {
            continue;
        }

        struct session * session = session_manager_get( manager, id );
        if ( session == NULL )
        {
            continue;
        }

        // 直接终止
        ++count;
        session_close( session );
        session_shutdown( session );
    }

    sidlist_destroy( ids );

    return count;
}
Esempio n. 2
0
int32_t iolayer_shutdown( iolayer_t self, sid_t id )
{
    uint8_t index = SID_INDEX(id);
    struct iolayer * layer = (struct iolayer *)self;

    if ( index >= layer->nthreads )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index );
        return -1;
    }

    // 避免在回调函数中直接终止会话
    // 这样会引发后续对会话的操作都非法了
#if 0
    if ( pthread_self() == iothreads_get_id( layer->group, index ) )
    {
        // 本线程内直接终止
        return _shutdown_direct( _get_manager(layer, index), &task );
    }
#endif

    // 跨线程提交终止任务
    return iothreads_post( layer->group, index, eIOTaskType_Shutdown, (void *)&id, sizeof(id) );

}
Esempio n. 3
0
int32_t iolayer_set_service( iolayer_t self, sid_t id, ioservice_t * service, void * context )
{
    // NOT Thread-Safe
    uint8_t index = SID_INDEX(id);
    struct iolayer * layer = (struct iolayer *)self;

    if ( index >= layer->nthreads )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index );
        return -1;
    }

    struct session_manager * manager = _get_manager( layer, index );
    if ( manager == NULL )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's manager[%u] is invalid .", __FUNCTION__, id, index );
        return -2;
    }

    struct session * session = session_manager_get( manager, id );
    if ( session == NULL )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__, id );
        return -3;
    }

    session->context = context;
    session->service = *service;

    return 0;
}
Esempio n. 4
0
int32_t iolayer_set_keepalive( iolayer_t self, sid_t id, int32_t seconds )
{
    // NOT Thread-Safe
    uint8_t index = SID_INDEX(id);
    struct iolayer * layer = (struct iolayer *)self;

    if ( index >= layer->nthreads )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index );
        return -1;
    }

    struct session_manager * manager = _get_manager( layer, index );
    if ( manager == NULL )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's manager[%u] is invalid .", __FUNCTION__, id, index );
        return -2;
    }

    struct session * session = session_manager_get( manager, id );
    if ( session == NULL )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__, id );
        return -3;
    }

    session->setting.keepalive_msecs = seconds*1000;

    return 0;
}
Esempio n. 5
0
int32_t _broadcast_direct( struct iolayer * self, uint8_t index, struct session_manager * manager, struct message * msg )
{
    uint32_t i = 0;
    int32_t count = 0;

    // 数据改造
    if ( self->transform != NULL )
    {
        // 数据需要改造
        char * buffer = NULL;
        uint32_t nbytes = message_get_length( msg );
        buffer = self->transform( self->context, message_get_buffer(msg), &nbytes );
        if ( buffer == NULL )
        {
            // 数据改造失败
            message_destroy( msg );
            return -1;
        }
        if ( buffer != message_get_buffer(msg) )
        {
            // 数据改造成功
            message_set_buffer( msg, buffer, nbytes );
        }
    }

    for ( i = 0; i < sidlist_count(msg->tolist); ++i )
    {
        sid_t id = sidlist_get(msg->tolist, i);

        if ( SID_INDEX(id) != index )
        {
            message_add_failure( msg, id );
            continue;
        }

        struct session * session = session_manager_get( manager, id );
        if ( unlikely(session == NULL) )
        {
            message_add_failure( msg, id );
            continue;
        }

        if ( session_append(session, msg) >= 0 )
        {
            // 尝试单独发送
            // 添加到发送队列成功
            ++count;
        }
    }

    // 消息发送完毕, 直接销毁
    if ( message_is_complete(msg) )
    {
        message_destroy( msg );
    }

    return count;
}
Esempio n. 6
0
int32_t _send_buffer( struct iolayer * self, sid_t id, const char * buf, uint32_t nbytes, int32_t isfree )
{
    int32_t result = 0;
    uint8_t index = SID_INDEX(id);

    if ( unlikely(index >= self->nthreads) )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session's index[%u] is invalid .", __FUNCTION__, id, index );
        return -1;
    }

    struct task_send task;
    task.id     = id;
    task.nbytes = nbytes;
    task.isfree = isfree;
    task.buf    = (char *)buf;

    if ( pthread_self() == iothreads_get_id( self->group, index ) )
    {
        return _send_direct( self, _get_manager(self, index), &task );
    }

    // 跨线程提交发送任务

    if ( isfree == 0 )
    {
        task.buf = (char *)malloc( nbytes );
        if ( unlikely( task.buf == NULL ) )
        {
            syslog(LOG_WARNING, "%s(SID=%ld) failed, can't allocate the memory for '_buf' .", __FUNCTION__, id );
            return -2;
        }

        task.isfree = 1;
        memcpy( task.buf, buf, nbytes );
    }

    result = iothreads_post( self->group, index, eIOTaskType_Send, (void *)&task, sizeof(task) );
    if ( unlikely( result != 0 ) )
    {
        free( task.buf );
    }

    return result;
}
Esempio n. 7
0
int32_t _append_session( struct hashtable * table, struct session * s )
{
    struct hashnode * node = _find_table( table, s->id, 1 );

    if ( unlikely(node == NULL) )
    {
        return -1;
    }

    if ( unlikely( node->session != NULL && node->session->id == s->id ) )
    {
        syslog(LOG_WARNING, "%s(Index=%d): the SID (Seq=%u, Sid=%ld) conflict !",
                __FUNCTION__, (int32_t)SID_INDEX(s->id), (uint32_t)SID_SEQ(s->id), s->id );
        return -2;
    }

    ++table->count;
    node->session = s;

    return 0;
}