Epoll fixes.
This commit is contained in:
		
							parent
							
								
									1c58a85de1
								
							
						
					
					
						commit
						314707f499
					
				
							
								
								
									
										17
									
								
								GNUmakefile
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								GNUmakefile
									
									
									
									
									
								
							| @ -139,21 +139,22 @@ libuhub_SOURCES := \ | |||||||
| 		src/core/hubevent.c \
 | 		src/core/hubevent.c \
 | ||||||
| 		src/core/hubio.c \
 | 		src/core/hubio.c \
 | ||||||
| 		src/core/inf.c \
 | 		src/core/inf.c \
 | ||||||
|  | 		src/core/netevent.c \
 | ||||||
| 		src/core/probe.c \
 | 		src/core/probe.c \
 | ||||||
|  | 		src/core/route.c \
 | ||||||
|  | 		src/core/user.c \
 | ||||||
|  | 		src/core/usermanager.c \
 | ||||||
| 		src/util/ipcalc.c \
 | 		src/util/ipcalc.c \
 | ||||||
|  | 		src/network/epoll.c \
 | ||||||
|  | 		src/network/libevent.c \
 | ||||||
|  | 		src/network/network.c \
 | ||||||
| 		src/util/list.c \
 | 		src/util/list.c \
 | ||||||
| 		src/util/log.c \
 | 		src/util/log.c \
 | ||||||
| 		src/util/memory.c \
 | 		src/util/memory.c \
 | ||||||
| 		src/util/misc.c \
 | 		src/util/misc.c \
 | ||||||
| 		src/util/timeout.c \
 |  | ||||||
| 		src/core/netevent.c \
 |  | ||||||
| 		src/network/connection.c \
 |  | ||||||
| 		src/network/network.c \
 |  | ||||||
| 		src/util/rbtree.c \
 | 		src/util/rbtree.c \
 | ||||||
| 		src/core/route.c \
 | 		src/util/timeout.c \
 | ||||||
| 		src/util/tiger.c \
 | 		src/util/tiger.c | ||||||
| 		src/core/user.c \
 |  | ||||||
| 		src/core/usermanager.c |  | ||||||
| 
 | 
 | ||||||
| libadc_common_SOURCES := \
 | libadc_common_SOURCES := \
 | ||||||
| 		src/adc/message.c \
 | 		src/adc/message.c \
 | ||||||
|  | |||||||
| @ -18,9 +18,6 @@ | |||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include "uhub.h" | #include "uhub.h" | ||||||
| #include "network/connection-common.c" | 
 | ||||||
| #include "network/connection-timeout.c" |  | ||||||
| #include "network/connection-libevent.c" |  | ||||||
| #include "network/connection-epoll.c" |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,8 +17,13 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include "uhub.h" | ||||||
|  | 
 | ||||||
| #ifdef USE_EPOLL | #ifdef USE_EPOLL | ||||||
| 
 | 
 | ||||||
|  | #include "network/connection.h" | ||||||
|  | #include "network/common.h" | ||||||
|  | 
 | ||||||
| #define EPOLL_EVBUFFER 512 | #define EPOLL_EVBUFFER 512 | ||||||
| 
 | 
 | ||||||
| struct net_connection | struct net_connection | ||||||
| @ -26,11 +31,27 @@ struct net_connection | |||||||
| 	int                  sd; | 	int                  sd; | ||||||
| 	uint32_t             flags; | 	uint32_t             flags; | ||||||
| 	net_connection_cb    callback; | 	net_connection_cb    callback; | ||||||
|  | 	void*                ptr; | ||||||
| 	struct epoll_event   ev; | 	struct epoll_event   ev; | ||||||
| 	struct timeout_evt*  timeout; | 	struct timeout_evt*  timeout; | ||||||
| 	void*                ptr; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static void net_con_print(const char* prefix, struct net_connection* con) | ||||||
|  | { | ||||||
|  | 	char buf[512]; | ||||||
|  | 	int off = snprintf(buf, 512, "%s: net_connection={ sd=%d, flags=%u, callback=%p, ptr=%p, ev={ events=%s%s, data.ptr=%p }", | ||||||
|  | 		prefix, con->sd, con->flags, con->callback, con->ptr, (con->ev.events & EPOLLIN ? "R" : ""),(con->ev.events & EPOLLOUT ? "W" : "") , con->ev.data.ptr); | ||||||
|  | 	if (con->timeout) | ||||||
|  | 	{ | ||||||
|  | 		sprintf(buf + off, ", timeout={ %d seconds left }", (int) (time(0) - con->timeout->timestamp)); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		sprintf(buf + off, ", timeout=NULL"); | ||||||
|  | 	} | ||||||
|  | 	LOG_WARN(buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct net_backend | struct net_backend | ||||||
| { | { | ||||||
| 	int epfd; | 	int epfd; | ||||||
| @ -38,6 +59,8 @@ struct net_backend | |||||||
| 	size_t max; | 	size_t max; | ||||||
| 	struct net_connection** conns; | 	struct net_connection** conns; | ||||||
| 	struct epoll_event events[EPOLL_EVBUFFER]; | 	struct epoll_event events[EPOLL_EVBUFFER]; | ||||||
|  | 	time_t now; | ||||||
|  | 	struct timeout_queue timeout_queue; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct net_backend* g_backend = 0; | static struct net_backend* g_backend = 0; | ||||||
| @ -61,7 +84,9 @@ int net_backend_initialize() | |||||||
| 	g_backend->max = max; | 	g_backend->max = max; | ||||||
| 	g_backend->conns = hub_malloc_zero(sizeof(struct net_connection*) * max); | 	g_backend->conns = hub_malloc_zero(sizeof(struct net_connection*) * max); | ||||||
| 	memset(g_backend->events, 0, sizeof(g_backend->events)); | 	memset(g_backend->events, 0, sizeof(g_backend->events)); | ||||||
| 	 | 
 | ||||||
|  | 	g_backend->now = time(0); | ||||||
|  | 	timeout_queue_initialize(&g_backend->timeout_queue, g_backend->now, 600); /* look max 10 minutes into the future. */ | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -81,24 +106,21 @@ void net_backend_shutdown() | |||||||
| int net_backend_process() | int net_backend_process() | ||||||
| { | { | ||||||
| 	int n; | 	int n; | ||||||
| 	int res = epoll_wait(g_backend->epfd, g_backend->events, EPOLL_EVBUFFER, 1000); | 	LOG_WARN("epoll_wait: fd=%d, events=%x, max=%zu", g_backend->epfd, g_backend->events, MIN(g_backend->num, EPOLL_EVBUFFER)); | ||||||
|  | 	int res = epoll_wait(g_backend->epfd, g_backend->events, MIN(g_backend->num, EPOLL_EVBUFFER), 1000); | ||||||
| 	if (res == -1) | 	if (res == -1) | ||||||
| 	{ | 	{ | ||||||
|  | 		LOG_WARN("epoll_wait returned -1"); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (n = 0; n < res; n++) | 	for (n = 0; n < res; n++) | ||||||
| 	{ | 	{ | ||||||
| 		struct net_connection* con = (struct net_connection*) g_backend->events[n].data.ptr; | 		struct net_connection* con = (struct net_connection*) g_backend->events[n].data.ptr; | ||||||
| 		if (con && con->callback) | 		int ev = 0; | ||||||
| 		{ | 		if (g_backend->events[n].events & EPOLLIN) ev |= NET_EVENT_READ; | ||||||
| 			con->callback(con, g_backend->events[n].events, con->ptr); | 		if (g_backend->events[n].events & EPOLLOUT) ev |= NET_EVENT_WRITE; | ||||||
| 		} | 		con->callback(con, ev, con->ptr); | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			LOG_WARN("Con == NULL"); |  | ||||||
| 		} |  | ||||||
| 		 |  | ||||||
| 	} | 	} | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| @ -120,9 +142,9 @@ void net_con_initialize(struct net_connection* con, int sd, net_connection_cb ca | |||||||
| 	con->sd = sd; | 	con->sd = sd; | ||||||
| 	con->flags = NET_INITIALIZED; | 	con->flags = NET_INITIALIZED; | ||||||
| 	con->callback = callback; | 	con->callback = callback; | ||||||
| 
 |  | ||||||
| 	con->ev.events = 0; | 	con->ev.events = 0; | ||||||
| 	con->ev.data.ptr = (void*) ptr; | 	con->ptr = (void*) ptr; | ||||||
|  | 	con->ev.data.ptr = (void*) con; | ||||||
| 
 | 
 | ||||||
| 	net_set_nonblocking(con->sd, 1); | 	net_set_nonblocking(con->sd, 1); | ||||||
| 	net_set_nosigpipe(con->sd, 1); | 	net_set_nosigpipe(con->sd, 1); | ||||||
| @ -137,12 +159,14 @@ void net_con_initialize(struct net_connection* con, int sd, net_connection_cb ca | |||||||
| 	{ | 	{ | ||||||
| 		LOG_WARN("epoll_ctl() add failed."); | 		LOG_WARN("epoll_ctl() add failed."); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	net_con_print("ADD", con); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events) | void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events) | ||||||
| { | { | ||||||
| 	con->callback = callback; | 	con->callback = callback; | ||||||
| 	con->ev.data.ptr = (void*) ptr; | 	con->ptr = (void*) ptr; | ||||||
| 	net_con_update(con, events); | 	net_con_update(con, events); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -156,6 +180,7 @@ void net_con_update(struct net_connection* con, int events) | |||||||
| 	{ | 	{ | ||||||
| 		LOG_WARN("epoll_ctl() modify failed."); | 		LOG_WARN("epoll_ctl() modify failed."); | ||||||
| 	} | 	} | ||||||
|  | 	net_con_print("MOD", con); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int net_con_close(struct net_connection* con) | int net_con_close(struct net_connection* con) | ||||||
| @ -171,10 +196,18 @@ int net_con_close(struct net_connection* con) | |||||||
| 		g_backend->num--; | 		g_backend->num--; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (timeout_evt_is_scheduled(con->timeout)) | ||||||
|  | 	{ | ||||||
|  | 		timeout_queue_remove(&g_backend->timeout_queue, con->timeout); | ||||||
|  | 		hub_free(con->timeout); | ||||||
|  | 		con->timeout = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (epoll_ctl(g_backend->epfd, EPOLL_CTL_DEL, con->sd, &con->ev) == -1) | 	if (epoll_ctl(g_backend->epfd, EPOLL_CTL_DEL, con->sd, &con->ev) == -1) | ||||||
| 	{ | 	{ | ||||||
| 		LOG_WARN("epoll_ctl() delete failed."); | 		LOG_WARN("epoll_ctl() delete failed."); | ||||||
| 	} | 	} | ||||||
|  | 	net_con_print("DEL", con); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -186,7 +219,7 @@ int net_con_get_sd(struct net_connection* con) | |||||||
| 
 | 
 | ||||||
| void* net_con_get_ptr(struct net_connection* con) | void* net_con_get_ptr(struct net_connection* con) | ||||||
| { | { | ||||||
| 	return con->ev.data.ptr; | 	return con->ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len) | ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len) | ||||||
| @ -254,13 +287,29 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len) | |||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | void timeout_evt_initialize(struct timeout_evt*, timeout_evt_cb, void* ptr); | ||||||
|  | void timeout_evt_reset(struct timeout_evt*); | ||||||
|  | int  timeout_evt_is_scheduled(struct timeout_evt*); | ||||||
|  | 
 | ||||||
|  | static void timeout_callback(struct timeout_evt* evt) | ||||||
|  | { | ||||||
|  | 	struct net_connection* con = (struct net_connection*) evt->ptr; | ||||||
|  | 	con->callback(con, NET_EVENT_TIMEOUT, con->ptr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| void net_con_set_timeout(struct net_connection* con, int seconds) | void net_con_set_timeout(struct net_connection* con, int seconds) | ||||||
| { | { | ||||||
| 	uhub_assert(con); |  | ||||||
| 	if (!con->timeout) | 	if (!con->timeout) | ||||||
| 	{ | 	{ | ||||||
| 		con->timeout = hub_malloc(sizeof(struct timeout_evt)); | 		con->timeout = hub_malloc_zero(sizeof(struct timeout_evt)); | ||||||
| 		timeout_evt_initialize(con->timeout, timeout_callback, con); | 		timeout_evt_initialize(con->timeout, timeout_callback, con); | ||||||
|  | 		timeout_queue_insert(&g_backend->timeout_queue, con->timeout, seconds); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		timeout_queue_reschedule(&g_backend->timeout_queue, con->timeout, seconds); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user