1 /* $Id: sel_thread.c,v 1.2 2007-04-20 10:15:19 adam Exp $
2 Copyright (c) 2006-2007, Index Data.
4 This file is part of Pazpar2.
6 Pazpar2 is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with Pazpar2; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 #include "sel_thread.h"
35 struct work_item *next;
42 pthread_mutex_t mutex;
43 pthread_cond_t input_data;
45 struct work_item *input_queue;
46 struct work_item *output_queue;
47 struct work_item *free_queue;
48 void (*work_handler)(void *work_data);;
51 static void *sel_thread_handler(void *vp)
53 sel_thread_t p = (sel_thread_t) vp;
57 struct work_item **work_p, *work_this;
58 /* wait for some work */
59 pthread_mutex_lock(&p->mutex);
60 while (!p->stop_flag && !p->input_queue)
61 pthread_cond_wait(&p->input_data, &p->mutex);
62 /* see if we were waken up because we're shutting down */
65 /* got something. Take the last one out of input_queue */
66 work_p = &p->input_queue;
67 while ((*work_p)->next)
68 work_p = &(*work_p)->next;
71 pthread_mutex_unlock(&p->mutex);
73 /* work on this item */
74 p->work_handler(work_this->data);
76 /* put it back into output queue */
77 pthread_mutex_lock(&p->mutex);
78 work_this->next = p->output_queue;
79 p->output_queue = work_this;
80 pthread_mutex_unlock(&p->mutex);
82 /* wake up select/poll with a single byte */
83 write(p->fd[1], "", 1);
85 pthread_mutex_unlock(&p->mutex);
89 sel_thread_t sel_thread_create(void (*work_handler)(void *work_data),
92 NMEM nmem = nmem_create();
93 sel_thread_t p = nmem_malloc(nmem, sizeof(*p));
105 p->work_handler = work_handler;
108 pthread_mutex_init(&p->mutex, 0);
109 pthread_cond_init(&p->input_data, 0);
110 pthread_create (&p->thread_id, 0, sel_thread_handler, p);
114 void sel_thread_destroy(sel_thread_t p)
116 pthread_mutex_lock(&p->mutex);
119 pthread_cond_broadcast(&p->input_data);
120 pthread_mutex_unlock(&p->mutex);
122 pthread_join(p->thread_id, 0);
126 pthread_cond_destroy(&p->input_data);
127 pthread_mutex_destroy(&p->mutex);
128 nmem_destroy(p->nmem);
131 void sel_thread_add(sel_thread_t p, void *data)
133 struct work_item *work_p;
135 pthread_mutex_lock(&p->mutex);
136 work_p = p->free_queue;
138 work_p = nmem_malloc(p->nmem, sizeof(*work_p));
141 work_p->next = p->input_queue;
142 p->input_queue = work_p;
143 pthread_mutex_unlock(&p->mutex);
146 void *sel_thread_result(sel_thread_t p)
148 struct work_item **work_p, *work_this;
152 /* got something. Take the last one out of output_queue */
153 work_p = &p->output_queue;
157 read(p->fd[0], read_buf, 1);
159 while ((*work_p)->next)
160 work_p = &(*work_p)->next;
164 /* put freed item in free list */
165 work_this->next = p->free_queue;
166 p->free_queue = work_this;
168 data = work_this->data;
169 pthread_mutex_unlock(&p->mutex);
177 * indent-tabs-mode: nil
179 * vim: shiftwidth=4 tabstop=8 expandtab