2 This file is part of catta.
4 catta 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 catta 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 catta; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
34 #include <catta/llist.h>
35 #include <catta/malloc.h>
36 #include <catta/timeval.h>
37 #include <catta/simple-watch.h>
38 #include <catta/thread-watch.h>
40 struct CattaThreadedPoll {
41 CattaSimplePoll *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 * catta_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 CattaThreadedPoll *p = userdata;
68 /* Make sure that signals are delivered to the main thread */
70 pthread_sigmask(SIG_BLOCK, &mask, NULL);
73 pthread_mutex_lock(&p->mutex);
74 p->retval = catta_simple_poll_loop(p->simple_poll);
75 pthread_mutex_unlock(&p->mutex);
80 CattaThreadedPoll *catta_threaded_poll_new(void) {
83 if (!(p = catta_new(CattaThreadedPoll, 1)))
86 if (!(p->simple_poll = catta_simple_poll_new()))
89 pthread_mutex_init(&p->mutex, NULL);
91 catta_simple_poll_set_func(p->simple_poll, poll_func, &p->mutex);
93 p->thread_running = 0;
100 catta_simple_poll_free(p->simple_poll);
101 pthread_mutex_destroy(&p->mutex);
110 void catta_threaded_poll_free(CattaThreadedPoll *p) {
113 /* Make sure that this function is not called from the helper thread */
114 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
116 if (p->thread_running)
117 catta_threaded_poll_stop(p);
120 catta_simple_poll_free(p->simple_poll);
122 pthread_mutex_destroy(&p->mutex);
126 const CattaPoll* catta_threaded_poll_get(CattaThreadedPoll *p) {
129 return catta_simple_poll_get(p->simple_poll);
132 int catta_threaded_poll_start(CattaThreadedPoll *p) {
135 assert(!p->thread_running);
137 if (pthread_create(&p->thread_id, NULL, thread, p) < 0)
140 p->thread_running = 1;
145 int catta_threaded_poll_stop(CattaThreadedPoll *p) {
148 if (!p->thread_running)
151 /* Make sure that this function is not called from the helper thread */
152 assert(!pthread_equal(pthread_self(), p->thread_id));
154 pthread_mutex_lock(&p->mutex);
155 catta_simple_poll_quit(p->simple_poll);
156 pthread_mutex_unlock(&p->mutex);
158 pthread_join(p->thread_id, NULL);
159 p->thread_running = 0;
164 void catta_threaded_poll_quit(CattaThreadedPoll *p) {
167 /* Make sure that this function is called from the helper thread */
168 assert(pthread_equal(pthread_self(), p->thread_id));
170 catta_simple_poll_quit(p->simple_poll);
173 void catta_threaded_poll_lock(CattaThreadedPoll *p) {
176 /* Make sure that this function is not called from the helper thread */
177 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
179 pthread_mutex_lock(&p->mutex);
182 void catta_threaded_poll_unlock(CattaThreadedPoll *p) {
185 /* Make sure that this function is not called from the helper thread */
186 assert(!p->thread_running || !pthread_equal(pthread_self(), p->thread_id));
188 pthread_mutex_unlock(&p->mutex);