Esempio n. 1
0
int32_t iolayer_shutdowns( iolayer_t self, sid_t * ids, uint32_t count )
{
    uint8_t i = 0;
    int32_t rc = 0;
    struct iolayer * layer = (struct iolayer *)self;

    for ( i = 0; i < layer->nthreads; ++i )
    {
        struct sidlist * list = sidlist_create( count );
        if ( list == NULL )
        {
            continue;
        }
        sidlist_adds( list, ids, count );

        // 参照iolayer_shutdown()

        // 跨线程提交批量终止任务
        int32_t result = iothreads_post( layer->group, i, eIOTaskType_Shutdowns, list, 0 );
        if ( unlikely(result != 0) )
        {
            sidlist_destroy( list );
            continue;
        }

        rc += count;
    }

    return rc;
}
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_assign_session( struct iolayer * self, uint8_t index, struct task_assign * task )
{
    evsets_t sets = iothreads_get_sets( self->group, index );
    pthread_t threadid = iothreads_get_id( self->group, index );

    if ( pthread_self() == threadid )
    {
        return _assign_direct( self, index, sets, task );
    }

    // 跨线程提交发送任务
    return iothreads_post( self->group, index, eIOTaskType_Assign, task, sizeof(struct task_assign) );
}
Esempio n. 4
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. 5
0
// 服务器开启
//        host        - 绑定的地址
//        port        - 监听的端口号
//        cb            - 新会话创建成功后的回调,会被多个网络线程调用
//                            参数1: 上下文参数;
//                            参数2: 网络线程本地数据(线程安全)
//                            参数3: 新会话ID;
//                            参数4: 会话的IP地址;
//                            参数5: 会话的端口号
//        context        - 上下文参数
int32_t iolayer_listen( iolayer_t self,
        const char * host, uint16_t port,
        int32_t (*cb)( void *, void *, sid_t, const char * , uint16_t ), void * context )
{
    struct iolayer * layer = (struct iolayer *)self;

    struct acceptor * acceptor = calloc( 1, sizeof(struct acceptor) );
    if ( acceptor == NULL )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, Out-Of-Memory .", __FUNCTION__, host, port);
        return -1;
    }

    acceptor->event = event_create();
    if ( acceptor->event == NULL )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, can't create AcceptEvent.", __FUNCTION__, host, port);
        return -2;
    }

    acceptor->fd = tcp_listen( (char *)host, port, iolayer_server_option );
    if ( acceptor->fd <= 0 )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, tcp_listen() failure .", __FUNCTION__, host, port);
        return -3;
    }

    acceptor->cb = cb;
    acceptor->context = context;
    acceptor->parent = self;
    acceptor->port = port;
    acceptor->host[0] = 0;
    if ( host != NULL )
    {
        strncpy( acceptor->host, host, INET_ADDRSTRLEN );
    }

    iothreads_post( layer->group, (acceptor->fd%layer->nthreads), eIOTaskType_Listen, acceptor, 0 );

    return 0;
}
Esempio n. 6
0
int32_t iolayer_broadcast( iolayer_t self, sid_t * ids, uint32_t count, const char * buf, uint32_t nbytes )
{
    uint8_t i = 0;
    int32_t rc = 0;

    pthread_t threadid = pthread_self();
    struct iolayer * layer = (struct iolayer *)self;

    for ( i = 0; i < layer->nthreads; ++i )
    {
        struct message * msg = message_create();
        if ( unlikely(msg == NULL) )
        {
            continue;
        }
        message_add_receivers( msg, ids, count );
        message_add_buffer( msg, (char *)buf, nbytes );

        if ( threadid == iothreads_get_id( layer->group, i ) )
        {
            // 本线程内直接广播
            _broadcast_direct( layer, i, _get_manager(layer, i), msg );
        }
        else
        {
            // 跨线程提交广播任务
            int32_t result = iothreads_post( layer->group, i, eIOTaskType_Broadcast, msg, 0 );
            if ( unlikely(result != 0) )
            {
                message_destroy( msg );
                continue;
            }
        }

        rc += count;
    }

    return rc;
}
Esempio n. 7
0
// 客户端开启
//        host        - 远程服务器的地址
//        port        - 远程服务器的端口
//        seconds        - 连接超时时间
//        cb            - 连接结果的回调
//                            参数1: 上下文参数
//                            参数2: 网络线程本地数据(线程安全)
//                            参数3: 连接结果
//                            参数4: 连接的远程服务器的地址
//                            参数5: 连接的远程服务器的端口
//                            参数6: 连接成功后返回的会话ID
//        context        - 上下文参数
int32_t iolayer_connect( iolayer_t self,
        const char * host, uint16_t port, int32_t seconds,
        int32_t (*cb)( void *, void *, int32_t, const char *, uint16_t , sid_t), void * context )
{
    struct iolayer * layer = (struct iolayer *)self;

    struct connector * connector = calloc( 1, sizeof(struct connector) );
    if ( connector == NULL )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, Out-Of-Memory .", __FUNCTION__, host, port);
        return -1;
    }

    connector->event = event_create();
    if ( connector->event == NULL )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, can't create ConnectEvent.", __FUNCTION__, host, port);
        return -2;
    }

    connector->fd = tcp_connect( (char *)host, port, iolayer_client_option );
    if ( connector->fd <= 0 )
    {
        syslog(LOG_WARNING, "%s(host:'%s', port:%d) failed, tcp_connect() failure .", __FUNCTION__, host, port);
        return -3;
    }

    connector->cb = cb;
    connector->context = context;
    connector->mseconds = seconds*1000;
    connector->parent = self;
    connector->port = port;
    strncpy( connector->host, host, INET_ADDRSTRLEN );

    iothreads_post( layer->group, (connector->fd%layer->nthreads), eIOTaskType_Connect, connector, 0 );

    return 0;
}
Esempio n. 8
0
int32_t main()
{
    uint64_t index = 0;

    uint8_t i = 0;
    uint8_t nthreads = 4;

    iothreads_t threadgroup;
    uint64_t start_time = 0, end_time = 0;

    struct iothread_args * args = NULL;

    srand( (int32_t)time(NULL) );
    signal( SIGINT, signal_handler );

    //
    threadgroup = iothreads_start( nthreads, 0, task_method, NULL );
    if ( threadgroup == NULL )
    {
        printf("iothreads_start() failed \n");
        return -1;
    }

    args = (struct iothread_args *)calloc( nthreads, sizeof(struct iothread_args) );
    if ( args == NULL )
    {
        printf("calloc for 'iothread_args' failed \n");
        return -2;
    }

    //
    runflags = 1;

    //
    start_time = milliseconds();
    while ( runflags )
    {
        uint8_t _index = index&(nthreads-1);
        struct iothread_args * _args = args + _index;

        iothreads_post( threadgroup, _index, 0, _args, 0 );
        ++index;
    }
    end_time = milliseconds();

    //
    iothreads_stop( threadgroup );

    //
    for ( i = 0; i < nthreads; ++i )
    {
        struct iothread_args * _args = args + i;
        float rate = (float)(_args->taskcount)*1000.0f/(float)(end_time-start_time);

        printf("iothread[%d] process tasks: %ld, rate: %6.3f\n", i, _args->taskcount, rate );
    }

    printf("dispatch tasks: %ld, rate: %6.3f\n", index, (float)(index)*1000.0f/(float)(end_time-start_time) );

    return 0;
}