Ejemplo n.º 1
0
void * iothread_main( void * arg )
{
    uint32_t maxtasks = 0;

    struct iothread * thread = (struct iothread *)arg;
    struct iothreads * parent = (struct iothreads *)(thread->parent);

    sigset_t mask;
    sigfillset(&mask);
    pthread_sigmask(SIG_SETMASK, &mask, NULL);

    // 初始化队列
    struct taskqueue doqueue;
    QUEUE_INIT(taskqueue)( &doqueue, MSGQUEUE_DEFAULT_SIZE );

    for ( ; parent->runflags; )
    {
        uint32_t nprocess = 0;

        // 轮询网络事件
        evsets_dispatch( thread->sets );

        // 处理事件
        nprocess = _process( parent, thread, &doqueue );

        // 最大任务数
        maxtasks = MAX( maxtasks, nprocess );
    }

    // 清理队列中剩余数据
    _process( parent, thread, &doqueue );
    // 清空队列
    QUEUE_CLEAR(taskqueue)( &doqueue );

    // 日志
    syslog( LOG_INFO, "%s(INDEX=%d) : the Maximum Number of Requests is %d in EachFrame .",
            __FUNCTION__, thread->index, maxtasks );

    // 向主线程发送终止信号
    pthread_mutex_lock( &parent->lock );
    --parent->nrunthreads;
    pthread_cond_signal( &parent->cond );
    pthread_mutex_unlock( &parent->lock );

    return NULL;
}
void * iothread_main( void * arg )
{
    struct iothread * thr = (struct iothread *)arg;

    thr->running = 1;
    while ( thr->running )
    {
        //
        // 尝试加锁
        //
        trylock_accept_mutex( thr );

        //
        // 分发IO事件
        //
        evsets_dispatch( thr->core_sets );
    }

    return (void *)0;
}
Ejemplo n.º 3
0
int32_t test_evtimer()
{
    evsets_t sets = NULL;
    event_t ev_timer = NULL;

    sets = evsets_create();

    ev_timer = event_create();
    event_set( ev_timer, -1, 0 );
    event_set_callback( ev_timer, ev_timer_callback, ev_timer );

    evsets_add( sets, ev_timer, 2*1000 );

    while( 1 )
    {
        evsets_dispatch( sets );
    }

    event_destroy( ev_timer );
    evsets_destroy( sets );

    return 0;
}
Ejemplo n.º 4
0
int main( int argc, char ** argv )
{
    if ( argc != 2 )
    {
        printf("echoserver [port] .\n");
        return 0;
    }

    evsets_t coreset = evsets_create();
    if ( coreset == NULL )
    {
        printf( "create core event sets failed .\n" );
        goto FINAL;
    }

    signal( SIGPIPE, SIG_IGN );
    signal( SIGINT, echoserver_signal_handler );
    signal( SIGTERM, echoserver_signal_handler );

    // listen port
    uint16_t port = (uint16_t)atoi( argv[1] );
    int32_t fd = tcp_listen( "127.0.0.1", port, listenfd_options );
    if ( fd < 0 )
    {
        printf( "listen failed %d .\n", port );
        goto FINAL;
    }
    set_non_block( fd );
    event_t evaccept = event_create();
    if ( evaccept == NULL )
    {
        printf( "create accept event failed .\n" );
        goto FINAL;
    }
    event_set( evaccept, fd, EV_READ|EV_PERSIST );
    event_set_callback( evaccept, accept_new_session, coreset );
    evsets_add( coreset, evaccept, 0 );

    // running ...
    isrunning = 1;
    while ( isrunning == 1 )
    {
        evsets_dispatch( coreset );
    }

FINAL :
    if ( evaccept != NULL )
    {
        event_destroy( evaccept );
    }

    if ( fd > 0 )
    {
        close( fd );
    }

    if ( coreset != NULL )
    {
        evsets_destroy( coreset );
    }

    return 0;
}
Ejemplo n.º 5
0
void echoserver_process_message( int32_t fd, int16_t ev, void * arg )
{
    struct session * s = (struct session *)arg;

    if ( ev & EV_READ )
    {
        char buf[16384];
        int32_t readn = -1;

        readn = read( fd, buf, 16384 );
        if ( readn <= 0 )
        {
#if __DEBUG
            printf( "Client[%ld, %d] is closed, BYTES:%d, TIME:%lld .\n",
                s->sid, s->fd, s->iobytes, milliseconds() );
#endif
            //evsets_del( event_get_sets(s->evread), s->evread );
            event_destroy( s->evread );
            close( s->fd );
            free( s );

            goto PROCESS_END;
        }
        else
        {
#if __DEBUG
            printf("echoserver_process_message(ev:%d) : TIME:%lld .\n", ev, milliseconds() );
#endif
            readn = write( fd, buf, readn );
            s->iobytes += readn;
        }

#if USE_LIBEVENT
        {
            struct timeval tv = {TIMEOUT_MSECS/1000, 0};
            event_add( s->evread, &tv );
        }
#else
        evsets_add( event_get_sets(s->evread), s->evread, TIMEOUT_MSECS );
#endif
    }
    else
    {
#if __DEBUG
        printf("echoserver_process_message(ev:%d) : TIME:%lld .\n", ev, milliseconds() );
#endif
    }

PROCESS_END :
}

void accept_new_session( int32_t fd, int16_t ev, void * arg )
{
    struct iothread * thr = (struct iothread *)arg;
    struct acceptor * a = thr->core_acceptor;

    if ( ev & EV_READ )
    {
        //
        // 接收新连接完毕后
        //
        char srchost[20];
        char dsthost[20];
        uint16_t dstport = 0;

        int32_t newfd = tcp_accept( fd, srchost, dsthost, &dstport );
        if ( newfd > 0 )
        {
            uint64_t sid = 0;
            struct session * newsession = NULL;

            set_fd_nonblock( newfd );

            newsession = (struct session *)malloc( sizeof(struct session) );
            if ( newsession == NULL )
            {
                printf("Out of memory, allocate for 'newsession' failed .\n");
                goto ACCEPT_END;
            }

            newsession->evread = event_create();
            if ( newsession->evread == NULL )
            {
                printf("Out of memory, allocate for 'newsession->evread' failed .\n");
                goto ACCEPT_END;
            }

            newsession->iobytes = 0;
            newsession->fd = newfd;

            sid = thr->key;
            sid <<= 32;
            sid += thr->index++;
            newsession->sid = sid;

#if USE_LIBEVENT
            {
                struct timeval tv = {TIMEOUT_MSECS/1000, 0};
                event_set( newsession->evread, newsession->fd, EV_READ, echoserver_process_message, newsession );
                event_base_set( thr->core_sets, newsession->evread );
                event_add( newsession->evread, &tv );
            }
#else
            event_set( newsession->evread, newsession->fd, EV_READ );
            event_set_callback( newsession->evread, echoserver_process_message, newsession );
            evsets_add( thr->core_sets, newsession->evread, TIMEOUT_MSECS );
#endif

#if __DEBUG
            printf( "Thread[%d] accept a new Client[%lld, fd:%d, '%s':%d] .\n",
                thr->key, newsession->sid, newsession->fd, dsthost, dstport );
#endif
        }

        a->holding = 0;
        pthread_mutex_unlock( &(a->lock) );
    }

ACCEPT_END :
}

void trylock_accept_mutex( struct iothread * thr )
{
    struct acceptor * a = thr->core_acceptor;

    if ( pthread_mutex_trylock(&(a->lock)) == 0 )
    {
        if ( a->holding == 0 )
        {
#if USE_LIBEVENT
            event_set( a->ev_accept, a->socketfd, EV_READ, accept_new_session, thr );
            event_base_set( thr->core_sets, a->ev_accept );
            event_add( a->ev_accept, 0 );
#else
            event_set( a->ev_accept, a->socketfd, EV_READ );
            event_set_callback( a->ev_accept, accept_new_session, thr );
            evsets_add(thr->core_sets, a->ev_accept, 0 );
#endif
            a->holding = 1;
        }

        //pthread_mutex_unlock( &(a->lock) );
    }
}

void acceptor_destroy( struct acceptor * self )
{
    pthread_mutex_destroy( &(self->lock) );

    if ( self->socketfd > 0 )
    {
        close( self->socketfd );
    }

    if ( self->ev_accept != NULL )
    {
        event_destroy( self->ev_accept );
    }

    free( self );
}

struct acceptor * acceptor_create( const char * host, uint16_t port )
{
    struct acceptor * a = NULL;

    a = (struct acceptor *)malloc( sizeof(struct acceptor) );
    if ( a )
    {
        a->holding = 0;
        a->socketfd = 0;
        a->ev_accept = NULL;
        pthread_mutex_init( &(a->lock), NULL );

        a->socketfd = tcp_listen( host, port );
        if ( a->socketfd < 0 )
        {
            acceptor_destroy( a );
            return NULL;
        }

        set_fd_nonblock( a->socketfd );

        a->ev_accept = event_create();
        if ( a->ev_accept == NULL )
        {
            acceptor_destroy( a );
            return NULL;
        }
    }

    return a;
}

void * iothread_main( void * arg )
{
    struct iothread * thr = (struct iothread *)arg;

    thr->running = 1;
    while ( thr->running )
    {
        //
        // 尝试加锁
        //
        trylock_accept_mutex( thr );

        //
        // 分发IO事件
        //
        evsets_dispatch( thr->core_sets );
    }

    return (void *)0;
}

struct iothread * iothread_create( uint8_t key, struct acceptor * a )
{
    pthread_t tid;
    struct iothread * thr = NULL;

    thr = (struct iothread *)malloc( sizeof(struct iothread) );
    if ( thr )
    {
        thr->key = key;
        thr->index = 0;
        thr->core_acceptor = a;

        thr->core_sets = evsets_create();
        if ( thr->core_sets == NULL )
        {
#if __DEBUG
            printf( "out of memory, allocate for 'thr->core_sets' failed, Thread[%d] .\n", key );
#endif
            return NULL;
        }

        pthread_create( &tid, NULL, iothread_main, thr );
    }

    return thr;
}
Ejemplo n.º 6
0
void * iothread_main( void * arg )
{
	struct iothread * thread = (struct iothread *)arg;
	struct iothreads * parent = (struct iothreads *)(thread->parent);

	int32_t i = 0;
	int32_t ntasks = 0;
	struct task tasks[ POP_TASKS_COUNT ];

	while ( parent->runflags )
	{
		// 轮询网络事件
		evsets_dispatch( thread->sets );

		// 处理任务
		do
		{
			ntasks = msgqueue_pops( thread->queue, tasks, POP_TASKS_COUNT );
			for ( i = 0; i < ntasks; ++i )
			{
				void * data = NULL;

				switch ( tasks[i].type )
				{
				case eTaskType_Null :
					{
						// 空命令
						continue;
					}
					break;

				case eTaskType_User :
					{
						// 用户命令
						data = tasks[i].task;
					}
					break;

				case eTaskType_Data :
					{
						// 数据命令
						data = (void *)(tasks[i].data);
					}
					break;
				}

				// 回调
				parent->method( parent->context, thread->index, tasks[i].utype, data );
			}
		}
		while ( ntasks == POP_TASKS_COUNT );
	}

	// 向主线程发送终止信号
	pthread_mutex_lock( &parent->lock );
	--parent->nrunthreads;
	pthread_cond_signal( &parent->cond );
	pthread_mutex_unlock( &parent->lock );
	
	return NULL;
}