1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-06-23 06:25:25 +00:00

Plug small memory leak when a thread exits.

Allow new threads to inherit scheduling policy.
Use long instead of int in thread_exit, thanks to the ports maintainers for
the heads up.

svn path=/trunk/thread/; revision=5179
This commit is contained in:
Karl Heyes 2003-07-27 18:19:31 +00:00
parent 909455fd42
commit 68bf65ca25
2 changed files with 58 additions and 70 deletions

View File

@ -77,9 +77,6 @@ typedef struct thread_start_tag {
void *(*start_routine)(void *); void *(*start_routine)(void *);
void *arg; void *arg;
/* whether to create the threaded in detached state */
int detached;
/* the other stuff we need to make sure this thread is inserted into /* the other stuff we need to make sure this thread is inserted into
** the thread tree ** the thread tree
*/ */
@ -126,7 +123,6 @@ static int _free_mutex(void *key);
static int _compare_threads(void *compare_arg, void *a, void *b); static int _compare_threads(void *compare_arg, void *a, void *b);
static int _free_thread(void *key); static int _free_thread(void *key);
static int _free_thread_if_detached(void *key);
/* mutex fuctions */ /* mutex fuctions */
static void _mutex_create(mutex_t *mutex); static void _mutex_create(mutex_t *mutex);
@ -267,44 +263,58 @@ static void _catch_signals(void)
thread_type *thread_create_c(char *name, void *(*start_routine)(void *), thread_type *thread_create_c(char *name, void *(*start_routine)(void *),
void *arg, int detached, int line, char *file) void *arg, int detached, int line, char *file)
{ {
int created; int ok = 1;
thread_type *thread; thread_type *thread = NULL;
thread_start_t *start; thread_start_t *start = NULL;
pthread_attr_t attr;
thread = (thread_type *)malloc(sizeof(thread_type)); thread = (thread_type *)calloc(1, sizeof(thread_type));
start = (thread_start_t *)malloc(sizeof(thread_start_t)); do {
thread->line = line; if (thread == NULL)
thread->file = strdup(file); break;
start = (thread_start_t *)calloc(1, sizeof(thread_start_t));
if (start == NULL)
break;
if (pthread_attr_init (&attr) < 0)
break;
_mutex_lock(&_threadtree_mutex); thread->line = line;
thread->thread_id = _next_thread_id++; thread->file = strdup(file);
_mutex_unlock(&_threadtree_mutex);
thread->name = strdup(name); _mutex_lock (&_threadtree_mutex);
thread->create_time = time(NULL); thread->thread_id = _next_thread_id++;
thread->detached = 0; _mutex_unlock (&_threadtree_mutex);
start->start_routine = start_routine; thread->name = strdup(name);
start->arg = arg; thread->create_time = time(NULL);
start->thread = thread;
start->detached = detached;
created = 0; start->start_routine = start_routine;
if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0) start->arg = arg;
created = 1; start->thread = thread;
#ifdef THREAD_DEBUG
else
LOG_ERROR("Could not create new thread");
#endif
if (created == 0) { pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED);
#ifdef THREAD_DEBUG if (detached)
LOG_ERROR("System won't let me create more threads, giving up"); {
#endif pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
return NULL; thread->detached = 1;
}
if (pthread_create (&thread->sys_thread, &attr, _start_routine, start) == 0)
{
pthread_attr_destroy (&attr);
return thread;
}
else
pthread_attr_destroy (&attr);
} }
while (0);
return thread; #ifdef THREAD_DEBUG
LOG_ERROR("Could not create new thread %s", name);
#endif
if (start) free (start);
if (thread) free (thread);
return NULL;
} }
/* _mutex_create /* _mutex_create
@ -547,7 +557,7 @@ void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file)
pthread_rwlock_unlock(&rwlock->sys_rwlock); pthread_rwlock_unlock(&rwlock->sys_rwlock);
} }
void thread_exit_c(int val, int line, char *file) void thread_exit_c(long val, int line, char *file)
{ {
thread_type *th = thread_self(); thread_type *th = thread_self();
@ -574,17 +584,18 @@ void thread_exit_c(int val, int line, char *file)
} }
#endif #endif
if (th) { if (th && th->detached)
{
#ifdef THREAD_DEBUG #ifdef THREAD_DEBUG
LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line); LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
#endif #endif
_mutex_lock(&_threadtree_mutex); _mutex_lock(&_threadtree_mutex);
avl_delete(_threadtree, th, _free_thread_if_detached); avl_delete(_threadtree, th, _free_thread);
_mutex_unlock(&_threadtree_mutex); _mutex_unlock(&_threadtree_mutex);
} }
pthread_exit((void *)val); pthread_exit ((void*)val);
} }
/* sleep for a number of microseconds */ /* sleep for a number of microseconds */
@ -625,12 +636,9 @@ static void *_start_routine(void *arg)
void *(*start_routine)(void *) = start->start_routine; void *(*start_routine)(void *) = start->start_routine;
void *real_arg = start->arg; void *real_arg = start->arg;
thread_type *thread = start->thread; thread_type *thread = start->thread;
int detach = start->detached;
_block_signals(); _block_signals();
free(start);
/* insert thread into thread tree here */ /* insert thread into thread tree here */
_mutex_lock(&_threadtree_mutex); _mutex_lock(&_threadtree_mutex);
thread->sys_thread = pthread_self(); thread->sys_thread = pthread_self();
@ -641,20 +649,17 @@ static void *_start_routine(void *arg)
LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line); LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
#endif #endif
if (detach) { pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
pthread_detach(thread->sys_thread); free (start);
thread->detached = 1;
}
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/* call the real start_routine and start the thread
** this should never exit!
*/
(start_routine)(real_arg); (start_routine)(real_arg);
#ifdef THREAD_DEBUG if (thread->detached)
LOG_WARN("Thread x should never exit from here!!!"); {
#endif _mutex_lock (&_threadtree_mutex);
avl_delete (_threadtree, thread, _free_thread);
_mutex_unlock (&_threadtree_mutex);
}
return NULL; return NULL;
} }
@ -805,21 +810,4 @@ static int _free_thread(void *key)
return 1; return 1;
} }
static int _free_thread_if_detached(void *key)
{
thread_type *t = key;
if(t->detached)
return _free_thread(key);
return 1;
}

View File

@ -162,7 +162,7 @@ void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, char *file);
void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, char *file); void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, char *file);
void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file); void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file);
void thread_rwlock_destroy(rwlock_t *rwlock); void thread_rwlock_destroy(rwlock_t *rwlock);
void thread_exit_c(int val, int line, char *file); void thread_exit_c(long val, int line, char *file);
/* sleeping */ /* sleeping */
void thread_sleep(unsigned long len); void thread_sleep(unsigned long len);