void mq_push_list(mq_t m,struct link_list *l,uint32_t timeout) { struct per_thread_struct *pts = (struct per_thread_struct*)pthread_getspecific(m->t_key); if(!pts) { pts = per_thread_create(); LINK_LIST_PUSH_BACK(m->local_lists,pts); pthread_setspecific(m->t_key,(void*)pts); } if(link_list_is_empty(pts->local_pop_q)) mq_sync_pop(m,pts,timeout); link_list_swap(l,pts->local_pop_q); }
static void write_to_file(log_t l,int32_t is_close) { mutex_lock(l->mtx); if(!list_is_empty(l->log_queue)) link_list_swap(l->pending_log,l->log_queue); mutex_unlock(l->mtx); if(is_close) { //日志系统关闭,写入关闭消息 char buf[4096]; time_t t = time(NULL); struct tm re; struct tm *_tm = localtime_r(&t,&re); snprintf(buf,4096,"[%d-%d-%d %d:%d:%d]close log sucessful\n",_tm->tm_year+1900,_tm->tm_mon+1,_tm->tm_mday,_tm->tm_hour,_tm->tm_min,_tm->tm_sec); int32_t str_len = strlen(buf); wpacket_t w = wpacket_create(0,NULL,str_len,1); wpacket_write_binary(w,buf,str_len); LINK_LIST_PUSH_BACK(l->pending_log,w); } while(!list_is_empty(l->pending_log)) { int32_t wbuf_count = prepare_write(l); int32_t bytetransfer = TEMP_FAILURE_RETRY(writev(l->file_descriptor,l->wbuf,wbuf_count)); if(bytetransfer > 0) { l->file_size += bytetransfer; on_write_finish(l,bytetransfer); g_log_system->bytes += bytetransfer; } if(bytetransfer <= 0) { printf("errno: %d wbuf_count: %d\n",errno,wbuf_count); } if(last_tick +1000 <= GetSystemMs()) { printf("log/ms:%u\n",log_count); last_tick = GetSystemMs(); log_count = 0; } } if(!is_close) { /* * if(l->file_size > max_log_filse_size) * 文件超过一定大小,将原文件重命名,开一个新的文件 */ } }
static inline mq_sync_push(mq_t m,struct per_thread_struct *pts) { mutex_lock(m->mtx); uint8_t empty = link_list_is_empty(m->share_list); link_list_swap(m->share_list,pts->local_push_q); if(empty) { struct double_link_node *l = double_link_pop(&m->blocks); if(l) { //if there is block per_thread_struct wake it up struct per_thread_struct *block_pts = (struct per_thread_struct *)((uint8_t*)l - sizeof(struct list_node)); mutex_unlock(m->mtx); condition_signal(block_pts->cond); return; } } mutex_unlock(m->mtx); }
static inline mq_sync_pop(mq_t m,struct per_thread_struct *pts,uint32_t timeout) { mutex_lock(m->mtx); if(link_list_is_empty(m->share_list)) { if(timeout) { while(link_list_is_empty(m->share_list)) { double_link_push(&m->blocks,&pts->block); if(0 != condition_timedwait(pts->cond,m->mtx,timeout)) { double_link_remove(&pts->block); break; } } } } link_list_swap(pts->local_pop_q,m->share_list); mutex_unlock(m->mtx); }
void connector_run(connector_t c,uint32_t ms) { int32_t i = 0; uint32_t tick,_timeout,_ms; int32_t size; int32_t total; struct pending_connect *pc; struct timeval timeout; tick = GetSystemMs(); _timeout = tick + ms; struct link_list *_l = LINK_LIST_CREATE(); mutex_lock(c->lock); link_list_swap(_l,c->extern_pending_connect); mutex_unlock(c->lock); while(pc = LINK_LIST_POP(struct pending_connect*,_l)) { if(c->fd_seisize >= FD_SETSIZE) { pc->call_back(-1,pc->ip,pc->port,pc->ud); free(pc); } else { FD_SET(pc->real_fd,&c->Set); LINK_LIST_PUSH_BACK(c->_pending_connect,pc); ++c->fd_seisize; } } LINK_LIST_DESTROY(&_l); do{ _ms = _timeout - tick; timeout.tv_sec = 0; timeout.tv_usec = 1000*_ms; size = list_size(c->_pending_connect); if(size == 0) return; if((total = select(1024,0,&c->Set,0, &timeout)) >0 ) { for(; i < size; ++i) { pc = LINK_LIST_POP(struct pending_connect*,c->_pending_connect); if(pc) { if(FD_ISSET(pc->real_fd, &c->Set)) { pc->call_back(pc->sock,pc->ip,pc->port,pc->ud); free(pc); --c->fd_seisize; } else LINK_LIST_PUSH_BACK(c->_pending_connect,pc); } } } FD_ZERO(&c->Set); tick = GetSystemMs(); size = list_size(c->_pending_connect); i = 0; for(; i < (int32_t)size; ++i) { pc = LINK_LIST_POP(struct pending_connect*,c->_pending_connect); if(tick >= pc->timeout) { pc->call_back(-1,pc->ip,pc->port,pc->ud); free(pc); --c->fd_seisize; } else { LINK_LIST_PUSH_BACK(c->_pending_connect,pc); FD_SET(pc->real_fd,&c->Set); } } tick = GetSystemMs(); }while(tick < _timeout); }