OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Licensed Materials - Property of IBM | 3 * Licensed Materials - Property of IBM |
4 * | 4 * |
5 * trousers - An open source TCG Software Stack | 5 * trousers - An open source TCG Software Stack |
6 * | 6 * |
7 * (C) Copyright International Business Machines Corp. 2004-2006 | 7 * (C) Copyright International Business Machines Corp. 2004-2006 |
8 * | 8 * |
9 */ | 9 */ |
10 | 10 |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 MUTEX_LOCK(tm->lock); | 39 MUTEX_LOCK(tm->lock); |
40 | 40 |
41 tm->shutdown = 1; | 41 tm->shutdown = 1; |
42 | 42 |
43 MUTEX_UNLOCK(tm->lock); | 43 MUTEX_UNLOCK(tm->lock); |
44 | 44 |
45 /* wait for all currently running threads to exit */ | 45 /* wait for all currently running threads to exit */ |
46 for (i = 0; i < tm->max_threads; i++) { | 46 for (i = 0; i < tm->max_threads; i++) { |
47 if (tm->thread_data[i].thread_id != THREAD_NULL) { | 47 if (tm->thread_data[i].thread_id != THREAD_NULL) { |
48 » » » if ((rc = THREAD_JOIN(tm->thread_data[i].thread_id, NULL
))) { | 48 » » » if ((rc = THREAD_JOIN(*(tm->thread_data[i].thread_id), N
ULL))) { |
49 LogError("Thread join failed: error: %d", rc); | 49 LogError("Thread join failed: error: %d", rc); |
50 } | 50 } |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 free(tm->thread_data); | 54 free(tm->thread_data); |
55 free(tm); | 55 free(tm); |
56 | 56 |
57 return TSS_SUCCESS; | 57 return TSS_SUCCESS; |
58 } | 58 } |
59 | 59 |
60 TSS_RESULT | 60 TSS_RESULT |
61 tcsd_threads_init(void) | 61 tcsd_threads_init(void) |
62 { | 62 { |
63 /* allocate the thread mgmt structure */ | 63 /* allocate the thread mgmt structure */ |
64 tm = calloc(1, sizeof(struct tcsd_thread_mgr)); | 64 tm = calloc(1, sizeof(struct tcsd_thread_mgr)); |
65 if (tm == NULL) { | 65 if (tm == NULL) { |
66 LogError("malloc of %zd bytes failed.", sizeof(struct tcsd_threa
d_mgr)); | 66 LogError("malloc of %zd bytes failed.", sizeof(struct tcsd_threa
d_mgr)); |
67 return TCSERR(TSS_E_OUTOFMEMORY); | 67 return TCSERR(TSS_E_OUTOFMEMORY); |
68 } | 68 } |
| 69 /* initialize mutex */ |
| 70 MUTEX_INIT(tm->lock); |
69 | 71 |
70 /* set the max threads variable from config */ | 72 /* set the max threads variable from config */ |
71 tm->max_threads = tcsd_options.num_threads; | 73 tm->max_threads = tcsd_options.num_threads; |
72 | 74 |
73 /* allocate each thread's data structure */ | 75 /* allocate each thread's data structure */ |
74 tm->thread_data = calloc(tcsd_options.num_threads, sizeof(struct tcsd_th
read_data)); | 76 tm->thread_data = calloc(tcsd_options.num_threads, sizeof(struct tcsd_th
read_data)); |
75 if (tm->thread_data == NULL) { | 77 if (tm->thread_data == NULL) { |
76 LogError("malloc of %zu bytes failed.", | 78 LogError("malloc of %zu bytes failed.", |
77 tcsd_options.num_threads * sizeof(struct tcsd_thread_da
ta)); | 79 tcsd_options.num_threads * sizeof(struct tcsd_thread_da
ta)); |
78 free(tm); | 80 free(tm); |
79 return TCSERR(TSS_E_OUTOFMEMORY); | 81 return TCSERR(TSS_E_OUTOFMEMORY); |
80 } | 82 } |
81 | 83 |
82 return TSS_SUCCESS; | 84 return TSS_SUCCESS; |
83 } | 85 } |
84 | 86 |
85 | 87 |
86 TSS_RESULT | 88 TSS_RESULT |
87 tcsd_thread_create(int socket, char *hostname) | 89 tcsd_thread_create(int socket, char *hostname) |
88 { | 90 { |
89 » UINT32 thread_num; | 91 » UINT32 thread_num = -1; |
| 92 » int rc = TCS_SUCCESS; |
90 #ifndef TCSD_SINGLE_THREAD_DEBUG | 93 #ifndef TCSD_SINGLE_THREAD_DEBUG |
91 int rc; | |
92 THREAD_ATTR_DECLARE(tcsd_thread_attr); | 94 THREAD_ATTR_DECLARE(tcsd_thread_attr); |
93 | 95 |
94 /* init the thread attribute */ | 96 /* init the thread attribute */ |
95 if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) { | 97 if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) { |
96 LogError("Initializing thread attribute failed: error=%d: %s", r
c, strerror(rc)); | 98 LogError("Initializing thread attribute failed: error=%d: %s", r
c, strerror(rc)); |
97 » » return TCSERR(TSS_E_INTERNAL_ERROR); | 99 » » rc = TCSERR(TSS_E_INTERNAL_ERROR); |
| 100 » » goto out; |
98 } | 101 } |
99 /* make all threads joinable */ | 102 /* make all threads joinable */ |
100 if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) { | 103 if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) { |
101 LogError("Making thread attribute joinable failed: error=%d: %s"
, rc, strerror(rc)); | 104 LogError("Making thread attribute joinable failed: error=%d: %s"
, rc, strerror(rc)); |
102 » » return TCSERR(TSS_E_INTERNAL_ERROR); | 105 » » rc = TCSERR(TSS_E_INTERNAL_ERROR); |
| 106 » » goto out; |
103 } | 107 } |
104 | 108 |
105 MUTEX_LOCK(tm->lock); | 109 MUTEX_LOCK(tm->lock); |
106 #endif | 110 #endif |
107 if (tm->num_active_threads == tm->max_threads) { | 111 if (tm->num_active_threads == tm->max_threads) { |
108 close(socket); | |
109 if (hostname != NULL) { | 112 if (hostname != NULL) { |
110 LogError("max number of connections reached (%d), new co
nnection" | 113 LogError("max number of connections reached (%d), new co
nnection" |
111 " from %s refused.", tm->max_threads, hostname)
; | 114 " from %s refused.", tm->max_threads, hostname)
; |
112 } else { | 115 } else { |
113 LogError("max number of connections reached (%d), new co
nnection" | 116 LogError("max number of connections reached (%d), new co
nnection" |
114 " refused.", tm->max_threads); | 117 " refused.", tm->max_threads); |
115 } | 118 } |
116 » » free(hostname); | 119 » » rc = TCSERR(TSS_E_CONNECTION_FAILED); |
117 » » MUTEX_UNLOCK(tm->lock); | 120 #ifndef TCSD_SINGLE_THREAD_DEBUG |
118 » » return TCSERR(TSS_E_CONNECTION_FAILED); | 121 » » goto out_unlock; |
| 122 #else |
| 123 » » goto out; |
| 124 #endif |
119 } | 125 } |
120 | 126 |
121 /* search for an open slot to store the thread data in */ | 127 /* search for an open slot to store the thread data in */ |
122 for (thread_num = 0; thread_num < tm->max_threads; thread_num++) { | 128 for (thread_num = 0; thread_num < tm->max_threads; thread_num++) { |
123 if (tm->thread_data[thread_num].thread_id == THREAD_NULL) | 129 if (tm->thread_data[thread_num].thread_id == THREAD_NULL) |
124 break; | 130 break; |
125 } | 131 } |
126 | 132 |
127 DBG_ASSERT(thread_num != tm->max_threads); | 133 DBG_ASSERT(thread_num != tm->max_threads); |
128 | 134 |
129 tm->thread_data[thread_num].sock = socket; | 135 tm->thread_data[thread_num].sock = socket; |
130 tm->thread_data[thread_num].context = NULL_TCS_HANDLE; | 136 tm->thread_data[thread_num].context = NULL_TCS_HANDLE; |
131 if (hostname != NULL) | 137 if (hostname != NULL) |
132 tm->thread_data[thread_num].hostname = hostname; | 138 tm->thread_data[thread_num].hostname = hostname; |
133 | 139 |
134 #ifdef TCSD_SINGLE_THREAD_DEBUG | 140 #ifdef TCSD_SINGLE_THREAD_DEBUG |
135 (void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num]))); | 141 (void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num]))); |
136 #else | 142 #else |
137 » if ((rc = THREAD_CREATE(&(tm->thread_data[thread_num].thread_id), | 143 » tm->thread_data[thread_num].thread_id = calloc(1, sizeof(THREAD_TYPE)); |
| 144 » if (tm->thread_data[thread_num].thread_id == NULL) { |
| 145 » » rc = TCSERR(TSS_E_OUTOFMEMORY); |
| 146 » » LogError("malloc of %zd bytes failed.", sizeof(THREAD_TYPE)); |
| 147 » » goto out_unlock; |
| 148 » } |
| 149 |
| 150 » if ((rc = THREAD_CREATE(tm->thread_data[thread_num].thread_id, |
138 &tcsd_thread_attr, | 151 &tcsd_thread_attr, |
139 tcsd_thread_run, | 152 tcsd_thread_run, |
140 (void *)(&(tm->thread_data[thread_num]))))) { | 153 (void *)(&(tm->thread_data[thread_num]))))) { |
141 LogError("Thread create failed: %d", rc); | 154 LogError("Thread create failed: %d", rc); |
142 » » MUTEX_UNLOCK(tm->lock); | 155 » » rc = TCSERR(TSS_E_INTERNAL_ERROR); |
143 » » return TCSERR(TSS_E_INTERNAL_ERROR); | 156 » » goto out_unlock; |
144 } | 157 } |
145 | 158 |
146 tm->num_active_threads++; | 159 tm->num_active_threads++; |
147 | 160 |
| 161 out_unlock: |
148 MUTEX_UNLOCK(tm->lock); | 162 MUTEX_UNLOCK(tm->lock); |
149 #endif | 163 #endif |
150 » return TSS_SUCCESS; | 164 out: |
| 165 » /* cleanup in case of error */ |
| 166 » if (rc != TCS_SUCCESS) { |
| 167 » » if (hostname != NULL) { |
| 168 » » » tm->thread_data[thread_num].hostname = NULL; |
| 169 » » » free(hostname); |
| 170 » » } |
| 171 » » close(socket); |
| 172 » } |
| 173 » return rc; |
151 } | 174 } |
152 | 175 |
153 /* Since we don't want any of the worker threads to catch any signals, we must m
ask off any | 176 /* Since we don't want any of the worker threads to catch any signals, we must m
ask off any |
154 * potential signals here after creating the threads. If any of the created thr
eads catch a signal, | 177 * potential signals here after creating the threads. If any of the created thr
eads catch a signal, |
155 * they'd eventually call join on themselves, causing a deadlock. | 178 * they'd eventually call join on themselves, causing a deadlock. |
156 */ | 179 */ |
157 void | 180 void |
158 thread_signal_init() | 181 thread_signal_init() |
159 { | 182 { |
160 sigset_t thread_sigmask; | 183 sigset_t thread_sigmask; |
161 int rc; | 184 int rc; |
162 | 185 |
163 if ((rc = sigfillset(&thread_sigmask))) { | 186 if ((rc = sigfillset(&thread_sigmask))) { |
164 LogError("sigfillset failed: error=%d: %s", rc, strerror(rc)); | 187 LogError("sigfillset failed: error=%d: %s", rc, strerror(rc)); |
165 » » LogError("worker thread %zd is exiting prematurely", THREAD_ID); | 188 » » LogError("worker thread %ld is exiting prematurely", THREAD_ID); |
166 THREAD_EXIT(NULL); | 189 THREAD_EXIT(NULL); |
167 } | 190 } |
168 | 191 |
169 if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) { | 192 if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) { |
170 LogError("Setting thread sigmask failed: error=%d: %s", rc, stre
rror(rc)); | 193 LogError("Setting thread sigmask failed: error=%d: %s", rc, stre
rror(rc)); |
171 » » LogError("worker thread %zd is exiting prematurely", THREAD_ID); | 194 » » LogError("worker thread %ld is exiting prematurely", THREAD_ID); |
172 THREAD_EXIT(NULL); | 195 THREAD_EXIT(NULL); |
173 } | 196 } |
174 } | 197 } |
175 #if 0 | 198 #if 0 |
176 void * | 199 void * |
177 tcsd_thread_run(void *v) | 200 tcsd_thread_run(void *v) |
178 { | 201 { |
179 struct tcsd_thread_data *data = (struct tcsd_thread_data *)v; | 202 struct tcsd_thread_data *data = (struct tcsd_thread_data *)v; |
180 BYTE buffer[TCSD_TXBUF_SIZE]; | 203 BYTE buffer[TCSD_TXBUF_SIZE]; |
181 struct tcsd_packet_hdr *ret_buf = NULL; | 204 struct tcsd_packet_hdr *ret_buf = NULL; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 TCS_CloseContext_Internal(data->context); | 306 TCS_CloseContext_Internal(data->context); |
284 data->context = NULL_TCS_HANDLE; | 307 data->context = NULL_TCS_HANDLE; |
285 } | 308 } |
286 | 309 |
287 #ifndef TCSD_SINGLE_THREAD_DEBUG | 310 #ifndef TCSD_SINGLE_THREAD_DEBUG |
288 MUTEX_LOCK(tm->lock); | 311 MUTEX_LOCK(tm->lock); |
289 tm->num_active_threads--; | 312 tm->num_active_threads--; |
290 /* if we're not in shutdown mode, then nobody is waiting to join this th
read, so | 313 /* if we're not in shutdown mode, then nobody is waiting to join this th
read, so |
291 * detach it so that its resources are free at THREAD_EXIT() time. */ | 314 * detach it so that its resources are free at THREAD_EXIT() time. */ |
292 if (!tm->shutdown) { | 315 if (!tm->shutdown) { |
293 » » if ((rc = THREAD_DETACH(data->thread_id))) { | 316 » » if ((rc = THREAD_DETACH(*(data->thread_id)))) { |
294 LogError("Thread detach failed (errno %d)." | 317 LogError("Thread detach failed (errno %d)." |
295 " Resources may not be properly released.", rc)
; | 318 " Resources may not be properly released.", rc)
; |
296 } | 319 } |
297 } | 320 } |
298 free(data->hostname); | 321 free(data->hostname); |
299 data->hostname = NULL; | 322 data->hostname = NULL; |
300 data->thread_id = THREAD_NULL; | 323 data->thread_id = THREAD_NULL; |
301 MUTEX_UNLOCK(tm->lock); | 324 MUTEX_UNLOCK(tm->lock); |
302 THREAD_EXIT(NULL); | 325 THREAD_EXIT(NULL); |
303 #else | 326 #else |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 LoadBlob_UINT32(&offset, result, data->comm.buf); | 405 LoadBlob_UINT32(&offset, result, data->comm.buf); |
383 } | 406 } |
384 send_size = Decode_UINT32(data->comm.buf); | 407 send_size = Decode_UINT32(data->comm.buf); |
385 LogDebug("Sending 0x%X bytes back", send_size); | 408 LogDebug("Sending 0x%X bytes back", send_size); |
386 send_size = send_to_socket(data->sock, data->comm.buf, send_size
); | 409 send_size = send_to_socket(data->sock, data->comm.buf, send_size
); |
387 if (send_size < 0) | 410 if (send_size < 0) |
388 break; | 411 break; |
389 | 412 |
390 /* check for shutdown */ | 413 /* check for shutdown */ |
391 if (tm->shutdown) { | 414 if (tm->shutdown) { |
392 » » » LogDebug("Thread %zd exiting via shutdown signal!", THRE
AD_ID); | 415 » » » LogDebug("Thread %ld exiting via shutdown signal!", THRE
AD_ID); |
393 break; | 416 break; |
394 } | 417 } |
395 } | 418 } |
396 | 419 |
397 LogDebug("Thread exiting."); | 420 LogDebug("Thread exiting."); |
398 | 421 |
399 /* Closing connection to TSP */ | 422 /* Closing connection to TSP */ |
400 close(data->sock); | 423 close(data->sock); |
401 data->sock = -1; | 424 data->sock = -1; |
402 free(data->comm.buf); | 425 free(data->comm.buf); |
403 data->comm.buf = NULL; | 426 data->comm.buf = NULL; |
404 data->comm.buf_size = -1; | 427 data->comm.buf_size = -1; |
405 /* If the connection was not shut down cleanly, free TCS resources here
*/ | 428 /* If the connection was not shut down cleanly, free TCS resources here
*/ |
406 if (data->context != NULL_TCS_HANDLE) { | 429 if (data->context != NULL_TCS_HANDLE) { |
407 TCS_CloseContext_Internal(data->context); | 430 TCS_CloseContext_Internal(data->context); |
408 data->context = NULL_TCS_HANDLE; | 431 data->context = NULL_TCS_HANDLE; |
409 } | 432 } |
| 433 if(data->hostname != NULL) { |
| 434 free(data->hostname); |
| 435 data->hostname = NULL; |
| 436 } |
410 | 437 |
411 #ifndef TCSD_SINGLE_THREAD_DEBUG | 438 #ifndef TCSD_SINGLE_THREAD_DEBUG |
412 pthread_mutex_lock(&(tm->lock)); | 439 pthread_mutex_lock(&(tm->lock)); |
413 tm->num_active_threads--; | 440 tm->num_active_threads--; |
414 /* if we're not in shutdown mode, then nobody is waiting to join this th
read, so | 441 /* if we're not in shutdown mode, then nobody is waiting to join this th
read, so |
415 * detach it so that its resources are free at pthread_exit() time. */ | 442 * detach it so that its resources are free at pthread_exit() time. */ |
416 if (!tm->shutdown) { | 443 if (!tm->shutdown) { |
417 » » if ((rc = pthread_detach(data->thread_id))) { | 444 » » if ((rc = pthread_detach(*(data->thread_id)))) { |
418 LogError("pthread_detach failed (errno %d)." | 445 LogError("pthread_detach failed (errno %d)." |
419 " Resources may not be properly released.", rc)
; | 446 " Resources may not be properly released.", rc)
; |
420 } | 447 } |
421 } | 448 } |
422 » free(data->hostname); | 449 » free(data->thread_id); |
423 » data->hostname = NULL; | 450 » data->thread_id = THREAD_NULL; |
424 » data->thread_id = (pthread_t)0; | |
425 pthread_mutex_unlock(&(tm->lock)); | 451 pthread_mutex_unlock(&(tm->lock)); |
426 pthread_exit(NULL); | 452 pthread_exit(NULL); |
427 #else | 453 #else |
428 return NULL; | 454 return NULL; |
429 #endif | 455 #endif |
430 } | 456 } |
431 | 457 |
432 #endif | 458 #endif |
OLD | NEW |