1 /*
2  * uhub - A tiny ADC p2p connection hub
3  * Copyright (C) 2007-2014, Jan Vidar Krey
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "uhub.h"
21 
22 struct uhub_notify_handle
23 {
24 	net_notify_callback callback;
25 	void* ptr;
26 #ifndef WIN32
27 	int pipe_fd[2];
28 	struct net_connection* con;
29 #endif
30 };
31 
32 /*
33  * This contains a mechanism to wake up the main thread
34  * in a thread safe manner while it would be blocking
35  * in select() or something equivalent typically invoked from
36  * net_backend_process().
37  *
38  * The main usage is for the DNS resolver to notify the
39  * main thread that there are DNS results to be
40  * processed.
41  */
42 
43 /**
44  * Create a notification handle.
45  */
46 #ifndef WIN32
notify_callback(struct net_connection * con,int event,void * ptr)47 static void notify_callback(struct net_connection* con, int event, void* ptr)
48 {
49 	LOG_TRACE("notify_callback()");
50 	struct uhub_notify_handle* handle = (struct uhub_notify_handle*) ptr;
51 	char buf;
52 	int ret = read(handle->pipe_fd[0], &buf, 1);
53 	if (ret == 1)
54 	{
55 		if (handle->callback)
56 			handle->callback(handle, handle->ptr);
57 	}
58 }
59 #endif
60 
net_notify_create(net_notify_callback cb,void * ptr)61 struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr)
62 {
63 	LOG_TRACE("net_notify_create()");
64 	struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle));
65 	handle->callback = cb;
66 	handle->ptr = ptr;
67 #ifndef WIN32
68 	int ret = pipe(handle->pipe_fd);
69 	if (ret == -1)
70 	{
71 		LOG_ERROR("Unable to setup notification pipes.");
72 		hub_free(handle);
73 		return 0;
74 	}
75 
76 	handle->con = net_con_create();
77 	net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ);
78 #endif
79 	return handle;
80 }
81 
82 
net_notify_destroy(struct uhub_notify_handle * handle)83 void net_notify_destroy(struct uhub_notify_handle* handle)
84 {
85 	LOG_TRACE("net_notify_destroy()");
86 #ifndef WIN32
87 	net_con_destroy(handle->con);
88 	close(handle->pipe_fd[0]);
89 	close(handle->pipe_fd[1]);
90 	handle->pipe_fd[0] = -1;
91 	handle->pipe_fd[0] = -1;
92 #endif
93 	hub_free(handle);
94 }
95 
net_notify_signal(struct uhub_notify_handle * handle,char data)96 void net_notify_signal(struct uhub_notify_handle* handle, char data)
97 {
98 	LOG_TRACE("net_notify_signal()");
99 #ifndef WIN32
100 	write(handle->pipe_fd[1], &data, 1);
101 #endif
102 }