4 This file is part of avahi.
6 avahi is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 avahi is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14 Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with avahi; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
39 #include "simple-watch.h"
40 #include "thread-watch.h"
42 struct AvahiThreadedPoll {
43 AvahiSimplePoll *simple_poll;
45 pthread_mutex_t mutex;
50 static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) {
51 pthread_mutex_t *mutex = userdata;
54 /* Before entering poll() we unlock the mutex, so that
55 * avahi_simple_poll_quit() can succeed from another thread. */
57 pthread_mutex_unlock(mutex);
58 r = poll(ufds, nfds, timeout);
59 pthread_mutex_lock(mutex);
64 static void* thread(void *userdata){
65 AvahiThreadedPoll *p = userdata;
68 /* Make sure that signals are delivered to the main thread */
70 pthread_sigmask(SIG_BLOCK, &mask, NULL);
72 pthread_mutex_lock(&p->mutex);
73 p->retval = avahi_simple_poll_loop(p->simple_poll);
74 pthread_mutex_unlock(&p->mutex);
79 AvahiThreadedPoll *avahi_threaded_poll_new(void) {
82 if (!(p = avahi_new(AvahiThreadedPoll, 1)))
85 if (!(p->simple_poll = avahi_simple_poll_new()))
88 pthread_mutex_init(&p->mutex, NULL);
90 avahi_simple_poll_set_func(p->simple_poll, poll_func, &p->mutex);
92 p->thread_running = 0;
99 avahi_simple_poll_free(p->simple_poll);
100 pthread_mutex_destroy(&p->mutex);
109 void avahi_threaded_poll_free(AvahiThreadedPoll *p) {
112 /* Make sure that this function is not called from the helper thread */
113 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
115 if (p->thread_running)
116 avahi_threaded_poll_stop(p);
119 avahi_simple_poll_free(p->simple_poll);
121 pthread_mutex_destroy(&p->mutex);
125 const AvahiPoll* avahi_threaded_poll_get(AvahiThreadedPoll *p) {
128 return avahi_simple_poll_get(p->simple_poll);
131 int avahi_threaded_poll_start(AvahiThreadedPoll *p) {
134 assert(!p->thread_running);
136 if (pthread_create(&p->thread_id, NULL, thread, p) < 0)
142 int avahi_threaded_poll_stop(AvahiThreadedPoll *p) {
145 if (!p->thread_running)
148 /* Make sure that this function is not called from the helper thread */
149 assert(!pthread_equal(pthread_self(), p->thread_id));
151 pthread_mutex_lock(&p->mutex);
152 avahi_simple_poll_quit(p->simple_poll);
153 pthread_mutex_unlock(&p->mutex);
155 pthread_join(p->thread_id, NULL);
156 p->thread_running = 0;
161 void avahi_threaded_poll_quit(AvahiThreadedPoll *p) {
164 /* Make sure that this function is called from the helper thread */
165 assert(pthread_equal(pthread_self(), p->thread_id));
167 avahi_simple_poll_quit(p->simple_poll);
170 void avahi_threaded_poll_lock(AvahiThreadedPoll *p) {
173 /* Make sure that this function is not called from the helper thread */
174 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
176 pthread_mutex_lock(&p->mutex);
179 void avahi_threaded_poll_unlock(AvahiThreadedPoll *p) {
182 /* Make sure that this function is not called from the helper thread */
183 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
185 pthread_mutex_unlock(&p->mutex);