Exemple #1
0
int32_t _send( struct session * self, char * buf, uint32_t nbytes )
{
    int32_t rc = 0;

    if ( self->status&SESSION_EXITING )
    {
        // 等待关闭的连接
        return -1;
    }

    // 判断session是否繁忙
    if ( !(self->status&SESSION_WRITING)
            && session_sendqueue_count(self) == 0 )
    {
        // 直接发送
        rc = channel_send( self, buf, nbytes );
        if ( rc == nbytes )
        {
            // 全部发送出去
            return rc;
        }

        // 为什么发送错误没有直接终止会话呢?
        // 该接口有可能在ioservice_t中调用, 直接终止会话后, 会引发后续对会话的操作崩溃
    }

    // 创建message, 添加到发送队列中
    struct message * message = message_create();
    if ( message == NULL )
    {
        return -2;
    }

    message_add_buffer( message, buf+rc, nbytes-rc );
    message_add_receiver( message, self->id );
    QUEUE_PUSH(sendqueue)(&self->sendqueue, &message);
    session_add_event( self, EV_WRITE );

    return rc;
}
Exemple #2
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;
}