| 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 |