Hi alli will post in this mail a set of patches which are bug fixes or improvements for the tcsd code.
The first patch (tcsd_thread_mutex_init_patch.diff) adds a call to mutex initialization function in "tcsd_threads_init" for the "lock" field of the allocated tcsd_thread_mgr structure.
The second patch (tcsd_threads_leaks_patch.diff) does a better cleanup if an error happens in the function "tcsd_thread_create". In particular the "hostname" string may not be freed and the socket is not closed if the functions THREAD_ATTR_INIT, THREAD_ATTR_SETJOINABLE or THREAD_CREATE return an error. Further, "data->hostname" in the function "tcsd_thread_run" is freed even if "TCSD_SINGLE_THREAD_DEBUG" is defined since the pointer assignment, in the function "tcsd_thread_create", is made in either cases.
The last patch (pthread_portability_patch.diff) minimizes the effort to port TrouSerS on Windows (please refer to previous mail sent by Giovanni Cabiddu). The problem is that while in Linux the type "pthread_t" is defined as "unsigned long int", in Windows it corresponds to a structure. As consequence it is not possible for example, when compiling the code for Windows, to compare the field "thread_id" of " tcsd_thread_data" with THREAD_NULL. (which is equal to 0). In this patch i modified the definition of the tcsd_thread_data structure, by making the field "thread_id" as pointer and i inserted the allocation/deallocation of the data (the proper size is given by THREAD_TYPE). In this way, finding an available slot in the array of "tcsd_thread_data" structure will consist in verifying that "thread_id" is NULL.
diff --git a/src/include/tcsd.h b/src/include/tcsd.h
index 711ea10..1f72e05 100644
--- a/src/include/tcsd.h
+++ b/src/include/tcsd.h
@@ -134,7 +134,7 @@ struct tcsd_thread_data
{
int sock;
UINT32 context;
- THREAD_TYPE thread_id;
+ THREAD_TYPE *thread_id;
char *hostname;
struct tcsd_comm_data comm;
};
diff --git a/src/include/threads.h b/src/include/threads.h
index 8cdd8dc..3c57144 100644
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -31,7 +31,7 @@
#define COND_SIGNAL(c) pthread_cond_signal(c)
/* thread abstractions */
-#define THREAD_ID ((size_t)pthread_self())
+#define THREAD_ID ((THREAD_TYPE)pthread_self())
#define THREAD_TYPE pthread_t
#define THREAD_JOIN pthread_join
#define THREAD_DETACH pthread_detach
@@ -41,7 +41,7 @@
#define THREAD_EXIT pthread_exit
#define THREAD_CREATE(a,b,c,d) pthread_create(a,b,c,d)
#define THREAD_SET_SIGNAL_MASK pthread_sigmask
-#define THREAD_NULL (THREAD_TYPE)0
+#define THREAD_NULL (THREAD_TYPE *)0
#else
diff --git a/src/tcsd/tcsd_threads.c b/src/tcsd/tcsd_threads.c
index bde025a..9a284dc 100644
--- a/src/tcsd/tcsd_threads.c
+++ b/src/tcsd/tcsd_threads.c
@@ -45,7 +45,7 @@ tcsd_threads_final()
/* wait for all currently running threads to exit */
for (i = 0; i < tm->max_threads; i++) {
if (tm->thread_data[i].thread_id != THREAD_NULL) {
- if ((rc = THREAD_JOIN(tm->thread_data[i].thread_id, NULL))) {
+ if ((rc = THREAD_JOIN(*(tm->thread_data[i].thread_id), NULL))) {
LogError("Thread join failed: error: %d", rc);
}
}
@@ -138,7 +138,14 @@ tcsd_thread_create(int socket, char *hostname)
#ifdef TCSD_SINGLE_THREAD_DEBUG
(void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num])));
#else
- if ((rc = THREAD_CREATE(&(tm->thread_data[thread_num].thread_id),
+ tm->thread_data[thread_num].thread_id = calloc(1, sizeof(THREAD_TYPE));
+ if (tm->thread_data[thread_num].thread_id == NULL) {
+ rc = TCSERR(TSS_E_OUTOFMEMORY);
+ LogError("malloc of %zd bytes failed.", sizeof(THREAD_TYPE));
+ goto out_unlock;
+ }
+
+ if ((rc = THREAD_CREATE(tm->thread_data[thread_num].thread_id,
&tcsd_thread_attr,
tcsd_thread_run,
(void *)(&(tm->thread_data[thread_num]))))) {
@@ -432,12 +439,13 @@ tcsd_thread_run(void *v)
/* if we're not in shutdown mode, then nobody is waiting to join this thread, so
* detach it so that its resources are free at pthread_exit() time. */
if (!tm->shutdown) {
- if ((rc = pthread_detach(data->thread_id))) {
+ if ((rc = pthread_detach(*(data->thread_id)))) {
LogError("pthread_detach failed (errno %d)."
" Resources may not be properly released.", rc);
}
}
- data->thread_id = (pthread_t)0;
+ free(data->thread_id);
+ data->thread_id = THREAD_NULL;
pthread_mutex_unlock(&(tm->lock));
pthread_exit(NULL);
#else
diff --git a/src/tcsd/tcsd_threads.c b/src/tcsd/tcsd_threads.c
index e6c8d6a..e5aacf3 100644
--- a/src/tcsd/tcsd_threads.c
+++ b/src/tcsd/tcsd_threads.c
@@ -66,6 +66,8 @@ tcsd_threads_init(void)
LogError("malloc of %zd bytes failed.", sizeof(struct tcsd_thread_mgr));
return TCSERR(TSS_E_OUTOFMEMORY);
}
+ /* initialize mutex */
+ MUTEX_INIT(tm->lock);
/* set the max threads variable from config */
tm->max_threads = tcsd_options.num_threads;
diff --git a/src/tcsd/tcsd_threads.c b/src/tcsd/tcsd_threads.c
index e6c8d6a..bde025a 100644
--- a/src/tcsd/tcsd_threads.c
+++ b/src/tcsd/tcsd_threads.c
@@ -87,25 +87,26 @@ TSS_RESULT
tcsd_thread_create(int socket, char *hostname)
{
UINT32 thread_num;
+ int rc = TCS_SUCCESS;
#ifndef TCSD_SINGLE_THREAD_DEBUG
- int rc;
THREAD_ATTR_DECLARE(tcsd_thread_attr);
/* init the thread attribute */
if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) {
LogError("Initializing thread attribute failed: error=%d: %s", rc, strerror(rc));
- return TCSERR(TSS_E_INTERNAL_ERROR);
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out;
}
/* make all threads joinable */
if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) {
LogError("Making thread attribute joinable failed: error=%d: %s", rc, strerror(rc));
- return TCSERR(TSS_E_INTERNAL_ERROR);
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out;
}
MUTEX_LOCK(tm->lock);
#endif
if (tm->num_active_threads == tm->max_threads) {
- close(socket);
if (hostname != NULL) {
LogError("max number of connections reached (%d), new connection"
" from %s refused.", tm->max_threads, hostname);
@@ -113,9 +114,12 @@ tcsd_thread_create(int socket, char *hostname)
LogError("max number of connections reached (%d), new connection"
" refused.", tm->max_threads);
}
- free(hostname);
- MUTEX_UNLOCK(tm->lock);
- return TCSERR(TSS_E_CONNECTION_FAILED);
+ rc = TCSERR(TSS_E_CONNECTION_FAILED);
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ goto out_unlock;
+#else
+ goto out;
+#endif
}
/* search for an open slot to store the thread data in */
@@ -139,15 +143,25 @@ tcsd_thread_create(int socket, char *hostname)
tcsd_thread_run,
(void *)(&(tm->thread_data[thread_num]))))) {
LogError("Thread create failed: %d", rc);
- MUTEX_UNLOCK(tm->lock);
- return TCSERR(TSS_E_INTERNAL_ERROR);
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out_unlock;
}
tm->num_active_threads++;
+out_unlock:
MUTEX_UNLOCK(tm->lock);
#endif
- return TSS_SUCCESS;
+out:
+ /* cleanup in case of error */
+ if (rc != TCS_SUCCESS) {
+ if (hostname != NULL) {
+ tm->thread_data[thread_num].hostname = NULL;
+ free(hostname);
+ }
+ close(socket);
+ }
+ return rc;
}
/* Since we don't want any of the worker threads to catch any signals, we must mask off any
@@ -407,6 +421,10 @@ tcsd_thread_run(void *v)
TCS_CloseContext_Internal(data->context);
data->context = NULL_TCS_HANDLE;
}
+ if(data->hostname != NULL) {
+ free(data->hostname);
+ data->hostname = NULL;
+ }
#ifndef TCSD_SINGLE_THREAD_DEBUG
pthread_mutex_lock(&(tm->lock));
@@ -419,8 +437,6 @@ tcsd_thread_run(void *v)
" Resources may not be properly released.", rc);
}
}
- free(data->hostname);
- data->hostname = NULL;
data->thread_id = (pthread_t)0;
pthread_mutex_unlock(&(tm->lock));
pthread_exit(NULL);
smime.p7s
Description: S/MIME Cryptographic Signature
------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev
_______________________________________________ TrouSerS-tech mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/trousers-tech
