Added select() backend which can be used as a fallback if epoll is not available.
This commit is contained in:
parent
7e60919596
commit
2f09fcea84
16
GNUmakefile
16
GNUmakefile
@ -9,7 +9,6 @@ MV := mv
|
||||
RANLIB := ranlib
|
||||
CFLAGS += -pipe -Wall
|
||||
USE_SSL ?= NO
|
||||
USE_LIBEVENT ?= NO
|
||||
USE_BIGENDIAN ?= AUTO
|
||||
BITS ?= AUTO
|
||||
SILENT ?= YES
|
||||
@ -63,9 +62,6 @@ else
|
||||
MSG_CLEAN="Clean as a whistle"
|
||||
endif
|
||||
|
||||
# CFLAGS += -I/source/libevent
|
||||
# LDFLAGS += -L/source/libevent
|
||||
|
||||
ifeq ($(RELEASE),YES)
|
||||
CFLAGS += -O3 -DNDEBUG
|
||||
GIT_REVISION ?= NO
|
||||
@ -116,15 +112,6 @@ CFLAGS += -DSSL_SUPPORT
|
||||
LDLIBS += -lssl
|
||||
endif
|
||||
|
||||
ifeq ($(USE_LIBEVENT),YES)
|
||||
CFLAGS += -DUSE_LIBEVENT
|
||||
LDLIBS += -levent
|
||||
ifneq ($(LIBEVENT_PATH),)
|
||||
CFLAGS += -I$(LIBEVENT_PATH)
|
||||
LDFLAGS += -L$(LIBEVENT_PATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(GIT_REVISION),YES)
|
||||
CFLAGS += -DGIT_REVISION=\"$(shell git show --abbrev-commit | head -n 1 | cut -f 2 -d " ")\"
|
||||
endif
|
||||
@ -146,8 +133,9 @@ libuhub_SOURCES := \
|
||||
src/core/usermanager.c \
|
||||
src/network/connection.c \
|
||||
src/network/epoll.c \
|
||||
src/network/libevent.c \
|
||||
src/network/network.c \
|
||||
src/network/select.c \
|
||||
src/network/timer.c \
|
||||
src/util/ipcalc.c \
|
||||
src/util/list.c \
|
||||
src/util/log.c \
|
||||
|
@ -622,9 +622,6 @@ void hub_shutdown_service(struct hub_info* hub)
|
||||
LOG_DEBUG("hub_shutdown_service()");
|
||||
|
||||
event_queue_shutdown(hub->queue);
|
||||
#ifdef USE_LIBEVENT
|
||||
event_del(&hub->ev_accept);
|
||||
#endif
|
||||
net_con_close(hub->server);
|
||||
hub_free(hub->server);
|
||||
uman_shutdown(hub);
|
||||
|
@ -91,10 +91,6 @@ struct hub_logout_info
|
||||
struct hub_info
|
||||
{
|
||||
struct net_connection* server;
|
||||
#ifdef USE_LIBEVENT
|
||||
struct event ev_accept;
|
||||
struct event ev_timer;
|
||||
#endif
|
||||
struct hub_stats stats;
|
||||
struct event_queue* queue;
|
||||
struct hub_config* config;
|
||||
|
@ -70,28 +70,9 @@ void uman_print_stats(struct hub_info* hub)
|
||||
(int) hub->stats.net_rx_peak / 1024);
|
||||
}
|
||||
|
||||
#ifdef USERMANAGER_TIMER
|
||||
#ifdef USE_LIBEVENT
|
||||
static void timer_statistics(int fd, short ev, void *arg)
|
||||
{
|
||||
struct hub_info* hub = (struct hub_info*) arg;
|
||||
struct timeval timeout = { TIMEOUT_STATS, 0 };
|
||||
uman_update_stats(hub);
|
||||
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
||||
evtimer_add(&hub->ev_timer, &timeout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
int uman_init(struct hub_info* hub)
|
||||
{
|
||||
struct hub_user_manager* users = NULL;
|
||||
#ifdef USERMANAGER_TIMER
|
||||
#ifdef USE_LIBEVENT
|
||||
struct timeval timeout = { TIMEOUT_STATS, 0 };
|
||||
#endif
|
||||
#endif
|
||||
if (!hub)
|
||||
return -1;
|
||||
|
||||
@ -110,16 +91,6 @@ int uman_init(struct hub_info* hub)
|
||||
}
|
||||
|
||||
hub->users = users;
|
||||
|
||||
#ifdef USERMANAGER_TIMER
|
||||
#ifdef USE_LIBEVENT
|
||||
if (net_get_evbase())
|
||||
{
|
||||
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
||||
evtimer_add(&hub->ev_timer, &timeout);
|
||||
}
|
||||
#endif
|
||||
#endif // 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -129,13 +100,6 @@ int uman_shutdown(struct hub_info* hub)
|
||||
if (!hub || !hub->users)
|
||||
return -1;
|
||||
|
||||
#ifdef USERMANAGER_TIMER
|
||||
#ifdef USE_LIBEVENT
|
||||
if (evtimer_pending(&hub->ev_timer, 0))
|
||||
evtimer_del(&hub->ev_timer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (hub->users->list)
|
||||
{
|
||||
list_clear(hub->users->list, &clear_user_list_callback);
|
||||
@ -144,7 +108,6 @@ int uman_shutdown(struct hub_info* hub)
|
||||
sid_pool_destroy(hub->users->sids);
|
||||
hub_free(hub->users);
|
||||
hub->users = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,4 +36,6 @@ extern void net_backend_shutdown();
|
||||
*/
|
||||
extern int net_backend_process();
|
||||
|
||||
extern struct timeout_queue* net_backend_get_timeout_queue();
|
||||
|
||||
#endif /* HAVE_UHUB_NETWORK_BACKEND_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#define NET_WANT_READ NET_EVENT_READ
|
||||
#define NET_WANT_WRITE NET_EVENT_WRITE
|
||||
#define NET_WANT_ACCEPT 0x0008
|
||||
#define NET_WANT_ACCEPT NET_EVENT_READ
|
||||
#define NET_WANT_SSL_READ 0x0010
|
||||
#define NET_WANT_SSL_WRITE 0x0020
|
||||
#define NET_WANT_SSL_ACCEPT 0x0040
|
||||
@ -13,14 +13,12 @@
|
||||
#define NET_INITIALIZED 0x2000
|
||||
#define NET_TIMER_ENABLED 0x1000
|
||||
|
||||
/* FIXME: Meant for debugging */
|
||||
#define NET_EVENT_SET 0x0800
|
||||
|
||||
#define NET_CON_STRUCT_BASIC \
|
||||
int sd; /** socket descriptor */ \
|
||||
uint32_t flags; /** Connection flags */ \
|
||||
void* ptr; /** data pointer */ \
|
||||
net_connection_cb callback; /** Callback function */ \
|
||||
struct timeout_evt* timeout; /** timeout event handler */
|
||||
|
||||
#define NET_CON_STRUCT_SSL \
|
||||
SSL* ssl; /** SSL handle */ \
|
||||
|
@ -25,7 +25,7 @@ static int handle_openssl_error(struct net_connection* con, int ret)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
int error = SSL_get_error(net_con_get_ssl(con), ret);
|
||||
int error = SSL_get_error(con->ssl, ret);
|
||||
switch (error)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
@ -77,7 +77,7 @@ ssize_t net_con_ssl_accept(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
ssize_t ret = SSL_accept(net_con_get_ssl(con));
|
||||
ssize_t ret = SSL_accept(con->ssl);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("SSL_accept() ret=%d", ret);
|
||||
#endif
|
||||
@ -96,7 +96,7 @@ ssize_t net_con_ssl_connect(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
ssize_t ret = SSL_connect(net_con_get_ssl(con));
|
||||
ssize_t ret = SSL_connect(con->ssl);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("SSL_connect() ret=%d", ret);
|
||||
#endif
|
||||
@ -119,14 +119,14 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
|
||||
if (ssl_mode == net_con_ssl_mode_server)
|
||||
{
|
||||
ssl = SSL_new(ssl_ctx);
|
||||
SSL_set_fd(ssl, net_con_get_sd(con));
|
||||
SSL_set_fd(ssl, con->sd);
|
||||
net_con_set_ssl(con, ssl);
|
||||
return net_con_ssl_accept(con);
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl = SSL_new(SSL_CTX_new(TLSv1_method()));
|
||||
SSL_set_fd(ssl, net_con_get_sd(con));
|
||||
SSL_set_fd(ssl, con->sd);
|
||||
net_con_set_ssl(con, ssl);
|
||||
return net_con_ssl_connect(con);
|
||||
}
|
||||
@ -136,7 +136,7 @@ ssize_t net_con_ssl_handshake(struct net_connection* con, enum net_con_ssl_mode
|
||||
|
||||
ssize_t net_con_send(struct net_connection* con, const void* buf, size_t len)
|
||||
{
|
||||
int ret = net_send(net_con_get_sd(con), buf, len, UHUB_SEND_SIGNAL);
|
||||
int ret = net_send(con->sd, buf, len, UHUB_SEND_SIGNAL);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (net_error() == EWOULDBLOCK || net_error() == EINTR)
|
||||
@ -154,7 +154,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
if (!net_con_is_ssl(con))
|
||||
{
|
||||
#endif
|
||||
int ret = net_recv(net_con_get_sd(con), buf, len, 0);
|
||||
int ret = net_recv(con->sd, buf, len, 0);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("net_recv: ret=%d", ret);
|
||||
#endif
|
||||
@ -174,7 +174,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret = SSL_read(net_con_get_ssl(con), buf, len);
|
||||
int ret = SSL_read(con->ssl, buf, len);
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("net_recv: ret=%d", ret);
|
||||
#endif
|
||||
@ -193,7 +193,7 @@ ssize_t net_con_recv(struct net_connection* con, void* buf, size_t len)
|
||||
|
||||
ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
||||
{
|
||||
int ret = net_recv(net_con_get_sd(con), buf, len, MSG_PEEK);
|
||||
int ret = net_recv(con->sd, buf, len, MSG_PEEK);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (net_error() == EWOULDBLOCK || net_error() == EINTR)
|
||||
@ -205,6 +205,39 @@ ssize_t net_con_peek(struct net_connection* con, void* buf, size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
int net_con_is_ssl(struct net_connection* con)
|
||||
{
|
||||
return con->ssl != 0;
|
||||
}
|
||||
|
||||
SSL* net_con_get_ssl(struct net_connection* con)
|
||||
{
|
||||
return con->ssl;
|
||||
}
|
||||
|
||||
void net_con_set_ssl(struct net_connection* con, SSL* ssl)
|
||||
{
|
||||
con->ssl = ssl;
|
||||
}
|
||||
#endif /* SSL_SUPPORT */
|
||||
|
||||
int net_con_get_sd(struct net_connection* con)
|
||||
{
|
||||
return con->sd;
|
||||
}
|
||||
|
||||
void* net_con_get_ptr(struct net_connection* con)
|
||||
{
|
||||
return con->ptr;
|
||||
}
|
||||
|
||||
void net_con_callback(struct net_connection* con, int events)
|
||||
{
|
||||
if (!(con->flags & NET_CLEANUP))
|
||||
{
|
||||
LOG_TRACE("net_con_callback(%p, %s%s%s)", con, (events & NET_EVENT_READ ? "R" : ""), (events & NET_EVENT_WRITE ? "W" : ""), events == NET_EVENT_TIMEOUT ? "TIMEOUT" : "");
|
||||
con->callback(con, events, con->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define HAVE_UHUB_NETWORK_CONNECTION_H
|
||||
|
||||
#include "uhub.h"
|
||||
#include "network/common.h"
|
||||
#include "network/backend.h"
|
||||
|
||||
#define NET_EVENT_TIMEOUT 0x0001
|
||||
@ -30,8 +31,14 @@
|
||||
#define NET_EVENT_CLOSED 0x2000 /* Socket closed */
|
||||
|
||||
struct net_connection;
|
||||
|
||||
typedef void (*net_connection_cb)(struct net_connection*, int event, void* ptr);
|
||||
|
||||
struct net_connection
|
||||
{
|
||||
NET_CON_STRUCT_COMMON
|
||||
};
|
||||
|
||||
extern int net_con_get_sd(struct net_connection* con);
|
||||
extern void* net_con_get_ptr(struct net_connection* con);
|
||||
|
||||
@ -40,6 +47,7 @@ extern void net_con_destroy(struct net_connection*);
|
||||
extern void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events);
|
||||
extern void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events);
|
||||
extern void net_con_update(struct net_connection* con, int events);
|
||||
extern void net_con_callback(struct net_connection* con, int events);
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
|
@ -27,18 +27,10 @@
|
||||
|
||||
#define EPOLL_EVBUFFER 512
|
||||
|
||||
struct net_connection
|
||||
struct net_connection_epoll
|
||||
{
|
||||
int sd;
|
||||
uint32_t flags;
|
||||
net_connection_cb callback;
|
||||
void* ptr;
|
||||
NET_CON_STRUCT_COMMON
|
||||
struct epoll_event ev;
|
||||
struct timeout_evt* timeout;
|
||||
#ifdef SSL_SUPPORT
|
||||
SSL* ssl;
|
||||
size_t write_len; /** Length of last SSL_write(), only used if flags is NET_WANT_SSL_READ. */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct net_backend
|
||||
@ -46,7 +38,7 @@ struct net_backend
|
||||
int epfd;
|
||||
size_t num;
|
||||
size_t max;
|
||||
struct net_connection** conns;
|
||||
struct net_connection_epoll** conns;
|
||||
struct epoll_event events[EPOLL_EVBUFFER];
|
||||
time_t now;
|
||||
struct timeout_queue timeout_queue;
|
||||
@ -54,7 +46,7 @@ struct net_backend
|
||||
|
||||
static struct net_backend* g_backend = 0;
|
||||
|
||||
static void net_con_print(const char* prefix, struct net_connection* con)
|
||||
static void net_con_print(const char* prefix, struct net_connection_epoll* 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 }",
|
||||
@ -87,7 +79,7 @@ int net_backend_initialize()
|
||||
|
||||
g_backend->num = 0;
|
||||
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_epoll*) * max);
|
||||
memset(g_backend->events, 0, sizeof(g_backend->events));
|
||||
|
||||
g_backend->now = time(0);
|
||||
@ -121,19 +113,23 @@ int net_backend_process()
|
||||
|
||||
for (n = 0; n < res; n++)
|
||||
{
|
||||
struct net_connection* con = (struct net_connection*) g_backend->events[n].data.ptr;
|
||||
struct net_connection_epoll* con = (struct net_connection_epoll*) g_backend->events[n].data.ptr;
|
||||
int ev = 0;
|
||||
if (g_backend->events[n].events & EPOLLIN) ev |= NET_EVENT_READ;
|
||||
if (g_backend->events[n].events & EPOLLOUT) ev |= NET_EVENT_WRITE;
|
||||
con->callback(con, ev, con->ptr);
|
||||
net_con_callback((struct net_connection*) con, ev);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct timeout_queue* net_backend_get_timeout_queue()
|
||||
{
|
||||
return &g_backend->timeout_queue;
|
||||
}
|
||||
|
||||
struct net_connection* net_con_create()
|
||||
{
|
||||
struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection));
|
||||
struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection_epoll));
|
||||
con->sd = -1;
|
||||
return con;
|
||||
}
|
||||
@ -143,8 +139,9 @@ void net_con_destroy(struct net_connection* con)
|
||||
hub_free(con);
|
||||
}
|
||||
|
||||
void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int events)
|
||||
void net_con_initialize(struct net_connection* con_, int sd, net_connection_cb callback, const void* ptr, int events)
|
||||
{
|
||||
struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
|
||||
con->sd = sd;
|
||||
con->flags = NET_INITIALIZED;
|
||||
con->callback = callback;
|
||||
@ -176,8 +173,9 @@ void net_con_reinitialize(struct net_connection* con, net_connection_cb callback
|
||||
net_con_update(con, events);
|
||||
}
|
||||
|
||||
void net_con_update(struct net_connection* con, int events)
|
||||
void net_con_update(struct net_connection* con_, int events)
|
||||
{
|
||||
struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
|
||||
con->ev.events = 0;
|
||||
if (events & NET_EVENT_READ) con->ev.events |= EPOLLIN;
|
||||
if (events & NET_EVENT_WRITE) con->ev.events |= EPOLLOUT;
|
||||
@ -211,8 +209,9 @@ void net_con_update(struct net_connection* con, int events)
|
||||
net_con_print("MOD", con);
|
||||
}
|
||||
|
||||
int net_con_close(struct net_connection* con)
|
||||
int net_con_close(struct net_connection* con_)
|
||||
{
|
||||
struct net_connection_epoll* con = (struct net_connection_epoll*) con_;
|
||||
if (!(con->flags & NET_INITIALIZED))
|
||||
return 0;
|
||||
|
||||
@ -239,68 +238,4 @@ int net_con_close(struct net_connection* con)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
int net_con_is_ssl(struct net_connection* con)
|
||||
{
|
||||
|
||||
return con->ssl != 0;
|
||||
}
|
||||
|
||||
SSL* net_con_get_ssl(struct net_connection* con)
|
||||
{
|
||||
return con->ssl;
|
||||
}
|
||||
|
||||
void net_con_set_ssl(struct net_connection* con, SSL* ssl)
|
||||
{
|
||||
con->ssl = ssl;
|
||||
}
|
||||
#endif
|
||||
|
||||
int net_con_get_sd(struct net_connection* con)
|
||||
{
|
||||
return con->sd;
|
||||
}
|
||||
|
||||
void* net_con_get_ptr(struct net_connection* con)
|
||||
{
|
||||
return con->ptr;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
if (!con->timeout)
|
||||
{
|
||||
con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void net_con_clear_timeout(struct net_connection* con)
|
||||
{
|
||||
if (con->timeout && timeout_evt_is_scheduled(con->timeout))
|
||||
{
|
||||
timeout_queue_remove(&g_backend->timeout_queue, con->timeout);
|
||||
hub_free(con->timeout);
|
||||
con->timeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_EPOLL */
|
||||
|
@ -1,399 +0,0 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2009, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef USE_LIBEVENT
|
||||
|
||||
struct net_connection
|
||||
{
|
||||
NET_CON_STRUCT_COMMON
|
||||
struct event event; /** libevent struct for read/write events */
|
||||
struct event timeout; /** Used for internal timeout handling */
|
||||
};
|
||||
|
||||
struct net_timer
|
||||
{
|
||||
unsigned int initialized;
|
||||
struct event timeout;
|
||||
net_timeout_cb callback;
|
||||
void* ptr;
|
||||
};
|
||||
|
||||
int net_con_get_sd(struct net_connection* con)
|
||||
{
|
||||
return con->sd;
|
||||
}
|
||||
|
||||
void* net_con_get_ptr(struct net_connection* con)
|
||||
{
|
||||
return con->ptr;
|
||||
}
|
||||
|
||||
struct net_connection* net_con_create()
|
||||
{
|
||||
struct net_connection* con = (struct net_connection*) hub_malloc(sizeof(struct net_connection));
|
||||
return con;
|
||||
}
|
||||
|
||||
static inline int net_con_flag_get(struct net_connection* con, unsigned int flag)
|
||||
{
|
||||
return con->flags & flag;
|
||||
}
|
||||
|
||||
static inline void net_con_flag_set(struct net_connection* con, unsigned int flag)
|
||||
{
|
||||
con->flags |= flag;
|
||||
}
|
||||
|
||||
static inline void net_con_flag_unset(struct net_connection* con, unsigned int flag)
|
||||
{
|
||||
con->flags &= ~flag;
|
||||
}
|
||||
|
||||
void net_con_destroy(struct net_connection* con)
|
||||
{
|
||||
hub_free(con);
|
||||
}
|
||||
|
||||
static inline int net_con_convert_to_libevent_mask(int ev)
|
||||
{
|
||||
int events = 0;
|
||||
if (ev & NET_EVENT_READ) events |= EV_READ;
|
||||
if (ev & NET_EVENT_WRITE) events |= EV_WRITE;
|
||||
return events;
|
||||
}
|
||||
|
||||
static inline int net_con_convert_from_libevent_mask(int ev)
|
||||
{
|
||||
int events = 0;
|
||||
if (ev & EV_TIMEOUT) events |= NET_EVENT_TIMEOUT;
|
||||
if (ev & EV_READ) events |= NET_EVENT_READ;
|
||||
if (ev & EV_WRITE) events |= NET_EVENT_WRITE;
|
||||
return events;
|
||||
}
|
||||
|
||||
static void net_con_event(int fd, short ev, void *arg);
|
||||
|
||||
|
||||
int net_con_close(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
con->ptr = 0;
|
||||
|
||||
if (net_con_flag_get(con, NET_CLEANUP))
|
||||
return 0;
|
||||
|
||||
if (net_con_flag_get(con, NET_PROCESSING_BUSY))
|
||||
{
|
||||
net_con_flag_set(con, NET_CLEANUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
net_con_after_close(con);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void net_con_set(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
int ev = 0;
|
||||
if (net_con_flag_get(con, NET_WANT_READ | NET_WANT_SSL_READ)) ev |= EV_READ;
|
||||
if (net_con_flag_get(con, NET_WANT_WRITE | NET_WANT_SSL_WRITE)) ev |= EV_WRITE;
|
||||
|
||||
if (net_con_flag_get(con, NET_EVENT_SET) != 0)
|
||||
{
|
||||
event_del(&con->event);
|
||||
}
|
||||
net_con_flag_set(con, NET_EVENT_SET);
|
||||
|
||||
LOG_MEMORY("SET: set+add: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, ev);
|
||||
event_set(&con->event, con->sd, ev, net_con_event, con);
|
||||
event_add(&con->event, 0);
|
||||
|
||||
net_con_flag_set(con, NET_INITIALIZED);
|
||||
}
|
||||
|
||||
static void net_con_after_close(struct net_connection* con)
|
||||
{
|
||||
if (net_con_flag_get(con, NET_INITIALIZED))
|
||||
{
|
||||
LOG_MEMORY("DEL: close: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, -1);
|
||||
net_con_flag_unset(con, NET_EVENT_SET);
|
||||
|
||||
event_del(&con->event);
|
||||
net_con_flag_unset(con, NET_INITIALIZED);
|
||||
}
|
||||
|
||||
net_con_clear_timeout(con);
|
||||
net_close(con->sd);
|
||||
con->sd = -1;
|
||||
|
||||
hub_free(con);
|
||||
}
|
||||
|
||||
void net_con_initialize(struct net_connection* con, int sd, net_connection_cb callback, const void* ptr, int ev)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
int events = net_con_convert_to_libevent_mask(ev);
|
||||
if (ev & NET_EVENT_READ) net_con_flag_set(con, NET_WANT_READ);
|
||||
if (ev & NET_EVENT_WRITE) net_con_flag_set(con, NET_WANT_WRITE);
|
||||
|
||||
con->sd = sd;
|
||||
con->flags = 0;
|
||||
con->ptr = (void*) ptr;
|
||||
con->callback = callback;
|
||||
con->last_send = time(0);
|
||||
con->last_recv = con->last_send;
|
||||
|
||||
if (ev)
|
||||
{
|
||||
uhub_assert(net_con_flag_get(con, NET_EVENT_SET) == 0);
|
||||
net_con_flag_set(con, NET_EVENT_SET);
|
||||
|
||||
LOG_MEMORY("SET: init: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, ev);
|
||||
event_set(&con->event, con->sd, events, net_con_event, con);
|
||||
event_add(&con->event, 0);
|
||||
net_con_flag_set(con, NET_INITIALIZED);
|
||||
}
|
||||
|
||||
net_set_nonblocking(sd, 1);
|
||||
net_set_nosigpipe(sd, 1);
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
con->ssl = NULL;
|
||||
con->write_len = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
|
||||
{
|
||||
uhub_assert(con);
|
||||
con->callback = callback;
|
||||
con->ptr = (void*) ptr;
|
||||
net_con_update(con, events);
|
||||
}
|
||||
|
||||
void net_con_update(struct net_connection* con, int ev)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
if (ev & NET_EVENT_READ)
|
||||
net_con_flag_set(con, NET_EVENT_READ);
|
||||
else
|
||||
net_con_flag_unset(con, NET_EVENT_READ);
|
||||
|
||||
if (ev & NET_EVENT_WRITE)
|
||||
net_con_flag_set(con, NET_EVENT_WRITE);
|
||||
else
|
||||
net_con_flag_unset(con, NET_EVENT_WRITE);
|
||||
|
||||
if (!net_con_flag_get(con, NET_PROCESSING_BUSY))
|
||||
{
|
||||
net_con_set(con);
|
||||
}
|
||||
}
|
||||
|
||||
#define CALLBACK(CON, EVENTS) \
|
||||
if (CON->callback) \
|
||||
CON->callback(con, EVENTS, CON->ptr);
|
||||
|
||||
static void net_con_event(int fd, short ev, void *arg)
|
||||
{
|
||||
struct net_connection* con = (struct net_connection*) arg;
|
||||
int events = net_con_convert_from_libevent_mask(ev);
|
||||
|
||||
if (!net_con_flag_get(con, NET_INITIALIZED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (net_con_flag_get(con, NET_CLEANUP))
|
||||
{
|
||||
net_con_after_close(con);
|
||||
return;
|
||||
}
|
||||
|
||||
net_con_flag_set(con, NET_PROCESSING_BUSY);
|
||||
|
||||
// uhub_assert(net_con_flag_get(con, NET_EVENT_SET) != 0);
|
||||
net_con_flag_unset(con, NET_EVENT_SET);
|
||||
|
||||
LOG_MEMORY("EVT: process: CON={ %p, %p, %d, %d}", con, &con->event, con->sd, (int) ev);
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
if (!con->ssl)
|
||||
{
|
||||
#endif
|
||||
CALLBACK(con, events);
|
||||
#ifdef SSL_SUPPORT
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NETWORK_DUMP_DEBUG
|
||||
LOG_PROTO("net_con_event: events=%d, con=%p", ev, con);
|
||||
#endif
|
||||
if (ev & (EV_READ | EV_WRITE))
|
||||
{
|
||||
if (net_con_flag_get(con, NET_WANT_SSL_ACCEPT))
|
||||
{
|
||||
if (net_con_ssl_accept(con) < 0)
|
||||
CALLBACK(con, NET_EVENT_SOCKERROR);
|
||||
}
|
||||
else if (net_con_flag_get(con, NET_WANT_SSL_CONNECT))
|
||||
{
|
||||
if (net_con_ssl_connect(con) < 0)
|
||||
CALLBACK(con, NET_EVENT_SOCKERROR);
|
||||
}
|
||||
else if (ev == EV_READ && net_con_flag_get(con, NET_WANT_SSL_READ))
|
||||
{
|
||||
CALLBACK(con, NET_EVENT_WRITE);
|
||||
}
|
||||
else if (ev == EV_WRITE && net_con_flag_get(con, NET_WANT_SSL_WRITE))
|
||||
{
|
||||
CALLBACK(con, events & NET_EVENT_READ);
|
||||
}
|
||||
else
|
||||
{
|
||||
CALLBACK(con, events);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CALLBACK(con, events);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
net_con_flag_unset(con, NET_PROCESSING_BUSY);
|
||||
|
||||
if (net_con_flag_get(con, NET_CLEANUP))
|
||||
{
|
||||
net_con_after_close(con);
|
||||
}
|
||||
else
|
||||
{
|
||||
net_con_set(con);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void net_timer_event(int fd, short ev, void *arg)
|
||||
{
|
||||
struct net_timer* timer = (struct net_timer*) arg;
|
||||
timer->callback(timer, timer->ptr);
|
||||
}
|
||||
|
||||
void net_timer_initialize(struct net_timer* timer, net_timeout_cb callback, void* ptr)
|
||||
{
|
||||
timer->initialized = 0;
|
||||
timer->callback = callback;
|
||||
timer->ptr = ptr;
|
||||
}
|
||||
|
||||
void net_timer_reset(struct net_timer* timer, int seconds)
|
||||
{
|
||||
struct timeval timeout = { seconds, 0 };
|
||||
if (timer->initialized)
|
||||
{
|
||||
evtimer_del(&timer->timeout);
|
||||
timer->initialized = 0;
|
||||
}
|
||||
evtimer_set(&timer->timeout, net_timer_event, timer);
|
||||
evtimer_add(&timer->timeout, &timeout);
|
||||
}
|
||||
|
||||
void net_timer_shutdown(struct net_timer* timer)
|
||||
{
|
||||
if (timer->initialized)
|
||||
{
|
||||
evtimer_del(&timer->timeout);
|
||||
timer->initialized = 0;
|
||||
}
|
||||
timer->callback = 0;
|
||||
timer->ptr = 0;
|
||||
}
|
||||
|
||||
|
||||
void net_con_set_timeout(struct net_connection* con, int seconds)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
struct timeval timeout = { seconds, 0 };
|
||||
net_con_clear_timeout(con);
|
||||
|
||||
evtimer_set(&con->timeout, net_con_event, con);
|
||||
evtimer_add(&con->timeout, &timeout);
|
||||
net_con_flag_set(con, NET_TIMER_ENABLED);
|
||||
}
|
||||
|
||||
void net_con_clear_timeout(struct net_connection* con)
|
||||
{
|
||||
uhub_assert(con);
|
||||
|
||||
if (net_con_flag_get(con, NET_TIMER_ENABLED))
|
||||
{
|
||||
evtimer_del(&con->timeout);
|
||||
net_con_flag_unset(con, NET_TIMER_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
static struct event_base g_evbase = 0;
|
||||
|
||||
/**
|
||||
* Initialize the network backend.
|
||||
* Returns 1 on success, or 0 on failure.
|
||||
*/
|
||||
int net_backend_initialize()
|
||||
{
|
||||
g_evbase = event_init();
|
||||
if (!g_evbase)
|
||||
{
|
||||
LOG_ERROR("Unable to initialize libevent.");
|
||||
return 0;
|
||||
}
|
||||
LOG_DEBUG("Using libevent %s, backend: %s", event_get_version(), event_get_method());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the network connection backend.
|
||||
*/
|
||||
void net_backend_shutdown()
|
||||
{
|
||||
event_base_free(g_evbase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the network backend.
|
||||
*/
|
||||
int net_backend_process()
|
||||
{
|
||||
int ret = event_base_loop(g_evbase, EVLOOP_ONCE);
|
||||
if (ret != 0)
|
||||
{
|
||||
LOG_DEBUG("event_base_loop returned: %d", (int) ret);
|
||||
}
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_LIBEVENT */
|
208
src/network/select.c
Normal file
208
src/network/select.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
|
||||
#ifdef USE_SELECT
|
||||
|
||||
#include "network/connection.h"
|
||||
#include "network/common.h"
|
||||
#include "network/backend.h"
|
||||
|
||||
struct net_connection_select
|
||||
{
|
||||
NET_CON_STRUCT_COMMON
|
||||
};
|
||||
|
||||
struct net_backend
|
||||
{
|
||||
size_t num;
|
||||
size_t max;
|
||||
struct net_connection_select** conns;
|
||||
fd_set rfds;
|
||||
fd_set wfds;
|
||||
time_t now;
|
||||
struct timeout_queue timeout_queue;
|
||||
};
|
||||
|
||||
static struct net_backend* g_backend = 0;
|
||||
|
||||
static void net_con_print(const char* prefix, struct net_connection_select* con)
|
||||
{
|
||||
char buf[512];
|
||||
int off = snprintf(buf, 512, "%s: net_connection={ sd=%d, flags=%u, callback=%p, ptr=%p, events=%s%s",
|
||||
prefix, con->sd, con->flags, con->callback, con->ptr, (con->flags & NET_EVENT_READ ? "R" : ""),(con->flags & NET_EVENT_WRITE ? "W" : ""));
|
||||
if (con->timeout)
|
||||
{
|
||||
sprintf(buf + off, ", timeout={ %d seconds left }", (int) (con->timeout->timestamp - g_backend->now));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf + off, ", timeout=NULL");
|
||||
}
|
||||
LOG_TRACE(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the network backend.
|
||||
* Returns 1 on success, or 0 on failure.
|
||||
*/
|
||||
int net_backend_initialize()
|
||||
{
|
||||
size_t max = net_get_max_sockets();
|
||||
g_backend = hub_malloc(sizeof(struct net_backend));
|
||||
g_backend->num = 0;
|
||||
g_backend->max = max;
|
||||
g_backend->conns = hub_malloc_zero(sizeof(struct net_connection_select*) * max);
|
||||
FD_ZERO(&g_backend->rfds);
|
||||
FD_ZERO(&g_backend->wfds);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the network connection backend.
|
||||
*/
|
||||
void net_backend_shutdown()
|
||||
{
|
||||
hub_free(g_backend->conns);
|
||||
hub_free(g_backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the network backend.
|
||||
*/
|
||||
int net_backend_process()
|
||||
{
|
||||
int n, found, maxfd;
|
||||
struct timeval tval = { 1, 0 };
|
||||
FD_ZERO(&g_backend->rfds);
|
||||
FD_ZERO(&g_backend->wfds);
|
||||
for (n = 0, found = 0; found < g_backend->num && n < g_backend->max; n++)
|
||||
{
|
||||
struct net_connection_select* con = g_backend->conns[n];
|
||||
if (con)
|
||||
{
|
||||
if (con->flags & NET_EVENT_READ) FD_SET(con->sd, &g_backend->rfds);
|
||||
if (con->flags & NET_EVENT_WRITE) FD_SET(con->sd, &g_backend->wfds);
|
||||
found++;
|
||||
maxfd = con->sd;
|
||||
}
|
||||
}
|
||||
|
||||
int res = select(maxfd+1, &g_backend->rfds, &g_backend->wfds, 0, &tval);
|
||||
if (res == -1)
|
||||
{
|
||||
LOG_WARN("select returned -1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (n = 0, found = 0; found < res && n < (maxfd+1); n++)
|
||||
{
|
||||
struct net_connection_select* con = g_backend->conns[n];
|
||||
if (con)
|
||||
{
|
||||
int ev = 0;
|
||||
if (FD_ISSET(con->sd, &g_backend->rfds)) ev |= NET_EVENT_READ;
|
||||
if (FD_ISSET(con->sd, &g_backend->wfds)) ev |= NET_EVENT_WRITE;
|
||||
|
||||
if (ev)
|
||||
{
|
||||
net_con_callback((struct net_connection*) con, ev);
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct timeout_queue* net_backend_get_timeout_queue()
|
||||
{
|
||||
return &g_backend->timeout_queue;
|
||||
}
|
||||
|
||||
struct net_connection* net_con_create()
|
||||
{
|
||||
struct net_connection* con = (struct net_connection*) hub_malloc_zero(sizeof(struct net_connection_select));
|
||||
con->sd = -1;
|
||||
return con;
|
||||
}
|
||||
|
||||
void net_con_destroy(struct net_connection* con)
|
||||
{
|
||||
hub_free(con);
|
||||
}
|
||||
|
||||
void net_con_initialize(struct net_connection* con_, int sd, net_connection_cb callback, const void* ptr, int events)
|
||||
{
|
||||
struct net_connection_select* con = (struct net_connection_select*) con_;
|
||||
con->sd = sd;
|
||||
con->flags = NET_INITIALIZED;
|
||||
con->flags |= events;
|
||||
con->callback = callback;
|
||||
con->ptr = (void*) ptr;
|
||||
|
||||
net_set_nonblocking(con->sd, 1);
|
||||
net_set_nosigpipe(con->sd, 1);
|
||||
|
||||
g_backend->conns[sd] = con;
|
||||
g_backend->num++;
|
||||
net_con_print("ADD", con);
|
||||
}
|
||||
|
||||
void net_con_reinitialize(struct net_connection* con, net_connection_cb callback, const void* ptr, int events)
|
||||
{
|
||||
con->callback = callback;
|
||||
con->ptr = (void*) ptr;
|
||||
net_con_update(con, events);
|
||||
}
|
||||
|
||||
void net_con_update(struct net_connection* con, int events)
|
||||
{
|
||||
con->flags = NET_INITIALIZED;
|
||||
con->flags |= events;
|
||||
net_con_print("MOD", (struct net_connection_select*) con);
|
||||
}
|
||||
|
||||
int net_con_close(struct net_connection* con)
|
||||
{
|
||||
if (!(con->flags & NET_INITIALIZED))
|
||||
return 0;
|
||||
|
||||
con->flags &= ~NET_INITIALIZED;
|
||||
|
||||
if (con->sd != -1)
|
||||
{
|
||||
g_backend->conns[con->sd] = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
net_con_print("DEL", (struct net_connection_select*) con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_SELECT */
|
50
src/network/timer.c
Normal file
50
src/network/timer.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* uhub - A tiny ADC p2p connection hub
|
||||
* Copyright (C) 2007-2010, Jan Vidar Krey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "uhub.h"
|
||||
#include "network/connection.h"
|
||||
|
||||
static void timeout_callback(struct timeout_evt* evt)
|
||||
{
|
||||
net_con_callback((struct net_connection*) evt->ptr, NET_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
void net_con_set_timeout(struct net_connection* con, int seconds)
|
||||
{
|
||||
if (!con->timeout)
|
||||
{
|
||||
con->timeout = hub_malloc_zero(sizeof(struct timeout_evt));
|
||||
timeout_evt_initialize(con->timeout, timeout_callback, con);
|
||||
timeout_queue_insert(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout_queue_reschedule(net_backend_get_timeout_queue(), con->timeout, seconds);
|
||||
}
|
||||
}
|
||||
|
||||
void net_con_clear_timeout(struct net_connection* con)
|
||||
{
|
||||
if (timeout_evt_is_scheduled(con->timeout))
|
||||
{
|
||||
timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout);
|
||||
hub_free(con->timeout);
|
||||
con->timeout = 0;
|
||||
}
|
||||
}
|
@ -102,13 +102,12 @@
|
||||
|
||||
#define uhub_assert assert
|
||||
|
||||
#ifdef USE_LIBEVENT
|
||||
#include <event.h>
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#define USE_EPOLL
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
#else
|
||||
#define USE_SELECT
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun__)
|
||||
|
@ -330,7 +330,7 @@ void runloop(size_t clients)
|
||||
|
||||
while (running)
|
||||
{
|
||||
event_base_loop(net_get_evbase(), EVLOOP_ONCE);
|
||||
net_backend_process();
|
||||
}
|
||||
|
||||
for (n = 0; n < clients; n++)
|
||||
@ -413,63 +413,17 @@ void parse_command_line(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
static void handle_signal(int signal, short events, void* arg)
|
||||
{
|
||||
switch (signal)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
running = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct event signal_events[10];
|
||||
static int signals[] =
|
||||
{
|
||||
SIGINT, /* Interrupt the application */
|
||||
SIGTERM, /* Terminate the application */
|
||||
0
|
||||
};
|
||||
|
||||
void setup_signal_handlers()
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; signals[i]; i++)
|
||||
{
|
||||
signal_set(&signal_events[i], signals[i], handle_signal, NULL);
|
||||
signal_add(&signal_events[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown_signal_handlers()
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; signals[i]; i++)
|
||||
{
|
||||
signal_del(&signal_events[i]);
|
||||
}
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
parse_command_line(argc, argv);
|
||||
|
||||
net_initialize();
|
||||
setup_signal_handlers();
|
||||
|
||||
hub_log_initialize(NULL, 0);
|
||||
hub_set_log_verbosity(1000);
|
||||
|
||||
runloop(cfg_clients);
|
||||
|
||||
shutdown_signal_handlers();
|
||||
net_destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int running = 1;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
@ -79,7 +80,10 @@ int main(int argc, char** argv)
|
||||
ADC_client_set_callback(&client, handle);
|
||||
ADC_client_connect(&client, argv[1]);
|
||||
|
||||
event_dispatch();
|
||||
while (running)
|
||||
{
|
||||
net_backend_process();
|
||||
}
|
||||
|
||||
ADC_client_destroy(&client);
|
||||
net_destroy();
|
||||
|
@ -99,7 +99,7 @@ void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt)
|
||||
size_t pos = (evt->timestamp % t->max);
|
||||
struct timeout_evt* first = t->events[pos];
|
||||
|
||||
if (!first)
|
||||
if (!first || !evt)
|
||||
return;
|
||||
|
||||
if (first == evt)
|
||||
|
Loading…
Reference in New Issue
Block a user