8 libogg2-zerocopy:1.17.0.2
9 branch-beta2-rewrite:1.5.0.2
17 date 2003.07.14.02.17.52; author brendan; state Exp;
22 date 2003.03.15.02.10.18; author msmith; state Exp;
27 date 2003.03.12.03.59.55; author karl; state Exp;
32 date 2003.03.09.22.56.46; author karl; state Exp;
37 date 2003.03.08.16.05.38; author karl; state Exp;
42 date 2003.03.04.15.31.34; author msmith; state Exp;
47 date 2003.01.17.09.01.04; author msmith; state Exp;
52 date 2002.12.29.09.55.50; author msmith; state Exp;
57 date 2002.11.22.13.00.44; author msmith; state Exp;
62 date 2002.09.24.07.09.08; author msmith; state Exp;
67 date 2002.08.16.14.23.17; author msmith; state Exp;
72 date 2002.08.13.01.08.15; author msmith; state Exp;
77 date 2002.08.10.03.22.44; author msmith; state Exp;
82 date 2002.08.09.06.52.07; author msmith; state Exp;
87 date 2002.08.05.14.48.03; author msmith; state Exp;
92 date 2002.08.03.08.14.56; author msmith; state Exp;
97 date 2002.04.30.06.50.47; author msmith; state Exp;
102 date 2002.03.05.23.59.38; author jack; state Exp;
107 date 2002.02.08.03.51.19; author jack; state Exp;
112 date 2002.02.07.01.04.09; author jack; state Exp;
117 date 2001.10.21.02.04.27; author jack; state Exp;
122 date 2001.10.20.22.27.52; author jack; state Exp;
127 date 2001.10.20.05.35.30; author jack; state Exp;
132 date 2001.10.20.03.39.10; author jack; state Exp;
137 date 2001.09.10.02.26.33; author jack; state Exp;
143 date 2001.09.10.02.26.33; author jack; state Exp;
154 @Assign LGP to thread module
157 @/* threads.c: Thread Abstraction Functions
159 * Copyright (c) 1999, 2000 the icecast team <team@@icecast.org>
161 * This library is free software; you can redistribute it and/or
162 * modify it under the terms of the GNU Library General Public
163 * License as published by the Free Software Foundation; either
164 * version 2 of the License, or (at your option) any later version.
166 * This library is distributed in the hope that it will be useful,
167 * but WITHOUT ANY WARRANTY; without even the implied warranty of
168 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
169 * Library General Public License for more details.
171 * You should have received a copy of the GNU Library General Public
172 * License along with this library; if not, write to the Free
173 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
185 #include <sys/types.h>
191 #include <sys/time.h>
195 #include <implement.h>
200 #include <thread/thread.h>
207 #define __FUNCTION__ __FILE__
211 #define CATMODULE "thread"
212 #define LOG_ERROR(y) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y)
213 #define LOG_ERROR3(y, z1, z2, z3) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y, z1, z2, z3)
214 #define LOG_ERROR7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 1, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7)
216 #define LOG_WARN(y) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y)
217 #define LOG_WARN3(y, z1, z2, z3) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3)
218 #define LOG_WARN5(y, z1, z2, z3, z4, z5) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5)
219 #define LOG_WARN7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 2, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7)
221 #define LOG_INFO(y) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y)
222 #define LOG_INFO4(y, z1, z2, z3, z4) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4)
223 #define LOG_INFO5(y, z1, z2, z3, z4, z5) log_write(_logid, 3, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5)
225 #define LOG_DEBUG(y) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y)
226 #define LOG_DEBUG2(y, z1, z2) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y, z1, z2)
227 #define LOG_DEBUG5(y, z1, z2, z3, z4, z5) log_write(_logid, 4, CATMODULE "/", __FUNCTION__, y, z1, z2, z3, z4, z5)
230 /* thread starting structure */
231 typedef struct thread_start_tag {
232 /* the real start routine and arg */
233 void *(*start_routine)(void *);
236 /* whether to create the threaded in detached state */
239 /* the other stuff we need to make sure this thread is inserted into
243 pthread_t sys_thread;
246 static long _next_thread_id = 0;
247 static int _initialized = 0;
248 static avl_tree *_threadtree = NULL;
251 static mutex_t _threadtree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1,
252 PTHREAD_MUTEX_INITIALIZER};
254 static mutex_t _threadtree_mutex = { PTHREAD_MUTEX_INITIALIZER };
260 static int _logid = -1;
261 static long _next_mutex_id = 0;
263 static avl_tree *_mutextree = NULL;
264 static mutex_t _mutextree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1,
265 PTHREAD_MUTEX_INITIALIZER};
269 static mutex_t _library_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1,
270 PTHREAD_MUTEX_INITIALIZER};
272 static mutex_t _library_mutex = { PTHREAD_MUTEX_INITIALIZER };
275 /* INTERNAL FUNCTIONS */
277 /* avl tree functions */
279 static int _compare_mutexes(void *compare_arg, void *a, void *b);
280 static int _free_mutex(void *key);
283 static int _compare_threads(void *compare_arg, void *a, void *b);
284 static int _free_thread(void *key);
285 static int _free_thread_if_detached(void *key);
288 static void _mutex_create(mutex_t *mutex);
289 static void _mutex_lock(mutex_t *mutex);
290 static void _mutex_unlock(mutex_t *mutex);
292 /* misc thread stuff */
293 static void *_start_routine(void *arg);
294 static void _catch_signals(void);
295 static void _block_signals(void);
297 /* LIBRARY INITIALIZATION */
299 void thread_initialize(void)
307 _logid = log_open("thread.log");
308 log_set_level(_logid, THREAD_DEBUG);
312 /* create all the internal mutexes, and initialize the mutex tree */
314 _mutextree = avl_tree_new(_compare_mutexes, NULL);
316 /* we have to create this one by hand, because there's no
317 ** mutextree_mutex to lock yet!
319 _mutex_create(&_mutextree_mutex);
321 _mutextree_mutex.mutex_id = _next_mutex_id++;
322 avl_insert(_mutextree, (void *)&_mutextree_mutex);
325 thread_mutex_create(&_threadtree_mutex);
326 thread_mutex_create(&_library_mutex);
328 /* initialize the thread tree and insert the main thread */
330 _threadtree = avl_tree_new(_compare_threads, NULL);
332 thread = (thread_type *)malloc(sizeof(thread_type));
334 thread->thread_id = _next_thread_id++;
336 thread->file = strdup("main.c");
337 thread->sys_thread = pthread_self();
338 thread->create_time = time(NULL);
339 thread->name = strdup("Main Thread");
341 avl_insert(_threadtree, (void *)thread);
348 void thread_shutdown(void)
350 if (_initialized == 1) {
351 thread_mutex_destroy(&_library_mutex);
352 thread_mutex_destroy(&_threadtree_mutex);
354 thread_mutex_destroy(&_mutextree_mutex);
356 avl_tree_free(_mutextree, _free_mutex);
358 avl_tree_free(_threadtree, _free_thread);
369 * Signals should be handled by the main thread, nowhere else.
370 * I'm using POSIX signal interface here, until someone tells me
371 * that I should use signal/sigset instead
373 * This function only valid for non-Win32
375 static void _block_signals(void)
382 /* These ones we want */
383 sigdelset(&ss, SIGKILL);
384 sigdelset(&ss, SIGSTOP);
385 sigdelset(&ss, SIGTERM);
386 sigdelset(&ss, SIGSEGV);
387 sigdelset(&ss, SIGBUS);
388 if (pthread_sigmask(SIG_BLOCK, &ss, NULL) != 0) {
390 LOG_ERROR("Pthread_sigmask() failed for blocking signals");
397 * Let the calling thread catch all the relevant signals
399 * This function only valid for non-Win32
401 static void _catch_signals(void)
408 /* These ones should only be accepted by the signal handling thread (main thread) */
409 sigaddset(&ss, SIGHUP);
410 sigaddset(&ss, SIGCHLD);
411 sigaddset(&ss, SIGINT);
412 sigaddset(&ss, SIGPIPE);
414 if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL) != 0) {
416 LOG_ERROR("pthread_sigmask() failed for catching signals!");
423 thread_type *thread_create_c(char *name, void *(*start_routine)(void *),
424 void *arg, int detached, int line, char *file)
428 thread_start_t *start;
430 thread = (thread_type *)malloc(sizeof(thread_type));
431 start = (thread_start_t *)malloc(sizeof(thread_start_t));
433 thread->file = strdup(file);
435 _mutex_lock(&_threadtree_mutex);
436 thread->thread_id = _next_thread_id++;
437 _mutex_unlock(&_threadtree_mutex);
439 thread->name = strdup(name);
440 thread->create_time = time(NULL);
441 thread->detached = 0;
443 start->start_routine = start_routine;
445 start->thread = thread;
446 start->detached = detached;
449 if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0)
453 LOG_ERROR("Could not create new thread");
458 LOG_ERROR("System won't let me create more threads, giving up");
470 static void _mutex_create(mutex_t *mutex)
473 mutex->thread_id = MUTEX_STATE_NEVERLOCKED;
477 pthread_mutex_init(&mutex->sys_mutex, NULL);
480 void thread_mutex_create_c(mutex_t *mutex, int line, char *file)
482 _mutex_create(mutex);
485 _mutex_lock(&_mutextree_mutex);
486 mutex->mutex_id = _next_mutex_id++;
487 avl_insert(_mutextree, (void *)mutex);
488 _mutex_unlock(&_mutextree_mutex);
492 void thread_mutex_destroy (mutex_t *mutex)
494 pthread_mutex_destroy(&mutex->sys_mutex);
497 _mutex_lock(&_mutextree_mutex);
498 avl_delete(_mutextree, mutex, _free_mutex);
499 _mutex_unlock(&_mutextree_mutex);
503 void thread_mutex_lock_c(mutex_t *mutex, int line, char *file)
506 thread_type *th = thread_self();
508 if (!th) LOG_WARN("No mt record for %u in lock [%s:%d]", thread_self(), file, line);
510 LOG_DEBUG5("Locking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
512 # ifdef CHECK_MUTEXES
513 /* Just a little sanity checking to make sure that we're locking
522 _mutex_lock(&_mutextree_mutex);
524 node = avl_get_first (_mutextree);
527 tmutex = (mutex_t *)node->key;
529 if (tmutex->mutex_id == mutex->mutex_id) {
530 if (tmutex->thread_id == th->thread_id) {
531 /* Deadlock, same thread can't lock the same mutex twice */
532 LOG_ERROR7("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]",
533 tmutex->thread_id, th->thread_id, mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);
535 _mutex_unlock(&_mutextree_mutex);
538 } else if (tmutex->thread_id == th->thread_id) {
539 /* Mutex locked by this thread (not this mutex) */
543 node = avl_get_next(node);
547 /* Has already got a mutex locked */
548 if (_multi_mutex.thread_id != th->thread_id) {
549 /* Tries to lock two mutexes, but has not got the double mutex, norty boy! */
550 LOG_WARN("(%d != %d) Thread %d [%s] tries to lock a second mutex [%s] in file %s line %d, without locking double mutex!",
551 _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);
555 _mutex_unlock(&_mutextree_mutex);
557 # endif /* CHECK_MUTEXES */
561 _mutex_lock(&_mutextree_mutex);
563 LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
566 mutex->thread_id = th->thread_id;
569 _mutex_unlock(&_mutextree_mutex);
572 #endif /* DEBUG_MUTEXES */
575 void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file)
578 thread_type *th = thread_self();
581 LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);
584 LOG_DEBUG5("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
588 # ifdef CHECK_MUTEXES
594 _mutex_lock(&_mutextree_mutex);
597 tmutex = (mutex_t *)node->key;
599 if (tmutex->mutex_id == mutex->mutex_id) {
600 if (tmutex->thread_id != th->thread_id) {
601 LOG_ERROR7("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id,
602 mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);
603 _mutex_unlock(&_mutextree_mutex);
606 } else if (tmutex->thread_id == th->thread_id) {
610 node = avl_get_next (node);
613 if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {
614 /* Don't have double mutex, has more than this mutex left */
616 LOG_WARN("(%d != %d) Thread %d [%s] tries to unlock a mutex [%s] in file %s line %d, without owning double mutex!",
617 _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);
620 _mutex_unlock(&_mutextree_mutex);
622 # endif /* CHECK_MUTEXES */
624 _mutex_unlock(mutex);
626 _mutex_lock(&_mutextree_mutex);
628 LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
630 if (mutex->thread_id == th->thread_id) {
631 mutex->thread_id = MUTEX_STATE_NOTLOCKED;
634 _mutex_unlock(&_mutextree_mutex);
636 _mutex_unlock(mutex);
637 #endif /* DEBUG_MUTEXES */
640 void thread_cond_create_c(cond_t *cond, int line, char *file)
642 pthread_cond_init(&cond->sys_cond, NULL);
643 pthread_mutex_init(&cond->cond_mutex, NULL);
646 void thread_cond_destroy(cond_t *cond)
648 pthread_mutex_destroy(&cond->cond_mutex);
649 pthread_cond_destroy(&cond->sys_cond);
652 void thread_cond_signal_c(cond_t *cond, int line, char *file)
654 pthread_cond_signal(&cond->sys_cond);
657 void thread_cond_broadcast_c(cond_t *cond, int line, char *file)
659 pthread_cond_broadcast(&cond->sys_cond);
662 void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file)
664 struct timespec time;
666 time.tv_sec = millis/1000;
667 time.tv_nsec = (millis - time.tv_sec*1000)*1000000;
669 pthread_mutex_lock(&cond->cond_mutex);
670 pthread_cond_timedwait(&cond->sys_cond, &cond->cond_mutex, &time);
671 pthread_mutex_unlock(&cond->cond_mutex);
674 void thread_cond_wait_c(cond_t *cond, int line, char *file)
676 pthread_mutex_lock(&cond->cond_mutex);
677 pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex);
678 pthread_mutex_unlock(&cond->cond_mutex);
681 void thread_rwlock_create_c(rwlock_t *rwlock, int line, char *file)
683 pthread_rwlock_init(&rwlock->sys_rwlock, NULL);
686 void thread_rwlock_destroy(rwlock_t *rwlock)
688 pthread_rwlock_destroy(&rwlock->sys_rwlock);
691 void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, char *file)
693 pthread_rwlock_rdlock(&rwlock->sys_rwlock);
696 void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, char *file)
698 pthread_rwlock_wrlock(&rwlock->sys_rwlock);
701 void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, char *file)
703 pthread_rwlock_unlock(&rwlock->sys_rwlock);
706 void thread_exit_c(int val, int line, char *file)
708 thread_type *th = thread_self();
710 #if defined(DEBUG_MUTEXES) && defined(CHECK_MUTEXES)
716 _mutex_lock(&_mutextree_mutex);
719 tmutex = (mutex_t *)node->key;
721 if (tmutex->thread_id == th->thread_id) {
722 LOG_WARN("Thread %d [%s] exiting in file %s line %d, without unlocking mutex [%s]",
723 th->thread_id, th->name, file, line, mutex_to_string(tmutex, name));
726 node = avl_get_next (node);
729 _mutex_unlock(&_mutextree_mutex);
735 LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
738 _mutex_lock(&_threadtree_mutex);
739 avl_delete(_threadtree, th, _free_thread_if_detached);
740 _mutex_unlock(&_threadtree_mutex);
743 pthread_exit((void *)val);
746 /* sleep for a number of microseconds */
747 void thread_sleep(unsigned long len)
752 # ifdef HAVE_NANOSLEEP
753 struct timespec time_sleep;
754 struct timespec time_remaining;
757 time_sleep.tv_sec = len / 1000000;
758 time_sleep.tv_nsec = (len % 1000000) * 1000;
760 ret = nanosleep(&time_sleep, &time_remaining);
761 while (ret != 0 && errno == EINTR) {
762 time_sleep.tv_sec = time_remaining.tv_sec;
763 time_sleep.tv_nsec = time_remaining.tv_nsec;
765 ret = nanosleep(&time_sleep, &time_remaining);
770 tv.tv_sec = len / 1000000;
771 tv.tv_usec = (len % 1000000);
773 select(0, NULL, NULL, NULL, &tv);
778 static void *_start_routine(void *arg)
780 thread_start_t *start = (thread_start_t *)arg;
781 void *(*start_routine)(void *) = start->start_routine;
782 void *real_arg = start->arg;
783 thread_type *thread = start->thread;
784 int detach = start->detached;
790 /* insert thread into thread tree here */
791 _mutex_lock(&_threadtree_mutex);
792 thread->sys_thread = pthread_self();
793 avl_insert(_threadtree, (void *)thread);
794 _mutex_unlock(&_threadtree_mutex);
797 LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
801 pthread_detach(thread->sys_thread);
802 thread->detached = 1;
804 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
806 /* call the real start_routine and start the thread
807 ** this should never exit!
809 (start_routine)(real_arg);
812 LOG_WARN("Thread x should never exit from here!!!");
818 thread_type *thread_self(void)
822 pthread_t sys_thread = pthread_self();
824 _mutex_lock(&_threadtree_mutex);
826 if (_threadtree == NULL) {
828 LOG_WARN("Thread tree is empty, this must be wrong!");
830 _mutex_unlock(&_threadtree_mutex);
834 node = avl_get_first(_threadtree);
837 th = (thread_type *)node->key;
839 if (th && pthread_equal(sys_thread, th->sys_thread)) {
840 _mutex_unlock(&_threadtree_mutex);
844 node = avl_get_next(node);
846 _mutex_unlock(&_threadtree_mutex);
850 LOG_ERROR("Nonexistant thread alive...");
856 void thread_rename(const char *name)
861 if (th->name) free(th->name);
863 th->name = strdup(name);
866 static void _mutex_lock(mutex_t *mutex)
868 pthread_mutex_lock(&mutex->sys_mutex);
871 static void _mutex_unlock(mutex_t *mutex)
873 pthread_mutex_unlock(&mutex->sys_mutex);
877 void thread_library_lock(void)
879 _mutex_lock(&_library_mutex);
882 void thread_library_unlock(void)
884 _mutex_unlock(&_library_mutex);
887 void thread_join(thread_type *thread)
892 i = pthread_join(thread->sys_thread, &ret);
893 _mutex_lock(&_threadtree_mutex);
894 avl_delete(_threadtree, thread, _free_thread);
895 _mutex_unlock(&_threadtree_mutex);
898 /* AVL tree functions */
901 static int _compare_mutexes(void *compare_arg, void *a, void *b)
908 if (m1->mutex_id > m2->mutex_id)
910 if (m1->mutex_id < m2->mutex_id)
916 static int _compare_threads(void *compare_arg, void *a, void *b)
918 thread_type *t1, *t2;
920 t1 = (thread_type *)a;
921 t2 = (thread_type *)b;
923 if (t1->thread_id > t2->thread_id)
925 if (t1->thread_id < t2->thread_id)
931 static int _free_mutex(void *key)
942 /* all mutexes are static. don't need to free them */
948 static int _free_thread(void *key)
952 t = (thread_type *)key;
964 static int _free_thread_if_detached(void *key)
966 thread_type *t = key;
968 return _free_thread(key);
987 @Brendan was getting pissed off about inconsistent indentation styles.
988 Convert all tabs to 4 spaces. All code must now use 4 space indents.
994 ** - Thread Abstraction Functions
996 ** Copyright (c) 1999, 2000 the icecast team
998 ** This program is free software; you can redistribute it and/or
999 ** modify it under the terms of the GNU General Public License
1000 ** as published by the Free Software Foundation; either version 2
1001 ** of the License, or (at your option) any latfer version.
1003 ** This program is distributed in the hope that it will be useful,
1004 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
1005 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1006 ** GNU General Public License for more details.
1008 ** You should have received a copy of the GNU General Public License
1009 ** along with this program; if not, write to the Free Software
1010 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1017 @avoid freeing a thread structure a second time.
1022 /* the real start routine and arg */
1023 void *(*start_routine)(void *);
1026 /* whether to create the threaded in detached state */
1029 /* the other stuff we need to make sure this thread is inserted into
1032 thread_type *thread;
1033 pthread_t sys_thread;
1036 thread_type *thread;
1039 /* set up logging */
1043 _logid = log_open("thread.log");
1044 log_set_level(_logid, THREAD_DEBUG);
1047 /* create all the internal mutexes, and initialize the mutex tree */
1050 _mutextree = avl_tree_new(_compare_mutexes, NULL);
1053 /* we have to create this one by hand, because there's no
1054 ** mutextree_mutex to lock yet!
1056 _mutex_create(&_mutextree_mutex);
1059 _mutextree_mutex.mutex_id = _next_mutex_id++;
1060 avl_insert(_mutextree, (void *)&_mutextree_mutex);
1063 thread_mutex_create(&_threadtree_mutex);
1064 thread_mutex_create(&_library_mutex);
1067 /* initialize the thread tree and insert the main thread */
1070 _threadtree = avl_tree_new(_compare_threads, NULL);
1073 thread = (thread_type *)malloc(sizeof(thread_type));
1076 thread->thread_id = _next_thread_id++;
1078 thread->file = strdup("main.c");
1079 thread->sys_thread = pthread_self();
1080 thread->create_time = time(NULL);
1081 thread->name = strdup("Main Thread");
1084 avl_insert(_threadtree, (void *)thread);
1093 if (_initialized == 1) {
1094 thread_mutex_destroy(&_library_mutex);
1095 thread_mutex_destroy(&_threadtree_mutex);
1098 thread_mutex_destroy(&_mutextree_mutex);
1100 avl_tree_free(_mutextree, _free_mutex);
1103 avl_tree_free(_threadtree, _free_thread);
1112 thread_type *thread;
1113 thread_start_t *start;
1115 thread = (thread_type *)malloc(sizeof(thread_type));
1116 start = (thread_start_t *)malloc(sizeof(thread_start_t));
1117 thread->line = line;
1118 thread->file = strdup(file);
1120 _mutex_lock(&_threadtree_mutex);
1121 thread->thread_id = _next_thread_id++;
1122 _mutex_unlock(&_threadtree_mutex);
1125 thread->name = strdup(name);
1126 thread->create_time = time(NULL);
1129 start->start_routine = start_routine;
1131 start->thread = thread;
1132 start->detached = detached;
1136 if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0)
1141 LOG_ERROR("Could not create new thread");
1147 LOG_ERROR("System won't let me create more threads, giving up");
1157 mutex->thread_id = MUTEX_STATE_NEVERLOCKED;
1161 pthread_mutex_init(&mutex->sys_mutex, NULL);
1164 _mutex_create(mutex);
1167 _mutex_lock(&_mutextree_mutex);
1168 mutex->mutex_id = _next_mutex_id++;
1169 avl_insert(_mutextree, (void *)mutex);
1170 _mutex_unlock(&_mutextree_mutex);
1173 pthread_mutex_destroy(&mutex->sys_mutex);
1176 _mutex_lock(&_mutextree_mutex);
1177 avl_delete(_mutextree, mutex, _free_mutex);
1178 _mutex_unlock(&_mutextree_mutex);
1181 thread_type *th = thread_self();
1184 if (!th) LOG_WARN("No mt record for %u in lock [%s:%d]", thread_self(), file, line);
1187 LOG_DEBUG5("Locking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
1190 /* Just a little sanity checking to make sure that we're locking
1191 ** mutexes correctly
1199 _mutex_lock(&_mutextree_mutex);
1201 node = avl_get_first (_mutextree);
1204 tmutex = (mutex_t *)node->key;
1206 if (tmutex->mutex_id == mutex->mutex_id) {
1207 if (tmutex->thread_id == th->thread_id) {
1208 /* Deadlock, same thread can't lock the same mutex twice */
1209 LOG_ERROR7("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]",
1210 tmutex->thread_id, th->thread_id, mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);
1212 _mutex_unlock(&_mutextree_mutex);
1215 } else if (tmutex->thread_id == th->thread_id) {
1216 /* Mutex locked by this thread (not this mutex) */
1220 node = avl_get_next(node);
1224 /* Has already got a mutex locked */
1225 if (_multi_mutex.thread_id != th->thread_id) {
1226 /* Tries to lock two mutexes, but has not got the double mutex, norty boy! */
1227 LOG_WARN("(%d != %d) Thread %d [%s] tries to lock a second mutex [%s] in file %s line %d, without locking double mutex!",
1228 _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);
1232 _mutex_unlock(&_mutextree_mutex);
1239 _mutex_lock(&_mutextree_mutex);
1241 LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
1244 mutex->thread_id = th->thread_id;
1248 _mutex_unlock(&_mutextree_mutex);
1254 thread_type *th = thread_self();
1258 LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);
1262 LOG_DEBUG5("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
1273 _mutex_lock(&_mutextree_mutex);
1276 tmutex = (mutex_t *)node->key;
1278 if (tmutex->mutex_id == mutex->mutex_id) {
1279 if (tmutex->thread_id != th->thread_id) {
1280 LOG_ERROR7("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id,
1281 mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);
1282 _mutex_unlock(&_mutextree_mutex);
1285 } else if (tmutex->thread_id == th->thread_id) {
1289 node = avl_get_next (node);
1292 if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {
1293 /* Don't have double mutex, has more than this mutex left */
1295 LOG_WARN("(%d != %d) Thread %d [%s] tries to unlock a mutex [%s] in file %s line %d, without owning double mutex!",
1296 _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);
1300 _mutex_unlock(&_mutextree_mutex);
1304 _mutex_unlock(mutex);
1307 _mutex_lock(&_mutextree_mutex);
1310 LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
1312 if (mutex->thread_id == th->thread_id) {
1313 mutex->thread_id = MUTEX_STATE_NOTLOCKED;
1317 _mutex_unlock(&_mutextree_mutex);
1320 _mutex_unlock(mutex);
1323 pthread_cond_init(&cond->sys_cond, NULL);
1324 pthread_mutex_init(&cond->cond_mutex, NULL);
1327 pthread_mutex_destroy(&cond->cond_mutex);
1328 pthread_cond_destroy(&cond->sys_cond);
1331 pthread_cond_signal(&cond->sys_cond);
1334 pthread_cond_broadcast(&cond->sys_cond);
1337 pthread_mutex_lock(&cond->cond_mutex);
1338 pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex);
1339 pthread_mutex_unlock(&cond->cond_mutex);
1342 pthread_rwlock_init(&rwlock->sys_rwlock, NULL);
1345 pthread_rwlock_destroy(&rwlock->sys_rwlock);
1348 pthread_rwlock_rdlock(&rwlock->sys_rwlock);
1351 pthread_rwlock_wrlock(&rwlock->sys_rwlock);
1354 pthread_rwlock_unlock(&rwlock->sys_rwlock);
1357 thread_type *th = thread_self();
1366 _mutex_lock(&_mutextree_mutex);
1369 tmutex = (mutex_t *)node->key;
1372 if (tmutex->thread_id == th->thread_id) {
1373 LOG_WARN("Thread %d [%s] exiting in file %s line %d, without unlocking mutex [%s]",
1374 th->thread_id, th->name, file, line, mutex_to_string(tmutex, name));
1377 node = avl_get_next (node);
1380 _mutex_unlock(&_mutextree_mutex);
1388 LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
1391 _mutex_lock(&_threadtree_mutex);
1392 avl_delete(_threadtree, th, _free_thread_if_detached);
1393 _mutex_unlock(&_threadtree_mutex);
1396 pthread_exit((void *)val);
1402 struct timespec time_sleep;
1403 struct timespec time_remaining;
1406 time_sleep.tv_sec = len / 1000000;
1407 time_sleep.tv_nsec = (len % 1000000) * 1000;
1409 ret = nanosleep(&time_sleep, &time_remaining);
1410 while (ret != 0 && errno == EINTR) {
1411 time_sleep.tv_sec = time_remaining.tv_sec;
1412 time_sleep.tv_nsec = time_remaining.tv_nsec;
1414 ret = nanosleep(&time_sleep, &time_remaining);
1421 tv.tv_sec = len / 1000000;
1422 tv.tv_usec = (len % 1000000);
1425 select(0, NULL, NULL, NULL, &tv);
1428 thread_start_t *start = (thread_start_t *)arg;
1429 void *(*start_routine)(void *) = start->start_routine;
1430 void *real_arg = start->arg;
1431 thread_type *thread = start->thread;
1440 /* insert thread into thread tree here */
1441 _mutex_lock(&_threadtree_mutex);
1442 thread->sys_thread = pthread_self();
1443 avl_insert(_threadtree, (void *)thread);
1444 _mutex_unlock(&_threadtree_mutex);
1447 LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
1451 pthread_detach(thread->sys_thread);
1455 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
1458 /* call the real start_routine and start the thread
1459 ** this should never exit!
1461 (start_routine)(real_arg);
1464 LOG_WARN("Thread x should never exit from here!!!");
1472 pthread_t sys_thread = pthread_self();
1475 _mutex_lock(&_threadtree_mutex);
1478 if (_threadtree == NULL) {
1481 LOG_WARN("Thread tree is empty, this must be wrong!");
1484 _mutex_unlock(&_threadtree_mutex);
1488 node = avl_get_first(_threadtree);
1491 th = (thread_type *)node->key;
1493 if (th && pthread_equal(sys_thread, th->sys_thread)) {
1494 _mutex_unlock(&_threadtree_mutex);
1498 node = avl_get_next(node);
1500 _mutex_unlock(&_threadtree_mutex);
1503 LOG_ERROR("Nonexistant thread alive...");
1514 if (th->name) free(th->name);
1517 th->name = strdup(name);
1520 pthread_mutex_lock(&mutex->sys_mutex);
1523 pthread_mutex_unlock(&mutex->sys_mutex);
1526 _mutex_lock(&_library_mutex);
1529 _mutex_unlock(&_library_mutex);
1536 i = pthread_join(thread->sys_thread, &ret);
1546 if (m1->mutex_id > m2->mutex_id)
1548 if (m1->mutex_id < m2->mutex_id)
1553 thread_type *t1, *t2;
1556 t1 = (thread_type *)a;
1557 t2 = (thread_type *)b;
1560 if (t1->thread_id > t2->thread_id)
1562 if (t1->thread_id < t2->thread_id)
1579 /* all mutexes are static. don't need to free them */
1588 t = (thread_type *)key;
1606 @reduce include file namespace clutter for libshout and the associated
1611 _free_thread(thread);
1617 @include the automake config.h file if the application defines one
1632 @Make various thread structures omit the bits only used in debug mode.
1633 Some of these are pretty heavily used, so saving 10-20 bytes each can be
1636 No functional differences.
1645 @Fix some warnings, fix cflags.
1649 static int _logid = -1;
1659 static int _free_mutex(void *key);
1662 #ifdef DEBUG_MUTEXES
1668 static int rwlocknum = 0;
1679 @Rename thread_t to avoid problems on OS X
1684 static mutex_t _threadtree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1 };
1687 static mutex_t _mutextree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1 };
1688 static mutex_t _library_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1 };
1694 @Lots of bugfixes contributed by Karl Heyes.
1705 thread = (thread_t *)malloc(sizeof(thread_t));
1708 thread_t *thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
1714 thread = (thread_t *)malloc(sizeof(thread_t));
1717 thread_t *th = thread_self();
1720 thread_t *th = thread_self();
1723 thread_t *th = thread_self();
1726 thread_t *thread = start->thread;
1729 thread_t *thread_self(void)
1735 th = (thread_t *)node->key;
1741 void thread_join(thread_t *thread)
1754 t = (thread_t *)key;
1763 @Bugfix: thread_join is often called after a thread has already exited, which it
1764 does using thread_exit(). thread_exit() was freeing the thread structure, so
1765 thread_join was using freed memory. Rearrange things so that if the thread
1766 is detached, the freeing happens in thread_join instead.
1775 @Liberally sprinkle #ifdef THREAD_DEBUG around so libshout doesn't need to link
1783 avl_delete(_threadtree, th, _free_thread);
1809 if (pthread_sigmask(SIG_BLOCK, &ss, NULL) != 0)
1813 if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL) != 0)
1839 tv.tv_usec = (len % 1000000) / 1000;
1845 @oddsock's xslt stats support, slightly cleaned up
1850 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
1856 // return thread->thread_id;
1857 return thread->sys_thread;
1860 void thread_join(long thread)
1863 i = pthread_join(thread, &ret);
1869 @Cleaned up version of Ciaran Anscomb's relaying patch.
1873 /* this must be called to init pthreads-win32 */
1875 ptw32_processInitialize();
1880 /* create all the interal mutexes, and initialize the mutex tree */
1886 @Lots of patches committable now that my sound card works properly again.
1888 logging API changed slightly (I got sick of gcc warnings about deprecated
1891 resampling (for live input, not yet for reencoding) is in there.
1893 several patches from Karl Heyes have been incorporated.
1903 @Don't use start after freeing it in thread startup code.
1908 #define LOG_ERROR(y) log_write(_logid, 1, CATMODULE "/" __FUNCTION__, y)
1909 #define LOG_ERROR3(y, z1, z2, z3) log_write(_logid, 1, CATMODULE "/" __FUNCTION__, y, z1, z2, z3)
1910 #define LOG_ERROR7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 1, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7)
1912 #define LOG_WARN(y) log_write(_logid, 2, CATMODULE "/" __FUNCTION__, y)
1913 #define LOG_WARN3(y, z1, z2, z3) log_write(_logid, 2, CATMODULE "/" __FUNCTION__, y, z1, z2, z3)
1914 #define LOG_WARN5(y, z1, z2, z3, z4, z5) log_write(_logid, 2, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4, z5)
1915 #define LOG_WARN7(y, z1, z2, z3, z4, z5, z6, z7) log_write(_logid, 2, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4, z5, z6, z7)
1917 #define LOG_INFO(y) log_write(_logid, 3, CATMODULE "/" __FUNCTION__, y)
1918 #define LOG_INFO4(y, z1, z2, z3, z4) log_write(_logid, 3, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4)
1919 #define LOG_INFO5(y, z1, z2, z3, z4, z5) log_write(_logid, 3, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4, z5)
1921 #define LOG_DEBUG(y) log_write(_logid, 4, CATMODULE "/" __FUNCTION__, y)
1922 #define LOG_DEBUG2(y, z1, z2) log_write(_logid, 4, CATMODULE "/" __FUNCTION__, y, z1, z2)
1923 #define LOG_DEBUG5(y, z1, z2, z3, z4, z5) log_write(_logid, 4, CATMODULE "/" __FUNCTION__, y, z1, z2, z3, z4, z5)
1931 @win32 patches from Ed
1937 if (start->detached) {
1949 #include <pthread.h>
1953 #define __FUNCTION__ __FILE__ ":" __LINE__
1959 @minor build fixes for win32 courtesy of Oddsock
1968 @Revert the stacksize work. It's stupid.
1970 The original patch from Ben Laurie some years ago was needed because
1971 FreeBSD's default stack size was < 8k and this wasn't acceptable.
1972 Both Linux and Solaris had reasonable defaults for stacksize, or grew the
1973 stack as needed to a reasonable size.
1975 Testing today and consulting documentation shows that the default stack
1976 sizes on FreeBSD, Linux, and Solaris are all acceptable. Linux can grow
1977 to 2MB, 32bit Solaris defaults to 1MB, 64bit Solaris defaults to 2MB, and
1978 FreeBSD defaults to 64k.
1980 In my opinion FreeBSD needs to get with the program and provide a
1981 reasonable default. 64k is enough for us, but might not be for others.
1991 @Stack size per thread needs to be configurable. Setting it on a global
1992 bases is not enough. ices and icecast need this to be different, and
1993 if one is interested in tuning memory usage, one will want to alter this
1999 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int stacksize, int detached, int line, char *file)
2001 pthread_attr_t attr;
2003 pthread_attr_init(&attr);
2004 pthread_attr_setstacksize(&attr, stacksize);
2007 if (pthread_create(&thread->sys_thread, &attr, _start_routine, start) == 0)
2010 pthread_attr_destroy(&attr);
2016 @Win32 fixes. Specifically a header change and not using the gcc extensions
2017 for vararg macros. It's not as pretty, but it works.
2022 #define STACKSIZE 8192
2026 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
2029 pthread_attr_setstacksize(&attr, STACKSIZE);
2035 @Oddsock found this bug when working with icecast2 on freebsd. Nanoseconds
2036 were off by a few orders of magnitude.
2040 #include <sys/time.h>
2044 #define LOG_ERROR(y, z...) log_write(_logid, 1, CATMODULE "/" __FUNCTION__, y, ##z)
2045 #define LOG_WARN(y, z...) log_write(_logid, 2, CATMODULE "/" __FUNCTION__, y, ##z)
2046 #define LOG_INFO(y, z...) log_write(_logid, 3, CATMODULE "/" __FUNCTION__, y, ##z)
2047 #define LOG_DEBUG(y, z...) log_write(_logid, 4, CATMODULE "/" __FUNCTION__, y, ##z)
2050 LOG_DEBUG("Locking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
2053 LOG_ERROR("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]",
2056 LOG_DEBUG("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
2059 LOG_ERROR("No record for %u in unlock [%s:%d]", thread_self(), file, line);
2062 LOG_DEBUG("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);
2065 LOG_ERROR("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id,
2068 LOG_DEBUG("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
2071 LOG_INFO("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
2074 LOG_INFO("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
2085 time_sleep.tv_nsec = len % 1000000;