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 |