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() */