1    | /***************************************
2    |   $Revision: 1.22 $
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  | 
251  |     /* Start a new thread. */
252  |     pthread_attr_init(&attr);     /* initialize attr with default attributes */
253  |     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
254  |     pthread_create(&tid, &attr, do_function, arguments);
255  | 
256  |     return tid;
257  | 
258  | } /* TH_run() */
259  | 
260  | 
261  |