another thread to the mainthread in a safe manner. This is used for the DNS lookup code, and can also be used by the signal handler to safely report actions back to the application mainloop without using global variables.
102 lines
2.6 KiB
C
102 lines
2.6 KiB
C
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#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
|
|
} |