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; }
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; }
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; }
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; }
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; }