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 }