88
90
#ifndef TCSD_SINGLE_THREAD_DEBUG
90
pthread_attr_t tcsd_thread_attr;
92
THREAD_ATTR_DECLARE(tcsd_thread_attr);
92
94
/* init the thread attribute */
93
if ((rc = pthread_attr_init(&tcsd_thread_attr))) {
94
LogError("pthread_attr_init failed: error=%d: %s", rc, strerror(rc));
95
if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) {
96
LogError("Initializing thread attribute failed: error=%d: %s", rc, strerror(rc));
95
97
return TCSERR(TSS_E_INTERNAL_ERROR);
97
99
/* make all threads joinable */
98
if ((rc = pthread_attr_setdetachstate(&tcsd_thread_attr, PTHREAD_CREATE_JOINABLE))) {
99
LogError("pthread_attr_init failed: error=%d: %s", rc, strerror(rc));
100
if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) {
101
LogError("Making thread attribute joinable failed: error=%d: %s", rc, strerror(rc));
100
102
return TCSERR(TSS_E_INTERNAL_ERROR);
103
pthread_mutex_lock(&(tm->lock));
105
MUTEX_LOCK(tm->lock);
105
107
if (tm->num_active_threads == tm->max_threads) {
132
134
#ifdef TCSD_SINGLE_THREAD_DEBUG
133
135
(void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num])));
135
if ((rc = pthread_create(&(tm->thread_data[thread_num].thread_id),
137
if ((rc = THREAD_CREATE(&(tm->thread_data[thread_num].thread_id),
136
138
&tcsd_thread_attr,
138
140
(void *)(&(tm->thread_data[thread_num]))))) {
139
LogError("pthread_create() failed: %d", rc);
140
pthread_mutex_unlock(&(tm->lock));
141
LogError("Thread create failed: %d", rc);
142
MUTEX_UNLOCK(tm->lock);
141
143
return TCSERR(TSS_E_INTERNAL_ERROR);
144
146
tm->num_active_threads++;
146
pthread_mutex_unlock(&(tm->lock));
148
MUTEX_UNLOCK(tm->lock);
148
150
return TSS_SUCCESS;
151
/* since we don't want any of the worker threads to catch any signals,
152
* we must mask off any potential signals here after creating the threads. If any of
153
* the created threads catch a signal, they'd eventually call pthread_join() on
154
* themselves, causing a deadlock.
153
/* Since we don't want any of the worker threads to catch any signals, we must mask off any
154
* potential signals here after creating the threads. If any of the created threads catch a signal,
155
* they'd eventually call join on themselves, causing a deadlock.
157
158
thread_signal_init()
162
163
if ((rc = sigfillset(&thread_sigmask))) {
163
164
LogError("sigfillset failed: error=%d: %s", rc, strerror(rc));
164
LogError("worker thread %u is exiting prematurely", (unsigned int)pthread_self());
168
if ((rc = pthread_sigmask(SIG_BLOCK, &thread_sigmask, NULL))) {
169
LogError("pthread_sigmask failed: error=%d: %s", rc, strerror(rc));
170
LogError("worker thread %u is exiting prematurely", (unsigned int)pthread_self());
165
LogError("worker thread %zd is exiting prematurely", THREAD_ID);
169
if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) {
170
LogError("Setting thread sigmask failed: error=%d: %s", rc, strerror(rc));
171
LogError("worker thread %zd is exiting prematurely", THREAD_ID);
177
tcsd_thread_run(void *v)
179
struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
180
BYTE buffer[TCSD_TXBUF_SIZE];
181
struct tcsd_packet_hdr *ret_buf = NULL;
183
int sizeToSend, sent_total, sent;
185
#ifndef TCSD_SINGLE_THREAD_DEBUG
188
thread_signal_init();
191
if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
192
LogError("Failed Receive: %s", strerror(errno));
195
LogDebug("Rx'd packet");
201
if (data->buf_size > TCSD_TXBUF_SIZE) {
202
LogError("Packet received from socket %d was too large (%u bytes)",
203
data->sock, data->buf_size);
205
} else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) {
206
LogError("Packet received from socket %d was too small (%u bytes)",
207
data->sock, data->buf_size);
211
if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) {
212
/* something internal to the TCSD went wrong in preparing the packet
213
* to return to the TSP. Use our already allocated buffer to return a
214
* TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
215
* these LoadBlob's are done in getTCSDPacket().
219
LoadBlob_UINT32(&offset, result, buffer);
220
/* load packet size */
221
LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
223
LoadBlob_UINT16(&offset, 0, buffer);
225
sizeToSend = sizeof(struct tcsd_packet_hdr);
226
LogDebug("Sending 0x%X bytes back", sizeToSend);
228
while (sent_total < sizeToSend) {
229
if ((sent = send(data->sock,
230
&data->buf[sent_total],
231
sizeToSend - sent_total, 0)) < 0) {
232
LogError("Packet send to TSP failed: send: %s. Thread exiting.",
239
sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));
241
LogDebug("Sending 0x%X bytes back", sizeToSend);
243
while (sent_total < sizeToSend) {
244
if ((sent = send(data->sock,
245
&(((BYTE *)ret_buf)[sent_total]),
246
sizeToSend - sent_total, 0)) < 0) {
247
LogError("response to TSP failed: send: %s. Thread exiting.",
260
LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
264
/* receive the next packet */
265
if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
266
LogError("TSP has closed its connection: %s. Thread exiting.",
269
} else if (data->buf_size == 0) {
270
LogDebug("The TSP has closed the socket's connection. Thread exiting.");
276
/* Closing connection to TSP */
281
/* If the connection was not shut down cleanly, free TCS resources here */
282
if (data->context != NULL_TCS_HANDLE) {
283
TCS_CloseContext_Internal(data->context);
284
data->context = NULL_TCS_HANDLE;
287
#ifndef TCSD_SINGLE_THREAD_DEBUG
288
MUTEX_LOCK(tm->lock);
289
tm->num_active_threads--;
290
/* if we're not in shutdown mode, then nobody is waiting to join this thread, so
291
* detach it so that its resources are free at THREAD_EXIT() time. */
293
if ((rc = THREAD_DETACH(data->thread_id))) {
294
LogError("Thread detach failed (errno %d)."
295
" Resources may not be properly released.", rc);
298
free(data->hostname);
299
data->hostname = NULL;
300
data->thread_id = THREAD_NULL;
301
MUTEX_UNLOCK(tm->lock);
176
309
tcsd_thread_run(void *v)
221
354
/* get the rest of the packet */
222
recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
355
recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
223
356
if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
225
358
LogDebug("Rx'd packet");
227
360
/* create a platform version of the tcsd header */
229
UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf, NULL);
230
UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf, NULL);
231
UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf, NULL);
232
UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf, NULL);
233
UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf, NULL);
234
UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf, NULL);
235
UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf, NULL);
362
UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf);
363
UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf);
364
UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf);
365
UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf);
366
UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf);
367
UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf);
368
UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf);
237
370
if ((result = getTCSDPacket(data)) != TSS_SUCCESS) {
238
371
/* something internal to the TCSD went wrong in preparing the packet