1 | /*************************************** 2 | $Revision: 1.3 $ 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 <stdio.h> 44 | #include <pthread.h> /* Posix thread library */ 45 | #include "protocol_config.h" 46 | #include "constants.h" 47 | 48 | /*+ String sizes +*/ 49 | #define STR_S 63 50 | #define STR_M 255 51 | #define STR_L 1023 52 | #define STR_XL 4095 53 | #define STR_XXL 16383 54 | 55 | /*+ Mutex lock. Used for synchronizing changes. +*/ 56 | pthread_mutex_t Whois_thread_count_lock; 57 | pthread_mutex_t Config_thread_count_lock; 58 | pthread_mutex_t Mirror_thread_count_lock; 59 | 60 | /*+ The number of threads. +*/ 61 | int Whois_thread_count; 62 | int Config_thread_count; 63 | int Mirror_thread_count; 64 | 65 | typedef struct th_args { 66 | void * function; 67 | int sock; 68 | } th_args; 69 | 70 | static void log_print(const char *arg) { 71 | FILE *logf; 72 | char *str; 73 | 74 | if (CO_get_thread_logging() == 1) { 75 | if (strcmp(CO_get_thread_logfile(), "stdout") == 0) { 76 | printf(arg); 77 | } 78 | else { 79 | logf = fopen(CO_get_thread_logfile(), "a"); 80 | fprintf(logf, arg); 81 | fclose(logf); 82 | } 83 | } 84 | 85 | } /* log_print() */ 86 | 87 | int TH_get_id(void) { 88 | 89 | return (int)pthread_self(); 90 | 91 | } /* TH_get_id() */ 92 | 93 | /* TH_to_string() */ 94 | char *TH_to_string(void) { 95 | char *thread_info; 96 | char tmp[STR_L]; 97 | char thread_info_buffer[STR_XL]; 98 | char *thread_name; 99 | 100 | strcpy(thread_info_buffer, "Thread = { "); 101 | 102 | sprintf(tmp, "[pthread_self] = \"%d\" ", pthread_self()); 103 | strcat(thread_info_buffer, tmp); 104 | 105 | /* 106 | thread_name = (char *)pthread_getspecific(Name); 107 | 108 | if (thread_name == NULL ) { 109 | sprintf(tmp, "[Name] = \"%s\" ", "didn't work!"); 110 | } 111 | else { 112 | sprintf(tmp, "[Name] = \"%s\" ", thread_name); 113 | } 114 | strcat(thread_info_buffer, tmp); 115 | */ 116 | 117 | strcat(thread_info_buffer, "}"); 118 | 119 | thread_info = (char *)calloc(1, strlen(thread_info_buffer)+1); 120 | strcpy(thread_info, thread_info_buffer); 121 | 122 | return thread_info; 123 | } /* TH_to_string() */ 124 | 125 | /* TH_do_whois() */ 126 | /*++++++++++++++++++++++++++++++++++++++ 127 | 128 | Handle whois connections. 129 | 130 | void *arg The socket to connect to. (It has to be passed in this way for this thread routine.) 131 | 132 | More: 133 | +html+ <PRE> 134 | Author: 135 | joao 136 | +html+ </PRE> 137 | ++++++++++++++++++++++++++++++++++++++*/ 138 | void TH_do_whois(void *arg) { 139 | int sock = (int)arg; 140 | char print_buf[STR_M]; 141 | 142 | sprintf(print_buf, "Whois: Child thread [%d]: Socket number = %d\n", pthread_self(), sock); log_print(print_buf); strcpy(print_buf, ""); 143 | 144 | /* Use a mutex to update the global whois thread counter. */ 145 | pthread_mutex_lock(&Whois_thread_count_lock); 146 | Whois_thread_count++; 147 | sprintf(print_buf, "Whois_thread_count++=%d\n", Whois_thread_count); log_print(print_buf); strcpy(print_buf, ""); 148 | pthread_mutex_unlock(&Whois_thread_count_lock); 149 | 150 | PW_interact(sock); 151 | 152 | /* Use a mutex to update the global whois thread counter. */ 153 | pthread_mutex_lock(&Whois_thread_count_lock); 154 | Whois_thread_count--; 155 | sprintf(print_buf, "Whois_thread_count--=%d\n", Whois_thread_count); log_print(print_buf); strcpy(print_buf, ""); 156 | pthread_mutex_unlock(&Whois_thread_count_lock); 157 | 158 | pthread_exit((void *)0); 159 | 160 | } /* TH_do_whois() */ 161 | 162 | /* TH_do_config() */ 163 | /*++++++++++++++++++++++++++++++++++++++ 164 | 165 | Handle config connections. 166 | 167 | void *arg The socket to connect to. (It has to be passed in this way for this 168 | thread routine.) 169 | 170 | More: 171 | +html+ <PRE> 172 | Author: 173 | joao 174 | +html+ </PRE> 175 | ++++++++++++++++++++++++++++++++++++++*/ 176 | void TH_do_config(void *arg) { 177 | int sock = (int)arg; 178 | char print_buf[STR_M]; 179 | 180 | sprintf(print_buf, "Config: Child thread [%d]: Socket number = %d\n", pthread_self(), sock); log_print(print_buf); strcpy(print_buf, ""); 181 | 182 | /* 183 | printf("Hi there, there is nothing to configure yet\nBye..... :-)\n"); 184 | fflush(NULL); 185 | 186 | SK_close(sock); 187 | */ 188 | PC_interact(sock); 189 | 190 | pthread_exit((void *)0); 191 | 192 | } /* TH_do_config() */ 193 | 194 | /* main_function() */ 195 | /*++++++++++++++++++++++++++++++++++++++ 196 | 197 | Waits for an incoming connection on the and spawns a new thread to handle it. 198 | 199 | void *arg Pointer to a struct containing the socket to talk to the client and 200 | the function to call depending on the incoming connection. 201 | 202 | More: 203 | +html+ <PRE> 204 | Author: 205 | ottrey 206 | joao 207 | +html+ </PRE> 208 | ++++++++++++++++++++++++++++++++++++++*/ 209 | static void *main_thread(void *arg) { 210 | th_args *args = (th_args *)arg; 211 | pthread_t tid; 212 | pthread_attr_t attr; 213 | int connected_socket; 214 | 215 | while(1) { 216 | 217 | connected_socket = SK_accept_connection(args->sock); 218 | 219 | /* Start a new thread. */ 220 | 221 | pthread_attr_init(&attr); /* initialize attr with default attributes */ 222 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 223 | pthread_create(&tid, &attr, (void *(*)(void *))(args->function), (void *)connected_socket); 224 | } 225 | 226 | } /* main_function() */ 227 | 228 | /* TH_run() */ 229 | /*++++++++++++++++++++++++++++++++++++++ 230 | 231 | This is the routine that creates the main threads. 232 | 233 | int sock The socket to connect to. 234 | void * do_function The function to call for each type of service 235 | 236 | More: 237 | +html+ <PRE> 238 | Author: 239 | ottrey 240 | joao 241 | +html+ </PRE> 242 | ++++++++++++++++++++++++++++++++++++++*/ 243 | void TH_run(int sock, void *do_function) { 244 | th_args *args; 245 | pthread_t tid; 246 | pthread_attr_t attr; 247 | char print_buf[STR_M]; 248 | 249 | int connected_socket; 250 | 251 | args = (th_args *)calloc(1,sizeof(th_args)); 252 | args->function=do_function; 253 | args->sock=sock; 254 | 255 | /* pthread_mutex_init(&Whois_thread_count_lock,NULL); */ 256 | 257 | if ( CO_get_max_threads() == 0 ) { 258 | sprintf(print_buf, "Running with no threads\n"); log_print(print_buf); strcpy(print_buf, ""); 259 | connected_socket = SK_accept_connection(sock); 260 | PW_interact(connected_socket); 261 | } 262 | else { 263 | /* Start a new thread. */ 264 | pthread_attr_init(&attr); /* initialize attr with default attributes */ 265 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 266 | pthread_create(&tid, &attr, main_thread, (void *)args); 267 | } 268 | 269 | } /* TH_run() */