Beispiel #1
0
/*与void mq_push(mq_t m,struct list_node *msg)
* 的区别,无论如何也不会调用mq_sync_push
*/
struct per_thread_struct* mq_push_local(mq_t m,struct list_node *msg)
{
	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(0 == pts->is_associate)
	{
		struct thread_associate_mqs *tmq = (struct thread_associate_mqs*)pthread_getspecific(g_mq_system->t_key);
		if(!tmq)
		{
			tmq = (struct thread_associate_mqs*)calloc(1,sizeof(tmq));
			tmq->mqs = LINK_LIST_CREATE();
			mutex_lock(g_mq_system->mtx);
			LINK_LIST_PUSH_BACK(g_mq_system->thread_mqs,tmq);
			mutex_unlock(g_mq_system->mtx);
			pthread_setspecific(g_mq_system->t_key,(void*)tmq);	
		}
		struct thread_mq_element *ele = calloc(1,sizeof(*ele));
		ele->_mq = m;
		LINK_LIST_PUSH_BACK(tmq->mqs,ele);
		pts->is_associate = 1;
	}
	LINK_LIST_PUSH_BACK(pts->local_push_q,msg);
	return pts;
}
Beispiel #2
0
void check_time_out(sche_t s,uint32_t now)
{
	coro_t co;
	for( ; ;)
	{
		struct heapele *ele = minheap_min(s->_minheap);
		if(!ele)
			break;
		co = (coro_t)((int8_t*)ele - sizeof(co->next));
		if(co->timeout < now)
			break;
		minheap_popmin(s->_minheap);
		if(co->status != CORO_ACTIVE)
		{
			co->status = CORO_ACTIVE;
			LINK_LIST_PUSH_BACK(s->active_list_1,co);
		}else if(co->status == CORO_DIE)
		{
			coro_destroy(&co);
			if(--s->coro_size == 0)
				s->stop = 1;
			//printf("a coro destroy\n");
		}	
	}
	s->next_check_timeout = now + 200;//check every 200 ms
}
Beispiel #3
0
static inline coro_t _sche_next(sche_t s,coro_t co)
{

	coro_t next = NULL;
	coro_t coro_goback = co->_goback;
	if(NULL == coro_goback)
	{
		next = LINK_LIST_POP(coro_t,s->active_list_1);
		if(!next)
			next = LINK_LIST_POP(coro_t,s->active_list_2);
		if(!next)	
			next = s->co;
	}
	else
	{
		next = coro_goback;
		co->_goback = NULL;
	}
	
	if(co->status == CORO_YIELD)
	{
		co->status = CORO_ACTIVE;
		LINK_LIST_PUSH_BACK(s->active_list_2,co);
	}
	assert(co != next);
	set_current_coro(next);
	return (coro_t)uthread_switch(co->ut,next->ut,co);
}
Beispiel #4
0
void connection_push_packet(struct connection *c,wpacket_t w,packet_send_finish callback)
{
	if(w)
	{
		w->_packet_send_finish = callback;
		LINK_LIST_PUSH_BACK(c->send_list,w);
	}
}
Beispiel #5
0
void* coro_fun(void *arg)
{
	//printf("a coro start\n");
	coro_t co = (coro_t)arg;
	LINK_LIST_PUSH_BACK(co->_sche->active_list_2,co);
	co->status = CORO_ACTIVE;
	uthread_switch(co->ut,co->_sche->co->ut,co);
	void *ret = co->fun(co->arg);
	co->status = CORO_DIE;
	uthread_switch(co->ut,co->_sche->co->ut,co);
	return NULL;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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)
		* 文件超过一定大小,将原文件重命名,开一个新的文件
		*/
	}
}
Beispiel #8
0
int32_t epoll_loop(engine_t n,int32_t timeout)
{

	assert(n);	
	uint32_t ms;
	uint32_t tick = GetSystemMs();
	uint32_t _timeout = tick + timeout;
	do{
		while(!LINK_LIST_IS_EMPTY(n->actived))
		{
			socket_t s = LINK_LIST_POP(socket_t,n->actived);
			s->isactived = 0;
			if(Process(s) && s->isactived == 0)
			{
				s->isactived = 1;
				LINK_LIST_PUSH_BACK(n->actived,s);
			}
		}		
		ms = _timeout - tick;
		int32_t nfds = TEMP_FAILURE_RETRY(epoll_wait(n->poller_fd,n->events,MAX_SOCKET,ms));
		if(nfds < 0)
			return -1;
		int32_t i;
		for(i = 0 ; i < nfds ; ++i)
		{	
			socket_t sock = (socket_t)n->events[i].data.ptr;
			if(sock)
			{
				//套接口可读
				if(n->events[i].events & EPOLLIN)
				{	
					on_read_active(sock);
				}
				//套接口可写
				if(n->events[i].events & EPOLLOUT)
					on_write_active(sock);	
			
				if(n->events[i].events & EPOLLERR)
				{
					//套接口异常
				}
			}
		}	
		tick = GetSystemMs();
	}while(tick < _timeout);
	return 0;
}
Beispiel #9
0
int32_t connector_connect(connector_t c,const char *ip,uint32_t port,on_connect call_back,void *ud,uint32_t ms)
{
	struct sockaddr_in remote;
	HANDLE sock;
	struct pending_connect *pc;	
	sock = OpenSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(sock < 0)
		return -1;
	
	remote.sin_family = AF_INET;
	remote.sin_port = htons(port);
	if(inet_pton(INET,ip,&remote.sin_addr) < 0)
	{

		printf("%s\n",strerror(errno));
		return -1;
	}
	if(ms>0)
	{
		if(setNonblock(sock)!=0)
			return -1;
	}
	if(Connect(sock, (struct sockaddr *)&remote, sizeof(remote)) == 0)
	{
		//连接成功,无需要后续处理了,直接调用回调函数
		call_back(sock,ip,port,ud);
		return 0;
	}
	
	socket_t s = GetSocketByHandle(sock);

	pc = malloc(sizeof(*pc));
	pc->lnode.next = NULL;
	pc->sock = sock;
	pc->ip = ip;
	pc->port = port;
	pc->call_back = call_back;
	pc->timeout = GetSystemMs() + ms;
	pc->ud = ud;
	pc->real_fd = s->fd;
	mutex_lock(c->lock);
	LINK_LIST_PUSH_BACK(c->extern_pending_connect,pc);
	mutex_unlock(c->lock);
	return 0;
}
Beispiel #10
0
int32_t log_write(log_t l,const char *content,int32_t level)
{
	if(g_log_system->is_close)
		return -1;
		
	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]%s\n",_tm->tm_year+1900,_tm->tm_mon+1,_tm->tm_mday,_tm->tm_hour,_tm->tm_min,_tm->tm_sec,content);
	//snprintf(buf,4096,"%s\n",content);
	int32_t str_len = strlen(buf);
	wpacket_t w = wpacket_create(0,NULL,str_len,1);
	wpacket_write_binary(w,buf,str_len);
	mutex_lock(l->mtx);
	LINK_LIST_PUSH_BACK(l->log_queue,w);
	mutex_unlock(l->mtx);
	return 0;
}
Beispiel #11
0
int32_t connection_send(struct connection *c,wpacket_t w,packet_send_finish callback)
{

	int32_t bytestransfer = 0;
	uint32_t err_code = 0;
	st_io *O;
	int32_t ret = 1;
	if(w)
	{
		w->_packet_send_finish = callback;
		LINK_LIST_PUSH_BACK(c->send_list,w);
	}
	if(!c->send_overlap.isUsed)
	{
		c->send_overlap.isUsed = 1;
		O = prepare_send(c);	
		return WSASend(c->socket,O,0,&err_code);
	}
}
Beispiel #12
0
int32_t connection_send(struct connection *c,wpacket_t w,packet_send_finish callback)
{
	st_io *O;
	if(w)
	{
		w->send_tick = GetCurrentMs();
		w->_packet_send_finish = callback;
		LINK_LIST_PUSH_BACK(c->send_list,w);
	}
	if(!c->send_overlap.isUsed)
	{
		O = prepare_send(c);
		if(O)
		{
			c->send_overlap.isUsed = 1;	
			return Post_Send(c->socket,O);
		}
	}
	return 0;
}
Beispiel #13
0
/*
*  next选择方案,如果有goback优先选择goback作为下一个被运行的coro,
*  否则取active_list_1首元素作为下一个被运行的coro,如果active_list_1
*  为空则直接返回.
*/
coro_t _sche_next_1(sche_t s,coro_t co)
{

	coro_t next = NULL;
	coro_t coro_goback = co->_goback;
	if(NULL == coro_goback)
	{	
		coro_t next = LINK_LIST_POP(coro_t,s->active_list_1);
		if(!next)
			return NULL;
	}
	else
	{
		next = coro_goback;
		co->_goback = NULL;
	}
	LINK_LIST_PUSH_BACK(s->active_list_2,co);
	assert(co != next);	
	set_current_coro(next);
	return (coro_t)uthread_switch(co->ut,next->ut,co);	
}
Beispiel #14
0
log_t create_log(const char *path)
{
   log_t l = calloc(1,sizeof(*l));
   
   l->file_descriptor = open(path,O_RDWR|O_CREAT,S_IWUSR|S_IRUSR);
   if(l->file_descriptor < 0)
   {
	   free(l);
	   l = 0;
   }
   else
   {
		l->file_size = 0;
		l->mtx = mutex_create();
		l->log_queue = create_link_list();
		l->pending_log = create_link_list();
		//add to log system
		mutex_lock(g_log_system->mtx);
		LINK_LIST_PUSH_BACK(g_log_system->log_files,l);
		mutex_unlock(g_log_system->mtx);
		log_write(l,"open log file",1);
   }
   return l;			
}
Beispiel #15
0
void rem_listener(acceptor_t a,SOCK l)
{
	if(a)
	{
		struct epoll_event ev;int32_t ret;
		TEMP_FAILURE_RETRY(ret = epoll_ctl(a->poller_fd,EPOLL_CTL_DEL,GetSocketByHandle(l)->fd,&ev));
		if(ret == 0)
		{
			int32_t count = link_list_size(a->st_listens);
			while(count>0)
			{
				struct st_listen *_st = LINK_LIST_POP(struct st_listen *,a->st_listens);
				if(_st->sock == l)
				{
					ReleaseSocket(l);
					free(_st);
					break;
				}
				else
					LINK_LIST_PUSH_BACK(a->st_listens,_st);
				--count;
			};
		}
	}
Beispiel #16
0
SOCK    add_listener(acceptor_t a,const char *ip,uint32_t port,on_accept call_back,void *ud)
{
	if(!a)
		return INVALID_SOCK;
	SOCK ListenSocket;
	struct sockaddr_in servaddr;
	ListenSocket = Tcp_Listen(ip,port,&servaddr,256);
	if(ListenSocket != INVALID_SOCK)
	{
		struct st_listen *_st = (struct st_listen *)calloc(1,sizeof(*_st));
		_st->accept_callback = call_back;
		_st->ud = ud;
		_st->sock = ListenSocket;
		_st->real_fd = GetSocketByHandle(ListenSocket)->fd;
		
		int32_t ret = -1;	
		struct epoll_event ev;	
		ev.data.ptr = _st;
		ev.events = EV_IN;
		TEMP_FAILURE_RETRY(ret = epoll_ctl(a->poller_fd,EPOLL_CTL_ADD,_st->real_fd,&ev));
		if(ret == -1)
		{
			ReleaseSocket(ListenSocket);
			printf("listen %s:%d error\n",ip,port);
			return INVALID_SOCK;
		}
		LINK_LIST_PUSH_BACK(a->st_listens,_st);
		return ListenSocket;
	}
	else
	{
		ReleaseSocket(ListenSocket);
		printf("listen %s:%d error\n",ip,port);
		return INVALID_SOCK;
	}	
}
Beispiel #17
0
void coro_wakeup(coro_t co)
{
	if(co->status == CORO_BLOCK)
		LINK_LIST_PUSH_BACK(co->_sche->active_list_1,co);
}
Beispiel #18
0
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);
}