Fixes to shutdown...
This commit is contained in:
parent
fbe98d6011
commit
eca0f931bd
@ -28,10 +28,14 @@
|
||||
/* Send a broadcast message */
|
||||
#define UHUB_EVENT_BROADCAST 0x2000
|
||||
|
||||
/* Shutdown hub */
|
||||
#define UHUB_EVENT_HUB_SHUTDOWN 0x3001
|
||||
|
||||
/* Statistics, OOM, reconfigure */
|
||||
#define UHUB_EVENT_STATISTICS 0x4000
|
||||
#define UHUB_EVENT_OUT_OF_MEMORY 0x4001
|
||||
#define UHUB_EVENT_RECONFIGURE 0x4002
|
||||
|
||||
|
||||
#endif /* HAVE_UHUB_EVENT_ID_H */
|
||||
|
||||
|
103
src/core/hub.c
103
src/core/hub.c
@ -107,7 +107,6 @@ int hub_handle_support(struct hub_info* hub, struct hub_user* u, struct adc_mess
|
||||
|
||||
while (arg)
|
||||
{
|
||||
|
||||
if (strlen(arg) == 6)
|
||||
{
|
||||
fourcc_t fourcc = FOURCC(arg[2], arg[3], arg[4], arg[5]);
|
||||
@ -401,6 +400,19 @@ static void hub_event_dispatcher(void* callback_data, struct event_data* message
|
||||
break;
|
||||
}
|
||||
|
||||
case UHUB_EVENT_HUB_SHUTDOWN:
|
||||
{
|
||||
struct hub_user* u = (struct hub_user*) list_get_first(hub->users->list);
|
||||
while (u)
|
||||
{
|
||||
uman_remove(hub, u);
|
||||
user_destroy(u);
|
||||
u = (struct hub_user*) list_get_first(hub->users->list);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
/* FIXME: ignored */
|
||||
break;
|
||||
@ -448,25 +460,11 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
net_address_to_string(AF_INET6, &((struct sockaddr_in6*) &addr)->sin6_addr, address_buf, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
#ifdef LIBEVENT_1_4
|
||||
hub->evbase = event_base_new();
|
||||
#else
|
||||
hub->evbase = event_init();
|
||||
#endif
|
||||
if (!hub->evbase)
|
||||
{
|
||||
LOG_ERROR("Unable to initialize libevent.");
|
||||
hub_free(hub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_INFO("Starting " PRODUCT "/" VERSION ", listening on %s:%d...", address_buf, config->server_port);
|
||||
LOG_DEBUG("Using libevent %s, backend: %s", event_get_version(), event_get_method());
|
||||
|
||||
server_tcp = net_socket_create(af, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (server_tcp == -1)
|
||||
{
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub);
|
||||
return 0;
|
||||
}
|
||||
@ -474,7 +472,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
ret = net_set_reuseaddress(server_tcp, 1);
|
||||
if (ret == -1)
|
||||
{
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub);
|
||||
net_close(server_tcp);
|
||||
return 0;
|
||||
@ -483,7 +480,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
ret = net_set_nonblocking(server_tcp, 1);
|
||||
if (ret == -1)
|
||||
{
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub);
|
||||
net_close(server_tcp);
|
||||
return 0;
|
||||
@ -493,7 +489,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("hub_start_service(): Unable to bind to TCP local address. errno=%d, str=%s", net_error(), net_error_string(net_error()));
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub);
|
||||
net_close(server_tcp);
|
||||
return 0;
|
||||
@ -503,7 +498,6 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
if (ret == -1)
|
||||
{
|
||||
LOG_FATAL("hub_start_service(): Unable to listen to socket");
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub);
|
||||
net_close(server_tcp);
|
||||
return 0;
|
||||
@ -549,7 +543,7 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
}
|
||||
|
||||
event_set(&hub->ev_accept, hub->fd_tcp, EV_READ | EV_PERSIST, net_on_accept, hub);
|
||||
event_base_set(hub->evbase, &hub->ev_accept);
|
||||
event_base_set(net_get_evbase(), &hub->ev_accept);
|
||||
if (event_add(&hub->ev_accept, NULL) == -1)
|
||||
{
|
||||
uman_shutdown(hub);
|
||||
@ -601,14 +595,13 @@ struct hub_info* hub_start_service(struct hub_config* config)
|
||||
|
||||
void hub_shutdown_service(struct hub_info* hub)
|
||||
{
|
||||
LOG_TRACE("hub_shutdown_service()");
|
||||
LOG_DEBUG("hub_shutdown_service()");
|
||||
|
||||
event_queue_shutdown(hub->queue);
|
||||
event_del(&hub->ev_accept);
|
||||
net_close(hub->fd_tcp);
|
||||
uman_shutdown(hub);
|
||||
hub->status = hub_status_stopped;
|
||||
event_base_free(hub->evbase);
|
||||
hub_free(hub->sendbuf);
|
||||
hub_free(hub->recvbuf);
|
||||
hub_chat_history_clear(hub);
|
||||
@ -959,13 +952,51 @@ size_t hub_get_min_hubs_op(struct hub_info* hub)
|
||||
return hub->config->limit_min_hubs_op;
|
||||
}
|
||||
|
||||
void hub_schedule_destroy_user(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
struct event_data post;
|
||||
memset(&post, 0, sizeof(post));
|
||||
post.id = UHUB_EVENT_USER_DESTROY;
|
||||
post.ptr = user;
|
||||
event_queue_post(hub->queue, &post);
|
||||
|
||||
net_con_close(&user->net.connection);
|
||||
|
||||
if (user->id.sid)
|
||||
{
|
||||
sid_free(hub->users->sids, user->id.sid);
|
||||
}
|
||||
}
|
||||
|
||||
void hub_disconnect_all(struct hub_info* hub)
|
||||
{
|
||||
struct event_data post;
|
||||
memset(&post, 0, sizeof(post));
|
||||
post.id = UHUB_EVENT_HUB_SHUTDOWN;
|
||||
post.ptr = 0;
|
||||
event_queue_post(hub->queue, &post);
|
||||
}
|
||||
|
||||
|
||||
void hub_schedule_destroy_all(struct hub_info* hub)
|
||||
{
|
||||
struct hub_user* user = (struct hub_user*) list_get_first(hub->users->list);
|
||||
while (user)
|
||||
{
|
||||
|
||||
hub_schedule_destroy_user(hub, user);
|
||||
user = (struct hub_user*) list_get_next(hub->users->list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void hub_event_loop(struct hub_info* hub)
|
||||
{
|
||||
int ret;
|
||||
do
|
||||
{
|
||||
ret = event_base_loop(hub->evbase, EVLOOP_ONCE);
|
||||
ret = event_base_loop(net_get_evbase(), EVLOOP_ONCE);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
@ -978,21 +1009,19 @@ void hub_event_loop(struct hub_info* hub)
|
||||
event_queue_process(hub->queue);
|
||||
}
|
||||
while (hub->status == hub_status_running || hub->status == hub_status_disabled);
|
||||
|
||||
|
||||
if (hub->status == hub_status_shutdown)
|
||||
{
|
||||
LOG_DEBUG("Removing all users...");
|
||||
event_queue_process(hub->queue);
|
||||
event_queue_process(hub->queue);
|
||||
hub_disconnect_all(hub);
|
||||
event_queue_process(hub->queue);
|
||||
hub->status = hub_status_stopped;
|
||||
}
|
||||
}
|
||||
|
||||
void hub_schedule_destroy_user(struct hub_info* hub, struct hub_user* user)
|
||||
{
|
||||
struct event_data post;
|
||||
memset(&post, 0, sizeof(post));
|
||||
post.id = UHUB_EVENT_USER_DESTROY;
|
||||
post.ptr = user;
|
||||
event_queue_post(hub->queue, &post);
|
||||
|
||||
if (user->id.sid)
|
||||
{
|
||||
sid_free(hub->users->sids, user->id.sid);
|
||||
}
|
||||
}
|
||||
|
||||
void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason)
|
||||
{
|
||||
@ -1010,7 +1039,7 @@ void hub_disconnect_user(struct hub_info* hub, struct hub_user* user, int reason
|
||||
|
||||
LOG_TRACE("hub_disconnect_user(), user=%p, reason=%d, state=%d", user, reason, user->state);
|
||||
|
||||
need_notify = user_is_logged_in(user);
|
||||
need_notify = user_is_logged_in(user) && hub->status == hub_status_running;
|
||||
user->quit_reason = reason;
|
||||
user_set_state(user, state_cleanup);
|
||||
|
||||
|
@ -95,7 +95,6 @@ struct hub_info
|
||||
struct event ev_timer;
|
||||
struct hub_stats stats;
|
||||
struct event_queue* queue;
|
||||
struct event_base* evbase;
|
||||
struct hub_config* config;
|
||||
struct hub_user_manager* users;
|
||||
struct acl_handle* acl;
|
||||
|
@ -81,7 +81,7 @@ void setup_signal_handlers(struct hub_info* hub)
|
||||
for (i = 0; signals[i]; i++)
|
||||
{
|
||||
signal_set(&signal_events[i], signals[i], hub_handle_signal, hub);
|
||||
event_base_set(hub->evbase, &signal_events[i]);
|
||||
event_base_set(net_get_evbase(), &signal_events[i]);
|
||||
if (signal_add(&signal_events[i], NULL))
|
||||
{
|
||||
LOG_ERROR("Error setting signal handler %d", signals[i]);
|
||||
@ -147,7 +147,7 @@ int main_loop()
|
||||
acl_shutdown(&acl);
|
||||
free_config(&configuration);
|
||||
|
||||
} while(hub->status != hub_status_shutdown);
|
||||
} while (hub->status == hub_status_restart);
|
||||
|
||||
#ifndef WIN32
|
||||
shutdown_signal_handlers(hub);
|
||||
|
@ -62,9 +62,6 @@ void user_destroy(struct hub_user* user)
|
||||
{
|
||||
LOG_TRACE("user_destroy(), user=%p", user);
|
||||
|
||||
net_con_close(&user->net.connection);
|
||||
net_con_clear_timeout(&user->net.connection);
|
||||
|
||||
hub_recvq_destroy(user->net.recv_queue);
|
||||
hub_sendq_destroy(user->net.send_queue);
|
||||
|
||||
|
@ -77,7 +77,7 @@ static void timer_statistics(int fd, short ev, void *arg)
|
||||
struct timeval timeout = { TIMEOUT_STATS, 0 };
|
||||
uman_update_stats(hub);
|
||||
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
||||
event_base_set(hub->evbase, &hub->ev_timer);
|
||||
event_base_set(net_get_evbase(), &hub->ev_timer);
|
||||
evtimer_add(&hub->ev_timer, &timeout);
|
||||
}
|
||||
#endif
|
||||
@ -108,10 +108,10 @@ int uman_init(struct hub_info* hub)
|
||||
hub->users = users;
|
||||
|
||||
#ifdef USERMANAGER_TIMER
|
||||
if (hub->evbase)
|
||||
if (net_get_evbase())
|
||||
{
|
||||
evtimer_set(&hub->ev_timer, timer_statistics, hub);
|
||||
event_base_set(hub->evbase, &hub->ev_timer);
|
||||
event_base_set(net_get_evbase(), &hub->ev_timer);
|
||||
evtimer_add(&hub->ev_timer, &timeout);
|
||||
}
|
||||
#endif // 0
|
||||
@ -126,7 +126,7 @@ int uman_shutdown(struct hub_info* hub)
|
||||
|
||||
#ifdef USERMANAGER_TIMER
|
||||
if (evtimer_pending(&hub->ev_timer, 0))
|
||||
event_del(&hub->ev_timer);
|
||||
evtimer_del(&hub->ev_timer);
|
||||
#endif
|
||||
|
||||
if (hub->users->list)
|
||||
|
@ -27,7 +27,7 @@ struct hub_user_manager
|
||||
struct sid_pool* sids;
|
||||
uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */
|
||||
uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */
|
||||
struct linked_list* list; /**<< "Contains all users" */
|
||||
struct linked_list* list; /**<< "Contains all logged in users" */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -107,7 +107,7 @@ void net_con_initialize(struct net_connection* con, int sd, struct ip_addr_encap
|
||||
if (events & EV_WRITE) net_con_flag_set(con, NET_WANT_WRITE);
|
||||
|
||||
event_set(&con->event, con->sd, events | EV_PERSIST, net_con_event, con);
|
||||
event_base_set(g_hub->evbase, &con->event);
|
||||
event_base_set(net_get_evbase(), &con->event);
|
||||
event_add(&con->event, 0);
|
||||
|
||||
net_set_nonblocking(sd, 1);
|
||||
@ -134,9 +134,12 @@ void net_con_update(struct net_connection* con, int events)
|
||||
|
||||
void net_con_close(struct net_connection* con)
|
||||
{
|
||||
if (!event_pending(&con->event, EV_READ | EV_WRITE, 0))
|
||||
return;
|
||||
if (event_pending(&con->event, EV_READ | EV_WRITE, 0))
|
||||
{
|
||||
event_del(&con->event);
|
||||
}
|
||||
|
||||
net_con_clear_timeout(con);
|
||||
net_close(con->sd);
|
||||
con->sd = -1;
|
||||
}
|
||||
@ -291,7 +294,7 @@ void net_con_set_timeout(struct net_connection* con, int seconds)
|
||||
{
|
||||
struct timeval timeout = { seconds, 0 };
|
||||
evtimer_set(&con->timeout, net_con_event, con);
|
||||
event_base_set(g_hub->evbase, &con->timeout);
|
||||
event_base_set(net_get_evbase(), &con->timeout);
|
||||
evtimer_add(&con->timeout, &timeout);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
static int is_ipv6_supported = -1; /* -1 = CHECK, 0 = NO, 1 = YES */
|
||||
static int net_initialized = 0;
|
||||
static struct event_base* net_evbase = 0;
|
||||
static struct net_statistics stats;
|
||||
static struct net_statistics stats_total;
|
||||
|
||||
@ -35,6 +36,7 @@ int net_initialize()
|
||||
{
|
||||
if (!net_initialized)
|
||||
{
|
||||
LOG_TRACE("Initializing network monitor.");
|
||||
|
||||
#ifdef WINSOCK
|
||||
struct WSAData wsa;
|
||||
@ -45,7 +47,18 @@ int net_initialize()
|
||||
}
|
||||
#endif /* WINSOCK */
|
||||
|
||||
LOG_TRACE("Initializing network monitor.");
|
||||
#ifdef LIBEVENT_1_4
|
||||
net_evbase = event_base_new();
|
||||
#else
|
||||
net_evbase = event_init();
|
||||
#endif
|
||||
if (!net_evbase)
|
||||
{
|
||||
LOG_ERROR("Unable to initialize libevent.");
|
||||
return 0;
|
||||
}
|
||||
LOG_DEBUG("Using libevent %s, backend: %s", event_get_version(), event_get_method());
|
||||
|
||||
net_stats_initialize();
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
@ -83,6 +96,9 @@ int net_destroy()
|
||||
{
|
||||
LOG_TRACE("Shutting down network monitor");
|
||||
|
||||
event_base_free(net_evbase);
|
||||
net_evbase = 0;
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
/* FIXME: Shutdown OpenSSL here. */
|
||||
#endif
|
||||
@ -96,6 +112,11 @@ int net_destroy()
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct event_base* net_get_evbase()
|
||||
{
|
||||
return net_evbase;
|
||||
}
|
||||
|
||||
static void net_error_out(int fd, const char* func)
|
||||
{
|
||||
int err = net_error();
|
||||
|
@ -66,6 +66,8 @@ extern int net_initialize();
|
||||
*/
|
||||
extern int net_destroy();
|
||||
|
||||
extern struct event_base* net_get_evbase();
|
||||
|
||||
/**
|
||||
* @return the number of sockets currrently being monitored.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user