diff --git a/src/network/backend.c b/src/network/backend.c index 384b14e..00cc72d 100644 --- a/src/network/backend.c +++ b/src/network/backend.c @@ -141,7 +141,7 @@ int net_backend_process() } // Process pending DNS results - net_dns_process(); + // net_dns_process(); g_backend->handler.backend_process(g_backend->data, res); diff --git a/src/network/dnsresolver.c b/src/network/dnsresolver.c index d3ff25e..0484e9a 100644 --- a/src/network/dnsresolver.c +++ b/src/network/dnsresolver.c @@ -68,6 +68,11 @@ static void shutdown_free_results(void* ptr) net_dns_result_free(result); } +static void notify_callback(struct uhub_notify_handle* handle, void* ptr) +{ + net_dns_process(); +} + // NOTE: Any job manipulating the members of this // struct must lock the mutex! @@ -76,6 +81,8 @@ struct net_dns_subsystem struct linked_list* jobs; // currently running jobs struct linked_list* results; // queue of results that are awaiting being delivered to callback. uhub_mutex_t mutex; + + struct uhub_notify_handle* notify_handle; // used to signal back to the event loop that there is something to process. }; static struct net_dns_subsystem* g_dns = NULL; @@ -87,6 +94,7 @@ void net_dns_initialize() g_dns->jobs = list_create(); g_dns->results = list_create(); uhub_mutex_init(&g_dns->mutex); + g_dns->notify_handle = net_notify_create(notify_callback, g_dns); } void net_dns_destroy() @@ -105,6 +113,7 @@ void net_dns_destroy() list_destroy(g_dns->jobs); list_destroy(g_dns->results); uhub_mutex_destroy(&g_dns->mutex); + net_notify_destroy(g_dns->notify_handle); hub_free(g_dns); g_dns = NULL; } @@ -113,7 +122,7 @@ void net_dns_process() { struct net_dns_result* result; uhub_mutex_lock(&g_dns->mutex); - LOG_DUMP("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); + LOG_TRACE("net_dns_process(): jobs=%d, results=%d", (int) list_size(g_dns->jobs), (int) list_size(g_dns->results)); LIST_FOREACH(struct net_dns_result*, result, g_dns->results, { @@ -210,6 +219,7 @@ static void* job_thread_resolve_name(void* ptr) uhub_mutex_lock(&g_dns->mutex); list_remove(g_dns->jobs, job); list_append(g_dns->results, dns_results); + net_notify_signal(g_dns->notify_handle, 1); uhub_mutex_unlock(&g_dns->mutex); return dns_results; diff --git a/src/network/notify.c b/src/network/notify.c new file mode 100644 index 0000000..110ef7b --- /dev/null +++ b/src/network/notify.c @@ -0,0 +1,102 @@ +/* + * uhub - A tiny ADC p2p connection hub + * Copyright (C) 2007-2014, 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 . + * + */ + +#include "uhub.h" + +struct uhub_notify_handle +{ + net_notify_callback callback; + void* ptr; +#ifndef WIN32 + int pipe_fd[2]; + struct net_connection* con; +#endif +}; + +/* + * This contains a mechanism to wake up the main thread + * in a thread safe manner while it would be blocking + * in select() or something equivalent typically invoked from + * net_backend_process(). + * + * The main usage is for the DNS resolver to notify the + * main thread that there are DNS results to be + * processed. + */ + +/** + * Create a notification handle. + */ +#ifndef WIN32 +static void notify_callback(struct net_connection* con, int event, void* ptr) +{ + LOG_TRACE("notify_callback()"); + struct uhub_notify_handle* handle = (struct uhub_notify_handle*) ptr; + char buf; + int ret = read(handle->pipe_fd[0], &buf, 1); + if (ret == 1) + { + if (handle->callback) + handle->callback(handle, handle->ptr); + } +} +#endif + +struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr) +{ + LOG_TRACE("net_notify_create()"); + struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle)); + handle->callback = cb; + handle->ptr = ptr; +#ifndef WIN32 + int ret = pipe(handle->pipe_fd); + if (ret == -1) + { + LOG_ERROR("Unable to setup notification pipes."); + hub_free(handle); + return 0; + } + + handle->con = net_con_create(); + net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ); +#endif + return handle; +} + + +void net_notify_destroy(struct uhub_notify_handle* handle) +{ + LOG_TRACE("net_notify_destroy()"); +#ifndef WIN32 + net_con_destroy(handle->con); + close(handle->pipe_fd[0]); + close(handle->pipe_fd[1]); + handle->pipe_fd[0] = -1; + handle->pipe_fd[0] = -1; +#endif + hub_free(handle); +} + +void net_notify_signal(struct uhub_notify_handle* handle, char data) +{ + LOG_TRACE("net_notify_signal()"); +#ifndef WIN32 + write(handle->pipe_fd[1], &data, 1); +#endif +} \ No newline at end of file diff --git a/src/network/notify.h b/src/network/notify.h new file mode 100644 index 0000000..e8337cb --- /dev/null +++ b/src/network/notify.h @@ -0,0 +1,56 @@ +/* + * uhub - A tiny ADC p2p connection hub + * Copyright (C) 2007-2014, 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 . + * + */ + +#ifndef HAVE_UHUB_NETWORK_NOTIFY_API_H +#define HAVE_UHUB_NETWORK_NOTIFY_API_H + +struct uhub_notify_handle; + +typedef void (*net_notify_callback)(struct uhub_notify_handle* handle, void* ptr); + +/* + * This contains a mechanism to wake up the main thread + * in a thread safe manner while it would be blocking + * in select() or something equivalent typically invoked from + * net_backend_process(). + * + * The main usage is for the DNS resolver to notify the + * main thread that there are DNS results to be + * processed. + */ + +/** + * Create a notification handle. + */ +struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr); + +/** + * Destroy a notification handle. + */ +void net_notify_destroy(struct uhub_notify_handle*); + +/** + * Signal the notification handle, this will surely + * interrupt the net_backend_process(), and force it to + * process messages. + */ +void net_notify_signal(struct uhub_notify_handle*, char data); + + +#endif /* HAVE_UHUB_NETWORK_NOTIFY_API_H */ diff --git a/src/tools/admin.c b/src/tools/admin.c index bf114cd..1916988 100644 --- a/src/tools/admin.c +++ b/src/tools/admin.c @@ -159,8 +159,7 @@ static int handle(struct ADC_client* client, enum ADC_client_callback_type type, static int running = 1; #if !defined(WIN32) -static int adm_pipes[2] = { -1, -1 }; -static struct net_connection* adm_con = 0; +static struct uhub_notify_handle* notify_handle; void adm_handle_signal(int sig) { @@ -198,10 +197,6 @@ static int signals[] = 0 }; -void adm_callback(struct net_connection* con, int event, void* ptr) -{ -} - void adm_setup_signal_handlers() { sigset_t sig_set; @@ -224,22 +219,13 @@ void adm_setup_signal_handlers() void adm_setup_control_pipe() { - int ret = pipe(adm_pipes); - if (ret == -1) - { - LOG_ERROR("Unable to setup control pipes."); - } - adm_con = net_con_create(); - net_con_initialize(adm_con, adm_pipes[0], adm_callback, 0, NET_EVENT_READ); + notify_handle = net_notify_create(NULL, NULL); } void adm_shutdown_control_pipe() { - net_con_destroy(adm_con); - close(adm_pipes[0]); - close(adm_pipes[1]); - adm_pipes[0] = -1; - adm_pipes[0] = -1; + net_notify_destroy(notify_handle); + notify_handle = NULL; } void adm_shutdown_signal_handlers() diff --git a/src/uhub.h b/src/uhub.h index 3d2bfd7..4069291 100644 --- a/src/uhub.h +++ b/src/uhub.h @@ -75,6 +75,7 @@ extern "C" { #include "adc/message.h" #include "network/network.h" +#include "network/notify.h" #include "network/connection.h" #include "network/dnsresolver.h" #include "network/ipcalc.h"