1 | /*************************************** 2 | $Revision: 1.20 $ 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 | #include "memwrap.h" 55 | 56 | /*+ String sizes +*/ 57 | #define STR_S 63 58 | #define STR_M 255 59 | #define STR_L 1023 60 | #define STR_XL 4095 61 | #define STR_XXL 16383 62 | 63 | //typedef struct th_args { 64 | // void *function; 65 | // int sock; 66 | //} th_args; 67 | 68 | 69 | /* TH_acquire_read_lock() */ 70 | /*++++++++++++++++++++++++++++++++++++++ 71 | 72 | Aquire a readers lock. 73 | 74 | rw_lock_t *prw_lock Readers writers lock. 75 | 76 | Reference: "Multithreaded Programming Techniques - Prasad p.192" 77 | More: 78 | +html+ <PRE> 79 | Author: 80 | ottrey 81 | +html+ </PRE> 82 | ++++++++++++++++++++++++++++++++++++++*/ 83 | void TH_acquire_read_lock(rw_lock_t *prw_lock) { 84 | pthread_mutex_lock(&prw_lock->rw_mutex); 85 | 86 | while (prw_lock->rw_count < 0) { 87 | pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex); 88 | } 89 | 90 | ++prw_lock->rw_count; 91 | pthread_mutex_unlock(&prw_lock->rw_mutex); 92 | 93 | } /* TH_acquire_read_lock() */ 94 | 95 | /* TH_release_read_lock() */ 96 | /*++++++++++++++++++++++++++++++++++++++ 97 | 98 | Release a readers lock. 99 | 100 | rw_lock_t *prw_lock Readers writers lock. 101 | 102 | Reference: "Multithreaded Programming Techniques - Prasad p.192" 103 | More: 104 | +html+ <PRE> 105 | Author: 106 | ottrey 107 | +html+ </PRE> 108 | ++++++++++++++++++++++++++++++++++++++*/ 109 | void TH_release_read_lock(rw_lock_t *prw_lock) { 110 | pthread_mutex_lock(&prw_lock->rw_mutex); 111 | 112 | --prw_lock->rw_count; 113 | 114 | if (!prw_lock->rw_count) { 115 | pthread_cond_signal(&prw_lock->rw_cond); 116 | } 117 | 118 | pthread_mutex_unlock(&prw_lock->rw_mutex); 119 | 120 | } /* TH_release_read_lock() */ 121 | 122 | /* TH_acquire_write_lock() */ 123 | /*++++++++++++++++++++++++++++++++++++++ 124 | 125 | Aquire a writers lock. 126 | 127 | rw_lock_t *prw_lock Readers writers lock. 128 | 129 | Reference: "Multithreaded Programming Techniques - Prasad p.192" 130 | More: 131 | +html+ <PRE> 132 | Author: 133 | ottrey 134 | +html+ </PRE> 135 | ++++++++++++++++++++++++++++++++++++++*/ 136 | void TH_acquire_write_lock(rw_lock_t *prw_lock) { 137 | pthread_mutex_lock(&prw_lock->rw_mutex); 138 | 139 | while (prw_lock->rw_count != 0) { 140 | pthread_cond_wait(&prw_lock->rw_cond, &prw_lock->rw_mutex); 141 | } 142 | 143 | prw_lock->rw_count = -1; 144 | pthread_mutex_unlock(&prw_lock->rw_mutex); 145 | 146 | } /* TH_acquire_write_lock() */ 147 | 148 | /* TH_release_write_lock() */ 149 | /*++++++++++++++++++++++++++++++++++++++ 150 | 151 | Release a writers lock. 152 | 153 | rw_lock_t *prw_lock Readers writers lock. 154 | 155 | Reference: "Multithreaded Programming Techniques - Prasad p.192" 156 | More: 157 | +html+ <PRE> 158 | Author: 159 | ottrey 160 | +html+ </PRE> 161 | ++++++++++++++++++++++++++++++++++++++*/ 162 | void TH_release_write_lock(rw_lock_t *prw_lock) { 163 | pthread_mutex_lock(&prw_lock->rw_mutex); 164 | prw_lock->rw_count = 0; 165 | pthread_mutex_unlock(&prw_lock->rw_mutex); 166 | pthread_cond_broadcast(&prw_lock->rw_cond); 167 | 168 | } /* TH_release_write_lock() */ 169 | 170 | /* TH_init_read_write_lock() */ 171 | /*++++++++++++++++++++++++++++++++++++++ 172 | 173 | Initialize a readers/writers lock. 174 | 175 | rw_lock_t *prw_lock Readers writers lock. 176 | 177 | Side effect: the lock is set to open(?) 178 | 179 | Reference: "Multithreaded Programming Techniques - Prasad p.192" 180 | More: 181 | +html+ <PRE> 182 | Author: 183 | ottrey 184 | +html+ </PRE> 185 | ++++++++++++++++++++++++++++++++++++++*/ 186 | void TH_init_read_write_lock(rw_lock_t *prw_lock) { 187 | pthread_mutex_init(&prw_lock->rw_mutex, NULL); 188 | pthread_cond_init(&prw_lock->rw_cond, NULL); 189 | prw_lock->rw_count = 0; 190 | 191 | } /* TH_init_read_write_lock() */ 192 | 193 | int TH_get_id(void) { 194 | 195 | return (int)pthread_self(); 196 | 197 | } /* TH_get_id() */ 198 | 199 | /* TH_to_string() */ 200 | char *TH_to_string(void) { 201 | char *thread_info; 202 | char tmp[STR_L]; 203 | char thread_info_buffer[STR_XL]; 204 | 205 | strcpy(thread_info_buffer, "Thread = { "); 206 | 207 | sprintf(tmp, "[pthread_self] = \"%d\" ", pthread_self()); 208 | strcat(thread_info_buffer, tmp); 209 | 210 | /* 211 | thread_name = (char *)pthread_getspecific(Name); 212 | 213 | if (thread_name == NULL ) { 214 | sprintf(tmp, "[Name] = \"%s\" ", "didn't work!"); 215 | } 216 | else { 217 | sprintf(tmp, "[Name] = \"%s\" ", thread_name); 218 | } 219 | strcat(thread_info_buffer, tmp); 220 | */ 221 | 222 | strcat(thread_info_buffer, "}"); 223 | 224 | dieif( wr_malloc((void **)&thread_info, 225 | strlen(thread_info_buffer)+1) != UT_OK); 226 | 227 | strcpy(thread_info, thread_info_buffer); 228 | 229 | return thread_info; 230 | } /* TH_to_string() */ 231 | 232 | 233 | /*++++++++++++++++++++++++++++++++++++++ 234 | 235 | This is the routine that creates a thread. 236 | 237 | More: 238 | +html+ <PRE> 239 | Author: 240 | ottrey 241 | joao 242 | andrei 243 | +html+ </PRE> 244 | ++++++++++++++++++++++++++++++++++++++*/ 245 | void TH_create(void *do_function(void *), void *arguments ) { 246 | pthread_t tid; 247 | pthread_attr_t attr; 248 | 249 | /* Start a new thread. */ 250 | pthread_attr_init(&attr); /* initialize attr with default attributes */ 251 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 252 | pthread_create(&tid, &attr, do_function, arguments); 253 | 254 | } /* TH_run() */ 255 | 256 | 257 |