2 This file is part of avahi.
4 avahi is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 avahi is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
12 Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with avahi; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
37 #include "simple-watch.h"
38 #include "thread-watch.h"
40 struct AvahiThreadedPoll {
41 AvahiSimplePoll *simple_poll;
43 pthread_mutex_t mutex;
48 static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) {
49 pthread_mutex_t *mutex = userdata;
52 /* Before entering poll() we unlock the mutex, so that
53 * avahi_simple_poll_quit() can succeed from another thread. */
55 pthread_mutex_unlock(mutex);
56 r = poll(ufds, nfds, timeout);
57 pthread_mutex_lock(mutex);
62 static void* thread(void *userdata){
63 AvahiThreadedPoll *p = userdata;
66 /* Make sure that signals are delivered to the main thread */
68 pthread_sigmask(SIG_BLOCK, &mask, NULL);
70 pthread_mutex_lock(&p->mutex);
71 p->retval = avahi_simple_poll_loop(p->simple_poll);
72 pthread_mutex_unlock(&p->mutex);
77 AvahiThreadedPoll *avahi_threaded_poll_new(void) {
80 if (!(p = avahi_new(AvahiThreadedPoll, 1)))
83 if (!(p->simple_poll = avahi_simple_poll_new()))
86 pthread_mutex_init(&p->mutex, NULL);
88 avahi_simple_poll_set_func(p->simple_poll, poll_func, &p->mutex);
90 p->thread_running = 0;
97 avahi_simple_poll_free(p->simple_poll);
98 pthread_mutex_destroy(&p->mutex);
107 void avahi_threaded_poll_free(AvahiThreadedPoll *p) {
110 /* Make sure that this function is not called from the helper thread */
111 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
113 if (p->thread_running)
114 avahi_threaded_poll_stop(p);
117 avahi_simple_poll_free(p->simple_poll);
119 pthread_mutex_destroy(&p->mutex);
123 const AvahiPoll* avahi_threaded_poll_get(AvahiThreadedPoll *p) {
126 return avahi_simple_poll_get(p->simple_poll);
129 int avahi_threaded_poll_start(AvahiThreadedPoll *p) {
132 assert(!p->thread_running);
134 if (pthread_create(&p->thread_id, NULL, thread, p) < 0)
137 p->thread_running = 1;
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);