Files
libreoffice/sd/source/ui/remotecontrol/avahi-common/thread-watch.c
Siqi af1ce3de97 add threaded pool support for avahi backward compatibility
As suggested by Avahi maintainer, we should ship threadedpool support with the build since it's not availble to avahi priori to 0.6.3
This keeps the avahi support backward compatible.

Change-Id: I70db9d5b3be3fba744e40c9bb183307819b7df4e
2013-07-26 12:54:48 +02:00

191 lines
4.7 KiB
C

/* $Id$ */
/***
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
avahi 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 Lesser General
Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/poll.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <avahi-common/llist.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
#include <avahi-common/timeval.h>
#include <avahi-common/simple-watch.h>
// Only introduced in 0.6.13. Place it here as advised by avahi maintainer
#include "thread-watch.h"
struct AvahiThreadedPoll {
AvahiSimplePoll *simple_poll;
pthread_t thread_id;
pthread_mutex_t mutex;
int thread_running;
int retval;
};
static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) {
pthread_mutex_t *mutex = userdata;
int r;
/* Before entering poll() we unlock the mutex, so that
* avahi_simple_poll_quit() can succeed from another thread. */
pthread_mutex_unlock(mutex);
r = poll(ufds, nfds, timeout);
pthread_mutex_lock(mutex);
return r;
}
static void* thread(void *userdata){
AvahiThreadedPoll *p = userdata;
sigset_t mask;
/* Make sure that signals are delivered to the main thread */
sigfillset(&mask);
pthread_sigmask(SIG_BLOCK, &mask, NULL);
pthread_mutex_lock(&p->mutex);
p->retval = avahi_simple_poll_loop(p->simple_poll);
pthread_mutex_unlock(&p->mutex);
return NULL;
}
AvahiThreadedPoll *avahi_threaded_poll_new(void) {
AvahiThreadedPoll *p;
if (!(p = avahi_new(AvahiThreadedPoll, 1)))
goto fail; /* OOM */
if (!(p->simple_poll = avahi_simple_poll_new()))
goto fail;
pthread_mutex_init(&p->mutex, NULL);
avahi_simple_poll_set_func(p->simple_poll, poll_func, &p->mutex);
p->thread_running = 0;
return p;
fail:
if (p) {
if (p->simple_poll) {
avahi_simple_poll_free(p->simple_poll);
pthread_mutex_destroy(&p->mutex);
}
avahi_free(p);
}
return NULL;
}
void avahi_threaded_poll_free(AvahiThreadedPoll *p) {
assert(p);
/* Make sure that this function is not called from the helper thread */
assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
if (p->thread_running)
avahi_threaded_poll_stop(p);
if (p->simple_poll)
avahi_simple_poll_free(p->simple_poll);
pthread_mutex_destroy(&p->mutex);
avahi_free(p);
}
const AvahiPoll* avahi_threaded_poll_get(AvahiThreadedPoll *p) {
assert(p);
return avahi_simple_poll_get(p->simple_poll);
}
int avahi_threaded_poll_start(AvahiThreadedPoll *p) {
assert(p);
assert(!p->thread_running);
if (pthread_create(&p->thread_id, NULL, thread, p) < 0)
return -1;
p->thread_running = 1;
return 0;
}
int avahi_threaded_poll_stop(AvahiThreadedPoll *p) {
assert(p);
if (!p->thread_running)
return -1;
/* Make sure that this function is not called from the helper thread */
assert(!pthread_equal(pthread_self(), p->thread_id));
pthread_mutex_lock(&p->mutex);
avahi_simple_poll_quit(p->simple_poll);
pthread_mutex_unlock(&p->mutex);
pthread_join(p->thread_id, NULL);
p->thread_running = 0;
return p->retval;
}
void avahi_threaded_poll_quit(AvahiThreadedPoll *p) {
assert(p);
/* Make sure that this function is called from the helper thread */
assert(pthread_equal(pthread_self(), p->thread_id));
avahi_simple_poll_quit(p->simple_poll);
}
void avahi_threaded_poll_lock(AvahiThreadedPoll *p) {
assert(p);
/* Make sure that this function is not called from the helper thread */
assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
pthread_mutex_lock(&p->mutex);
}
void avahi_threaded_poll_unlock(AvahiThreadedPoll *p) {
assert(p);
/* Make sure that this function is not called from the helper thread */
assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
pthread_mutex_unlock(&p->mutex);
}