- job_queue tested
[strongswan.git] / Source / charon / thread_pool.c
1 /**
2 * @file worker.c
3 *
4 * @brief worker thread, gets jobs form job_queue
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23
24 #include "thread_pool.h"
25
26 #include <stdlib.h>
27 #include <freeswan.h>
28 #include <pluto/constants.h>
29 #include <pluto/defs.h>
30
31 #include <pthread.h>
32
33 /**
34 * structure with private members for thread_pool
35 */
36 typedef struct {
37 /**
38 * inclusion of public members
39 */
40 thread_pool_t public;
41 /**
42 * number of running threads
43 */
44 size_t pool_size;
45 /**
46 * array of thread ids
47 */
48 pthread_t *threads;
49 } private_thread_pool_t;
50
51
52
53
54 void *job_processing(private_thread_pool_t *this)
55 {
56 for (;;) {
57
58 sleep(1);
59
60 /* flag for termination received ? */
61 pthread_testcancel();
62 }
63 }
64
65 /**
66 * Implementation of thread_pool_t.get_pool_size
67 */
68 static status_t get_pool_size(private_thread_pool_t *this, size_t *size)
69 {
70 *size = this->pool_size;
71 return SUCCESS;
72 }
73
74 /**
75 * Implementation of thread_pool_t.destroy
76 */
77 static status_t destroy(private_thread_pool_t *this)
78 {
79 int current;
80
81 /* flag thread for termination */
82 for (current = 0; current < this->pool_size; current++) {
83 pthread_cancel(this->threads[current]);
84 }
85
86 /* wait for all threads */
87 for (current = 0; current < this->pool_size; current++) {
88 pthread_join(this->threads[current], NULL);
89 }
90
91 /* free mem */
92 pfree(this->threads);
93 pfree(this);
94 return SUCCESS;
95 }
96
97 /**
98 * Implementation of default constructor for thread_pool_t
99 */
100 thread_pool_t *thread_pool_create(size_t pool_size)
101 {
102 int current;
103
104 private_thread_pool_t *this = alloc_thing(private_thread_pool_t, "private_thread_pool_t");
105
106 /* fill in public fields */
107 this->public.destroy = (status_t(*)(thread_pool_t*))destroy;
108 this->public.get_pool_size = (status_t(*)(thread_pool_t*, size_t*))get_pool_size;
109
110 this->pool_size = pool_size;
111 this->threads = alloc_bytes(sizeof(pthread_t) * pool_size, "pthread_t[] of private_thread_pool_t");
112
113 /* try to create as many threads as possible, up tu pool_size */
114 for (current = 0; current < pool_size; current++) {
115 if (pthread_create(&(this->threads[current]), NULL, (void*(*)(void*))job_processing, this)) {
116 /* did we get any? */
117 if (current == 0) {
118 pfree(this->threads);
119 pfree(this);
120 return NULL;
121 }
122 /* not all threads could be created, but at least one :-/ */
123 this->pool_size = current;
124 return (thread_pool_t*)this;
125 }
126 }
127
128 return (thread_pool_t*)this;
129 }