1 | /***************************************
2 | $Revision: 1.23 $
3 |
4 | Example code: A thread.
5 |
6 | Status: NOT REVUED, NOT TESTED
7 |
8 | Authors: Chris Ottrey
9 | Joao Damas
10 |
11 | +html+ <DL COMPACT>
12 | +html+ <DT>Online References:
13 | +html+ <DD><UL>
14 | +html+ </UL>
15 | +html+ </DL>
16 |
17 | ******************/ /******************
18 | Modification History:
19 | ottrey (02/03/1999) Created.
20 | ottrey (08/03/1999) Modified.
21 | ottrey (17/06/1999) Stripped down.
22 | joao (22/06/1999) Redid thread startup
23 | ******************/ /******************
24 | Copyright (c) 1999 RIPE NCC
25 |
26 | All Rights Reserved
27 |
28 | Permission to use, copy, modify, and distribute this software and its
29 | documentation for any purpose and without fee is hereby granted,
30 | provided that the above copyright notice appear in all copies and that
31 | both that copyright notice and this permission notice appear in
32 | supporting documentation, and that the name of the author not be
33 | used in advertising or publicity pertaining to distribution of the
34 | software without specific, written prior permission.
35 |
36 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
37 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
38 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
39 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
40 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
41 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 | ***************************************/
43 | #include <pthread.h> /* Posix thread library */
44 | #include <stdio.h>
45 | #include <strings.h>
46 |
47 | #include "thread.h"
48 | /* #include "socket.h"
49 | #include "protocol_whois.h"
50 | #include "protocol_config.h"
51 | #include "protocol_mirror.h"
52 | #include "constants.h"
53 | #include "server.h"
54 | */
55 | #include "memwrap.h"
56 |
57 |
58 | /*+ String sizes +*/
59 | #define STR_S 63
60 | #define STR_M 255
61 | #define STR_L 1023
62 | #define STR_XL 4095
63 | #define STR_XXL 16383
64 |
65 | //typedef struct th_args {
66 | // void *function;
67 | // int sock;
68 | //} th_args;
69 |
70 |
71 | /* TH_acquire_read_lock() */
72 | /*++++++++++++++++++++++++++++++++++++++
73 |
74 | Aquire a readers lock.
75 |
76 | rw_lock_t *prw_lock Readers writers lock.
77 |
78 | Reference: "Multithreaded Programming Techniques - Prasad p.192"
79 | More:
80 | +html+ <PRE>
81 | Author:
82 | ottrey
83 | +html+ </PRE>
84 | ++++++++++++++++++++++++++++++++++++++*/
85 | void TH_acquire_read_lock(rw_lock_t *prw_lock) {
86 | pthread_mutex_lock(&prw_lock->rw_mutex);
87 |
88 | while (prw_lock->rw_count < 0) {
89 | pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
90 | }
91 |
92 | ++prw_lock->rw_count;
93 | pthread_mutex_unlock(&prw_lock->rw_mutex);
94 |
95 | } /* TH_acquire_read_lock() */
96 |
97 | /* TH_release_read_lock() */
98 | /*++++++++++++++++++++++++++++++++++++++
99 |
100 | Release a readers lock.
101 |
102 | rw_lock_t *prw_lock Readers writers lock.
103 |
104 | Reference: "Multithreaded Programming Techniques - Prasad p.192"
105 | More:
106 | +html+ <PRE>
107 | Author:
108 | ottrey
109 | +html+ </PRE>
110 | ++++++++++++++++++++++++++++++++++++++*/
111 | void TH_release_read_lock(rw_lock_t *prw_lock) {
112 | pthread_mutex_lock(&prw_lock->rw_mutex);
113 |
114 | --prw_lock->rw_count;
115 |
116 | if (!prw_lock->rw_count) {
117 | pthread_cond_signal(&prw_lock->rw_cond);
118 | }
119 |
120 | pthread_mutex_unlock(&prw_lock->rw_mutex);
121 |
122 | } /* TH_release_read_lock() */
123 |
124 | /* TH_acquire_write_lock() */
125 | /*++++++++++++++++++++++++++++++++++++++
126 |
127 | Aquire a writers lock.
128 |
129 | rw_lock_t *prw_lock Readers writers lock.
130 |
131 | Reference: "Multithreaded Programming Techniques - Prasad p.192"
132 | More:
133 | +html+ <PRE>
134 | Author:
135 | ottrey
136 | +html+ </PRE>
137 | ++++++++++++++++++++++++++++++++++++++*/
138 | void TH_acquire_write_lock(rw_lock_t *prw_lock) {
139 | pthread_mutex_lock(&prw_lock->rw_mutex);
140 |
141 | while (prw_lock->rw_count != 0) {
142 | pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex);
143 | }
144 |
145 | prw_lock->rw_count = -1;
146 | pthread_mutex_unlock(&prw_lock->rw_mutex);
147 |
148 | } /* TH_acquire_write_lock() */
149 |
150 | /* TH_release_write_lock() */
151 | /*++++++++++++++++++++++++++++++++++++++
152 |
153 | Release a writers lock.
154 |
155 | rw_lock_t *prw_lock Readers writers lock.
156 |
157 | Reference: "Multithreaded Programming Techniques - Prasad p.192"
158 | More:
159 | +html+ <PRE>
160 | Author:
161 | ottrey
162 | +html+ </PRE>
163 | ++++++++++++++++++++++++++++++++++++++*/
164 | void TH_release_write_lock(rw_lock_t *prw_lock) {
165 | pthread_mutex_lock(&prw_lock->rw_mutex);
166 | prw_lock->rw_count = 0;
167 | pthread_mutex_unlock(&prw_lock->rw_mutex);
168 | pthread_cond_broadcast(&prw_lock->rw_cond);
169 |
170 | } /* TH_release_write_lock() */
171 |
172 | /* TH_init_read_write_lock() */
173 | /*++++++++++++++++++++++++++++++++++++++
174 |
175 | Initialize a readers/writers lock.
176 |
177 | rw_lock_t *prw_lock Readers writers lock.
178 |
179 | Side effect: the lock is set to open(?)
180 |
181 | Reference: "Multithreaded Programming Techniques - Prasad p.192"
182 | More:
183 | +html+ <PRE>
184 | Author:
185 | ottrey
186 | +html+ </PRE>
187 | ++++++++++++++++++++++++++++++++++++++*/
188 | void TH_init_read_write_lock(rw_lock_t *prw_lock) {
189 | pthread_mutex_init(&prw_lock->rw_mutex, NULL);
190 | pthread_cond_init(&prw_lock->rw_cond, NULL);
191 | prw_lock->rw_count = 0;
192 |
193 | } /* TH_init_read_write_lock() */
194 |
195 | int TH_get_id(void) {
196 |
197 | return (int)pthread_self();
198 |
199 | } /* TH_get_id() */
200 |
201 | /* TH_to_string() */
202 | char *TH_to_string(void) {
203 | char *thread_info;
204 | char tmp[STR_L];
205 | char thread_info_buffer[STR_XL];
206 |
207 | strcpy(thread_info_buffer, "Thread = { ");
208 |
209 | sprintf(tmp, "[pthread_self] = \"%d\" ", pthread_self());
210 | strcat(thread_info_buffer, tmp);
211 |
212 | /*
213 | thread_name = (char *)pthread_getspecific(Name);
214 |
215 | if (thread_name == NULL ) {
216 | sprintf(tmp, "[Name] = \"%s\" ", "didn't work!");
217 | }
218 | else {
219 | sprintf(tmp, "[Name] = \"%s\" ", thread_name);
220 | }
221 | strcat(thread_info_buffer, tmp);
222 | */
223 |
224 | strcat(thread_info_buffer, "}");
225 |
226 | dieif( wr_malloc((void **)&thread_info,
227 | strlen(thread_info_buffer)+1) != UT_OK);
228 |
229 | strcpy(thread_info, thread_info_buffer);
230 |
231 | return thread_info;
232 | } /* TH_to_string() */
233 |
234 |
235 | /*++++++++++++++++++++++++++++++++++++++
236 |
237 | This is the routine that creates a thread.
238 |
239 | More:
240 | +html+ <PRE>
241 | Author:
242 | ottrey
243 | joao
244 | andrei
245 | +html+ </PRE>
246 | ++++++++++++++++++++++++++++++++++++++*/
247 | pthread_t TH_create(void *do_function(void *), void *arguments ) {
248 | pthread_t tid;
249 | pthread_attr_t attr;
250 | int ret;
251 |
252 | /* Start a new thread. */
253 | pthread_attr_init(&attr); /* initialize attr with default attributes */
254 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
255 | ret = pthread_create(&tid, &attr, do_function, arguments);
256 | if( ret !=0 ) die;
257 | pthread_attr_destroy(&attr);
258 |
259 | return tid;
260 |
261 | } /* TH_run() */
262 |
263 |
264 |