Remove redundant call of len().
[cvs2svn.git] / test-data / resync-misgroups-cvsrepos / thread / thread.c,v
blob83c8c5fe5d6b0839a230100222a9d96cdd5d8247
1 head    1.25;
2 access;
3 symbols
4         libshout-2_0:1.24
5         libshout-2_0b3:1.24
6         libshout-2_0b2:1.24
7         libshout_2_0b1:1.24
8         libogg2-zerocopy:1.17.0.2
9         branch-beta2-rewrite:1.5.0.2
10         start:1.1.1.1
11         xiph:1.1.1;
12 locks; strict;
13 comment @ * @;
16 1.25
17 date    2003.07.14.02.17.52;    author brendan; state Exp;
18 branches;
19 next    1.24;
21 1.24
22 date    2003.03.15.02.10.18;    author msmith;  state Exp;
23 branches;
24 next    1.23;
26 1.23
27 date    2003.03.12.03.59.55;    author karl;    state Exp;
28 branches;
29 next    1.22;
31 1.22
32 date    2003.03.09.22.56.46;    author karl;    state Exp;
33 branches;
34 next    1.21;
36 1.21
37 date    2003.03.08.16.05.38;    author karl;    state Exp;
38 branches;
39 next    1.20;
41 1.20
42 date    2003.03.04.15.31.34;    author msmith;  state Exp;
43 branches;
44 next    1.19;
46 1.19
47 date    2003.01.17.09.01.04;    author msmith;  state Exp;
48 branches;
49 next    1.18;
51 1.18
52 date    2002.12.29.09.55.50;    author msmith;  state Exp;
53 branches;
54 next    1.17;
56 1.17
57 date    2002.11.22.13.00.44;    author msmith;  state Exp;
58 branches;
59 next    1.16;
61 1.16
62 date    2002.09.24.07.09.08;    author msmith;  state Exp;
63 branches;
64 next    1.15;
66 1.15
67 date    2002.08.16.14.23.17;    author msmith;  state Exp;
68 branches;
69 next    1.14;
71 1.14
72 date    2002.08.13.01.08.15;    author msmith;  state Exp;
73 branches;
74 next    1.13;
76 1.13
77 date    2002.08.10.03.22.44;    author msmith;  state Exp;
78 branches;
79 next    1.12;
81 1.12
82 date    2002.08.09.06.52.07;    author msmith;  state Exp;
83 branches;
84 next    1.11;
86 1.11
87 date    2002.08.05.14.48.03;    author msmith;  state Exp;
88 branches;
89 next    1.10;
91 1.10
92 date    2002.08.03.08.14.56;    author msmith;  state Exp;
93 branches;
94 next    1.9;
96 1.9
97 date    2002.04.30.06.50.47;    author msmith;  state Exp;
98 branches;
99 next    1.8;
102 date    2002.03.05.23.59.38;    author jack;    state Exp;
103 branches;
104 next    1.7;
107 date    2002.02.08.03.51.19;    author jack;    state Exp;
108 branches;
109 next    1.6;
112 date    2002.02.07.01.04.09;    author jack;    state Exp;
113 branches;
114 next    1.5;
117 date    2001.10.21.02.04.27;    author jack;    state Exp;
118 branches;
119 next    1.4;
122 date    2001.10.20.22.27.52;    author jack;    state Exp;
123 branches;
124 next    1.3;
127 date    2001.10.20.05.35.30;    author jack;    state Exp;
128 branches;
129 next    1.2;
132 date    2001.10.20.03.39.10;    author jack;    state Exp;
133 branches;
134 next    1.1;
137 date    2001.09.10.02.26.33;    author jack;    state Exp;
138 branches
139         1.1.1.1;
140 next    ;
142 1.1.1.1
143 date    2001.09.10.02.26.33;    author jack;    state Exp;
144 branches;
145 next    ;
148 desc
152 1.25
154 @Assign LGP to thread module
156 text
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
174  */
176 #ifdef HAVE_CONFIG_H
177  #include <config.h>
178 #endif
180 #include <stdio.h>
181 #include <stdlib.h>
182 #include <string.h>
183 #include <errno.h>
184 #include <time.h>
185 #include <sys/types.h>
187 #include <pthread.h>
189 #ifndef _WIN32
190 #include <unistd.h>
191 #include <sys/time.h>
192 #else
193 #include <windows.h>
194 #include <winbase.h>
195 #include <implement.h>
196 #endif
198 #include <signal.h>
200 #include <thread/thread.h>
201 #include <avl/avl.h>
202 #ifdef THREAD_DEBUG
203 #include <log/log.h>
204 #endif
206 #ifdef _WIN32
207 #define __FUNCTION__ __FILE__
208 #endif
210 #ifdef THREAD_DEBUG
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)
228 #endif
230 /* thread starting structure */
231 typedef struct thread_start_tag {
232     /* the real start routine and arg */
233     void *(*start_routine)(void *);
234     void *arg;
236     /* whether to create the threaded in detached state */
237     int detached;
239     /* the other stuff we need to make sure this thread is inserted into
240     ** the thread tree
241     */
242     thread_type *thread;
243     pthread_t sys_thread;
244 } thread_start_t;
246 static long _next_thread_id = 0;
247 static int _initialized = 0;
248 static avl_tree *_threadtree = NULL;
250 #ifdef DEBUG_MUTEXES
251 static mutex_t _threadtree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1, 
252     PTHREAD_MUTEX_INITIALIZER};
253 #else
254 static mutex_t _threadtree_mutex = { PTHREAD_MUTEX_INITIALIZER };
255 #endif
259 #ifdef DEBUG_MUTEXES
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};
266 #endif
268 #ifdef DEBUG_MUTEXES
269 static mutex_t _library_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1,
270     PTHREAD_MUTEX_INITIALIZER};
271 #else
272 static mutex_t _library_mutex = { PTHREAD_MUTEX_INITIALIZER };
273 #endif
275 /* INTERNAL FUNCTIONS */
277 /* avl tree functions */
278 #ifdef DEBUG_MUTEXES
279 static int _compare_mutexes(void *compare_arg, void *a, void *b);
280 static int _free_mutex(void *key);
281 #endif
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);
287 /* mutex fuctions */
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)
301     thread_type *thread;
303     /* set up logging */
305 #ifdef THREAD_DEBUG
306     log_initialize();
307     _logid = log_open("thread.log");
308     log_set_level(_logid, THREAD_DEBUG);
309 #endif
311 #ifdef DEBUG_MUTEXES
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! 
318     */
319     _mutex_create(&_mutextree_mutex);
321     _mutextree_mutex.mutex_id = _next_mutex_id++;
322     avl_insert(_mutextree, (void *)&_mutextree_mutex);
323 #endif
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++;
335     thread->line = 0;
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);
343     _catch_signals();
345     _initialized = 1;
348 void thread_shutdown(void)
350     if (_initialized == 1) {
351         thread_mutex_destroy(&_library_mutex);
352         thread_mutex_destroy(&_threadtree_mutex);
353 #ifdef THREAD_DEBUG
354         thread_mutex_destroy(&_mutextree_mutex);
355         
356         avl_tree_free(_mutextree, _free_mutex);
357 #endif
358         avl_tree_free(_threadtree, _free_thread);
359     }
361 #ifdef THREAD_DEBUG
362     log_close(_logid);
363     log_shutdown();
364 #endif
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
374  */
375 static void _block_signals(void)
377 #ifndef _WIN32
378         sigset_t ss;
380         sigfillset(&ss);
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) {
389 #ifdef THREAD_DEBUG
390                 LOG_ERROR("Pthread_sigmask() failed for blocking signals");
391 #endif
392         }
393 #endif
397  * Let the calling thread catch all the relevant signals
399  * This function only valid for non-Win32
400  */
401 static void _catch_signals(void)
403 #ifndef _WIN32
404         sigset_t ss;
406         sigemptyset(&ss);
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) {
415 #ifdef THREAD_DEBUG
416                 LOG_ERROR("pthread_sigmask() failed for catching signals!");
417 #endif
418         }
419 #endif
423 thread_type *thread_create_c(char *name, void *(*start_routine)(void *), 
424         void *arg, int detached, int line, char *file)
426     int created;
427     thread_type *thread;
428     thread_start_t *start;
430     thread = (thread_type *)malloc(sizeof(thread_type));    
431     start = (thread_start_t *)malloc(sizeof(thread_start_t));
432     thread->line = line;
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;
444     start->arg = arg;
445     start->thread = thread;
446     start->detached = detached;
448     created = 0;
449     if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0)
450         created = 1;
451 #ifdef THREAD_DEBUG
452     else
453         LOG_ERROR("Could not create new thread");
454 #endif
456     if (created == 0) {
457 #ifdef THREAD_DEBUG
458         LOG_ERROR("System won't let me create more threads, giving up");
459 #endif
460         return NULL;
461     }
463     return thread;
466 /* _mutex_create
467 ** 
468 ** creates a mutex
470 static void _mutex_create(mutex_t *mutex)
472 #ifdef DEBUG_MUTEXES
473     mutex->thread_id = MUTEX_STATE_NEVERLOCKED;
474     mutex->line = -1;
475 #endif
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);
484 #ifdef DEBUG_MUTEXES
485     _mutex_lock(&_mutextree_mutex);
486     mutex->mutex_id = _next_mutex_id++;
487     avl_insert(_mutextree, (void *)mutex);
488     _mutex_unlock(&_mutextree_mutex);
489 #endif
492 void thread_mutex_destroy (mutex_t *mutex)
494     pthread_mutex_destroy(&mutex->sys_mutex);
496 #ifdef DEBUG_MUTEXES
497     _mutex_lock(&_mutextree_mutex);
498     avl_delete(_mutextree, mutex, _free_mutex);
499     _mutex_unlock(&_mutextree_mutex);
500 #endif
503 void thread_mutex_lock_c(mutex_t *mutex, int line, char *file)
505 #ifdef DEBUG_MUTEXES
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
514     ** mutexes correctly
515     */
517     if (th) {
518         int locks = 0;
519         avl_node *node;
520         mutex_t *tmutex;
522         _mutex_lock(&_mutextree_mutex);
524         node = avl_get_first (_mutextree);
525         
526         while (node) {
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);
536                     return;
537                 }
538             } else if (tmutex->thread_id == th->thread_id) { 
539                 /* Mutex locked by this thread (not this mutex) */
540                 locks++;
541             }
543             node = avl_get_next(node);
544         }
546         if (locks > 0) { 
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);
552             }
553         }
554         
555         _mutex_unlock(&_mutextree_mutex);
556     }
557 # endif /* CHECK_MUTEXES */
558     
559     _mutex_lock(mutex);
560     
561     _mutex_lock(&_mutextree_mutex);
563     LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
564     mutex->line = line;
565     if (th) {
566         mutex->thread_id = th->thread_id;
567     }
569     _mutex_unlock(&_mutextree_mutex);
570 #else
571     _mutex_lock(mutex);
572 #endif /* DEBUG_MUTEXES */
575 void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file)
577 #ifdef DEBUG_MUTEXES
578     thread_type *th = thread_self();
580     if (!th) {
581         LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);
582     }
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);
586     mutex->line = line;
588 # ifdef CHECK_MUTEXES
589     if (th) {
590         int locks = 0;
591         avl_node *node;
592         mutex_t *tmutex;
594         _mutex_lock(&_mutextree_mutex);
596         while (node) {
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);
604                     return;
605                 }
606             } else if (tmutex->thread_id == th->thread_id) {
607                 locks++;
608             }
610             node = avl_get_next (node);
611         }
613         if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {
614             /* Don't have double mutex, has more than this mutex left */
615         
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);
618         }
620         _mutex_unlock(&_mutextree_mutex);
621     }
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);
629     mutex->line = -1;
630     if (mutex->thread_id == th->thread_id) {
631         mutex->thread_id = MUTEX_STATE_NOTLOCKED;
632     }
634     _mutex_unlock(&_mutextree_mutex);
635 #else
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)
711     if (th) {
712         avl_node *node;
713         mutex_t *tmutex;
714         char name[40];
716         _mutex_lock(&_mutextree_mutex);
718         while (node) {
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));
724             }
726             node = avl_get_next (node);
727         }
729         _mutex_unlock(&_mutextree_mutex);
730     }
731 #endif
732     
733     if (th)    {
734 #ifdef THREAD_DEBUG
735         LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
736 #endif
738         _mutex_lock(&_threadtree_mutex);
739         avl_delete(_threadtree, th, _free_thread_if_detached);
740         _mutex_unlock(&_threadtree_mutex);
741     }
742     
743     pthread_exit((void *)val);
746 /* sleep for a number of microseconds */
747 void thread_sleep(unsigned long len)
749 #ifdef _WIN32
750     Sleep(len / 1000);
751 #else
752 # ifdef HAVE_NANOSLEEP
753     struct timespec time_sleep;
754     struct timespec time_remaining;
755     int ret;
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;
764         
765         ret = nanosleep(&time_sleep, &time_remaining);
766     }
767 # else
768     struct timeval tv;
770     tv.tv_sec = len / 1000000;
771     tv.tv_usec = (len % 1000000);
773     select(0, NULL, NULL, NULL, &tv);
774 # endif
775 #endif
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;
786     _block_signals();
788     free(start);
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);
796 #ifdef THREAD_DEBUG
797     LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
798 #endif
800     if (detach) {
801         pthread_detach(thread->sys_thread);
802         thread->detached = 1;
803     }
804     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
806     /* call the real start_routine and start the thread
807     ** this should never exit!
808     */
809     (start_routine)(real_arg);
811 #ifdef THREAD_DEBUG
812     LOG_WARN("Thread x should never exit from here!!!");
813 #endif
815     return NULL;
818 thread_type *thread_self(void)
820     avl_node *node;
821     thread_type *th;
822     pthread_t sys_thread = pthread_self();
824     _mutex_lock(&_threadtree_mutex);
826     if (_threadtree == NULL) {
827 #ifdef THREAD_DEBUG
828         LOG_WARN("Thread tree is empty, this must be wrong!");
829 #endif
830         _mutex_unlock(&_threadtree_mutex);
831         return NULL;
832     }
833     
834     node = avl_get_first(_threadtree);
835     
836     while (node) {
837         th = (thread_type *)node->key;
839         if (th && pthread_equal(sys_thread, th->sys_thread)) {
840             _mutex_unlock(&_threadtree_mutex);
841             return th;
842         }
843         
844         node = avl_get_next(node);
845     }
846     _mutex_unlock(&_threadtree_mutex);
849 #ifdef THREAD_DEBUG
850     LOG_ERROR("Nonexistant thread alive...");
851 #endif
852     
853     return NULL;
856 void thread_rename(const char *name)
858     thread_type *th;
860     th = thread_self();
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)
889     void *ret;
890     int i;
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 */
900 #ifdef DEBUG_MUTEXES
901 static int _compare_mutexes(void *compare_arg, void *a, void *b)
903     mutex_t *m1, *m2;
905     m1 = (mutex_t *)a;
906     m2 = (mutex_t *)b;
908     if (m1->mutex_id > m2->mutex_id)
909         return 1;
910     if (m1->mutex_id < m2->mutex_id)
911         return -1;
912     return 0;
914 #endif
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)
924         return 1;
925     if (t1->thread_id < t2->thread_id)
926         return -1;
927     return 0;
930 #ifdef DEBUG_MUTEXES
931 static int _free_mutex(void *key)
933     mutex_t *m;
935     m = (mutex_t *)key;
937     if (m && m->file) {
938         free(m->file);
939         m->file = NULL;
940     }
942     /* all mutexes are static.  don't need to free them */
944     return 1;
946 #endif
948 static int _free_thread(void *key)
950     thread_type *t;
952     t = (thread_type *)key;
954     if (t->file)
955         free(t->file);
956     if (t->name)
957         free(t->name);
959     free(t);
961     return 1;
964 static int _free_thread_if_detached(void *key)
966     thread_type *t = key;
967     if(t->detached)
968         return _free_thread(key);
969     return 1;
985 1.24
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.
990 text
991 @d1 18
992 a18 19
993 /* threads.c
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.
1002 ** 
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.
1007 ** 
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.
1015 1.23
1017 @avoid freeing a thread structure a second time.
1019 text
1020 @d77 12
1021 a88 12
1022         /* the real start routine and arg */
1023         void *(*start_routine)(void *);
1024         void *arg;
1026         /* whether to create the threaded in detached state */
1027         int detached;
1029         /* the other stuff we need to make sure this thread is inserted into
1030         ** the thread tree
1031         */
1032         thread_type *thread;
1033         pthread_t sys_thread;
1034 d146 1
1035 a146 1
1036         thread_type *thread;
1037 d148 1
1038 a148 1
1039         /* set up logging */
1040 d151 3
1041 a153 3
1042         log_initialize();
1043         _logid = log_open("thread.log");
1044         log_set_level(_logid, THREAD_DEBUG);
1045 d157 1
1046 a157 1
1047         /* create all the internal mutexes, and initialize the mutex tree */
1048 d159 1
1049 a159 1
1050         _mutextree = avl_tree_new(_compare_mutexes, NULL);
1051 d161 4
1052 a164 4
1053         /* we have to create this one by hand, because there's no
1054         ** mutextree_mutex to lock yet! 
1055         */
1056         _mutex_create(&_mutextree_mutex);
1057 d166 2
1058 a167 2
1059         _mutextree_mutex.mutex_id = _next_mutex_id++;
1060         avl_insert(_mutextree, (void *)&_mutextree_mutex);
1061 d170 2
1062 a171 2
1063         thread_mutex_create(&_threadtree_mutex);
1064         thread_mutex_create(&_library_mutex);   
1065 d173 1
1066 a173 1
1067         /* initialize the thread tree and insert the main thread */
1068 d175 1
1069 a175 1
1070         _threadtree = avl_tree_new(_compare_threads, NULL);
1071 d177 1
1072 a177 1
1073         thread = (thread_type *)malloc(sizeof(thread_type));
1074 d179 6
1075 a184 6
1076         thread->thread_id = _next_thread_id++;
1077         thread->line = 0;
1078         thread->file = strdup("main.c");
1079         thread->sys_thread = pthread_self();
1080         thread->create_time = time(NULL);
1081         thread->name = strdup("Main Thread");
1082 d186 1
1083 a186 1
1084         avl_insert(_threadtree, (void *)thread);
1085 d188 1
1086 a188 1
1087         _catch_signals();
1088 d190 1
1089 a190 1
1090         _initialized = 1;
1091 d195 3
1092 a197 3
1093         if (_initialized == 1) {
1094                 thread_mutex_destroy(&_library_mutex);
1095                 thread_mutex_destroy(&_threadtree_mutex);
1096 d199 3
1097 a201 3
1098                 thread_mutex_destroy(&_mutextree_mutex);
1099                 
1100                 avl_tree_free(_mutextree, _free_mutex);
1101 d203 2
1102 a204 2
1103                 avl_tree_free(_threadtree, _free_thread);
1104         }
1105 d207 2
1106 a208 2
1107         log_close(_logid);
1108         log_shutdown();
1109 d271 8
1110 a278 12
1111         int created;
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);
1123 d280 6
1124 a285 2
1125         thread->name = strdup(name);
1126         thread->create_time = time(NULL);
1127 d288 4
1128 a291 4
1129         start->start_routine = start_routine;
1130         start->arg = arg;
1131         start->thread = thread;
1132         start->detached = detached;
1133 d293 3
1134 a295 3
1135         created = 0;
1136         if (pthread_create(&thread->sys_thread, NULL, _start_routine, start) == 0)
1137                 created = 1;
1138 d297 2
1139 a298 2
1140         else
1141                 LOG_ERROR("Could not create new thread");
1142 d301 1
1143 a301 1
1144         if (created == 0) {
1145 d303 1
1146 a303 1
1147                 LOG_ERROR("System won't let me create more threads, giving up");
1148 d305 2
1149 a306 2
1150                 return NULL;
1151         }
1152 d308 1
1153 a308 1
1154         return thread;
1155 d318 2
1156 a319 2
1157         mutex->thread_id = MUTEX_STATE_NEVERLOCKED;
1158         mutex->line = -1;
1159 d322 1
1160 a322 1
1161         pthread_mutex_init(&mutex->sys_mutex, NULL);
1162 d327 1
1163 a327 1
1164         _mutex_create(mutex);
1165 d330 4
1166 a333 4
1167         _mutex_lock(&_mutextree_mutex);
1168         mutex->mutex_id = _next_mutex_id++;
1169         avl_insert(_mutextree, (void *)mutex);
1170         _mutex_unlock(&_mutextree_mutex);
1171 d339 1
1172 a339 1
1173         pthread_mutex_destroy(&mutex->sys_mutex);
1174 d342 3
1175 a344 3
1176         _mutex_lock(&_mutextree_mutex);
1177         avl_delete(_mutextree, mutex, _free_mutex);
1178         _mutex_unlock(&_mutextree_mutex);
1179 d351 1
1180 a351 1
1181         thread_type *th = thread_self();
1182 d353 1
1183 a353 1
1184         if (!th) LOG_WARN("No mt record for %u in lock [%s:%d]", thread_self(), file, line);
1185 d355 1
1186 a355 1
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);
1188 d358 44
1189 a401 44
1190         /* Just a little sanity checking to make sure that we're locking
1191         ** mutexes correctly
1192         */
1194         if (th) {
1195                 int locks = 0;
1196                 avl_node *node;
1197                 mutex_t *tmutex;
1199                 _mutex_lock(&_mutextree_mutex);
1201                 node = avl_get_first (_mutextree);
1202                 
1203                 while (node) {
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);
1213                                         return;
1214                                 }
1215                         } else if (tmutex->thread_id == th->thread_id) { 
1216                                 /* Mutex locked by this thread (not this mutex) */
1217                                 locks++;
1218                         }
1220                         node = avl_get_next(node);
1221                 }
1223                 if (locks > 0) { 
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);
1229                         }
1230                 }
1231                 
1232                 _mutex_unlock(&_mutextree_mutex);
1233         }
1234 d403 10
1235 a412 10
1236         
1237         _mutex_lock(mutex);
1238         
1239         _mutex_lock(&_mutextree_mutex);
1241         LOG_DEBUG2("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
1242         mutex->line = line;
1243         if (th) {
1244                 mutex->thread_id = th->thread_id;
1245         }
1246 d414 1
1247 a414 1
1248         _mutex_unlock(&_mutextree_mutex);
1249 d416 1
1250 a416 1
1251         _mutex_lock(mutex);
1252 d423 1
1253 a423 1
1254         thread_type *th = thread_self();
1255 d425 3
1256 a427 3
1257         if (!th) {
1258                 LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);
1259         }
1260 d429 1
1261 a429 1
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);
1263 d431 1
1264 a431 1
1265         mutex->line = line;
1266 d434 20
1267 a453 30
1268         if (th) {
1269                 int locks = 0;
1270                 avl_node *node;
1271                 mutex_t *tmutex;
1273                 _mutex_lock(&_mutextree_mutex);
1275                 while (node) {
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);
1283                                         return;
1284                                 }
1285                         } else if (tmutex->thread_id == th->thread_id) {
1286                                 locks++;
1287                         }
1289                         node = avl_get_next (node);
1290                 }
1292                 if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {
1293                         /* Don't have double mutex, has more than this mutex left */
1294                 
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);
1297                 }
1298 d455 12
1299 a466 2
1300                 _mutex_unlock(&_mutextree_mutex);
1301         }
1302 d469 1
1303 a469 1
1304         _mutex_unlock(mutex);
1305 d471 1
1306 a471 1
1307         _mutex_lock(&_mutextree_mutex);
1308 d473 5
1309 a477 5
1310         LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
1311         mutex->line = -1;
1312         if (mutex->thread_id == th->thread_id) {
1313                 mutex->thread_id = MUTEX_STATE_NOTLOCKED;
1314         }
1315 d479 1
1316 a479 1
1317         _mutex_unlock(&_mutextree_mutex);
1318 d481 1
1319 a481 1
1320         _mutex_unlock(mutex);
1321 d487 2
1322 a488 2
1323         pthread_cond_init(&cond->sys_cond, NULL);
1324         pthread_mutex_init(&cond->cond_mutex, NULL);
1325 d493 2
1326 a494 2
1327         pthread_mutex_destroy(&cond->cond_mutex);
1328         pthread_cond_destroy(&cond->sys_cond);
1329 d499 1
1330 a499 1
1331         pthread_cond_signal(&cond->sys_cond);
1332 d504 1
1333 a504 1
1334         pthread_cond_broadcast(&cond->sys_cond);
1335 d521 3
1336 a523 3
1337         pthread_mutex_lock(&cond->cond_mutex);
1338         pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex);
1339         pthread_mutex_unlock(&cond->cond_mutex);
1340 d528 1
1341 a528 1
1342         pthread_rwlock_init(&rwlock->sys_rwlock, NULL);
1343 d533 1
1344 a533 1
1345         pthread_rwlock_destroy(&rwlock->sys_rwlock);
1346 d538 1
1347 a538 1
1348         pthread_rwlock_rdlock(&rwlock->sys_rwlock);
1349 d543 1
1350 a543 1
1351         pthread_rwlock_wrlock(&rwlock->sys_rwlock);
1352 d548 1
1353 a548 1
1354         pthread_rwlock_unlock(&rwlock->sys_rwlock);
1355 d553 1
1356 a553 1
1357         thread_type *th = thread_self();
1358 d556 14
1359 a569 4
1360         if (th) {
1361                 avl_node *node;
1362                 mutex_t *tmutex;
1363                 char name[40];
1364 d571 2
1365 a572 4
1366                 _mutex_lock(&_mutextree_mutex);
1368                 while (node) {
1369                         tmutex = (mutex_t *)node->key;
1370 d574 2
1371 a575 10
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));
1375                         }
1377                         node = avl_get_next (node);
1378                 }
1380                 _mutex_unlock(&_mutextree_mutex);
1381         }
1382 d577 2
1383 a578 2
1384         
1385         if (th) {
1386 d580 1
1387 a580 1
1388                 LOG_INFO4("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
1389 d583 6
1390 a588 6
1391                 _mutex_lock(&_threadtree_mutex);
1392         avl_delete(_threadtree, th, _free_thread_if_detached);
1393                 _mutex_unlock(&_threadtree_mutex);
1394         }
1395         
1396         pthread_exit((void *)val);
1397 d595 1
1398 a595 1
1399         Sleep(len / 1000);
1400 d598 14
1401 a611 14
1402         struct timespec time_sleep;
1403         struct timespec time_remaining;
1404         int ret;
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;
1413                 
1414                 ret = nanosleep(&time_sleep, &time_remaining);
1415         }
1416 d613 1
1417 a613 1
1418         struct timeval tv;
1419 d615 2
1420 a616 2
1421         tv.tv_sec = len / 1000000;
1422         tv.tv_usec = (len % 1000000);
1423 d618 1
1424 a618 1
1425         select(0, NULL, NULL, NULL, &tv);
1426 d625 4
1427 a628 4
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;
1432 d631 1
1433 a631 1
1434         _block_signals();
1435 d633 1
1436 a633 1
1437         free(start);
1438 d635 5
1439 a639 5
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);
1445 d642 1
1446 a642 1
1447         LOG_INFO4("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
1448 d645 2
1449 a646 2
1450         if (detach) {
1451                 pthread_detach(thread->sys_thread);
1452 d648 2
1453 a649 2
1454         }
1455         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
1456 d651 4
1457 a654 4
1458         /* call the real start_routine and start the thread
1459         ** this should never exit!
1460         */
1461         (start_routine)(real_arg);
1462 d657 1
1463 a657 1
1464         LOG_WARN("Thread x should never exit from here!!!");
1465 d660 1
1466 a660 1
1467         return NULL;
1468 d665 3
1469 a667 3
1470         avl_node *node;
1471         thread_type *th;
1472         pthread_t sys_thread = pthread_self();
1473 d669 1
1474 a669 1
1475         _mutex_lock(&_threadtree_mutex);
1476 d671 1
1477 a671 1
1478         if (_threadtree == NULL) {
1479 d673 1
1480 a673 1
1481                 LOG_WARN("Thread tree is empty, this must be wrong!");
1482 d675 17
1483 a691 17
1484                 _mutex_unlock(&_threadtree_mutex);
1485                 return NULL;
1486         }
1487         
1488         node = avl_get_first(_threadtree);
1489         
1490         while (node) {
1491                 th = (thread_type *)node->key;
1493                 if (th && pthread_equal(sys_thread, th->sys_thread)) {
1494                         _mutex_unlock(&_threadtree_mutex);
1495                         return th;
1496                 }
1497                 
1498                 node = avl_get_next(node);
1499         }
1500         _mutex_unlock(&_threadtree_mutex);
1501 d695 1
1502 a695 1
1503         LOG_ERROR("Nonexistant thread alive...");
1504 d697 2
1505 a698 2
1506         
1507         return NULL;
1508 d703 1
1509 a703 1
1510         thread_type *th;
1511 d705 2
1512 a706 2
1513         th = thread_self();
1514         if (th->name) free(th->name);
1515 d708 1
1516 a708 1
1517         th->name = strdup(name);
1518 d713 1
1519 a713 1
1520         pthread_mutex_lock(&mutex->sys_mutex);
1521 d718 1
1522 a718 1
1523         pthread_mutex_unlock(&mutex->sys_mutex);
1524 d724 1
1525 a724 1
1526         _mutex_lock(&_library_mutex);
1527 d729 1
1528 a729 1
1529         _mutex_unlock(&_library_mutex);
1530 d734 2
1531 a735 2
1532         void *ret;
1533         int i;
1534 d737 1
1535 a737 1
1536         i = pthread_join(thread->sys_thread, &ret);
1537 d748 1
1538 a748 1
1539         mutex_t *m1, *m2;
1540 d750 2
1541 a751 2
1542         m1 = (mutex_t *)a;
1543         m2 = (mutex_t *)b;
1544 d753 5
1545 a757 5
1546         if (m1->mutex_id > m2->mutex_id)
1547                 return 1;
1548         if (m1->mutex_id < m2->mutex_id)
1549                 return -1;
1550         return 0;
1551 d763 1
1552 a763 1
1553         thread_type *t1, *t2;
1554 d765 2
1555 a766 2
1556         t1 = (thread_type *)a;
1557         t2 = (thread_type *)b;
1558 d768 5
1559 a772 5
1560         if (t1->thread_id > t2->thread_id)
1561                 return 1;
1562         if (t1->thread_id < t2->thread_id)
1563                 return -1;
1564         return 0;
1565 d778 1
1566 a778 1
1567         mutex_t *m;
1568 d780 1
1569 a780 1
1570         m = (mutex_t *)key;
1571 d782 4
1572 a785 4
1573         if (m && m->file) {
1574                 free(m->file);
1575                 m->file = NULL;
1576         }
1577 d787 1
1578 a787 1
1579         /* all mutexes are static.  don't need to free them */
1580 d789 1
1581 a789 1
1582         return 1;
1583 d795 1
1584 a795 1
1585         thread_type *t;
1586 d797 1
1587 a797 1
1588         t = (thread_type *)key;
1589 d799 4
1590 a802 4
1591         if (t->file)
1592                 free(t->file);
1593         if (t->name)
1594                 free(t->name);
1595 d804 1
1596 a804 1
1597         free(t);
1598 d806 1
1599 a806 1
1600         return 1;
1604 1.22
1606 @reduce include file namespace clutter for libshout and the associated
1607 smaller libs.
1609 text
1610 @a740 1
1611     _free_thread(thread);
1615 1.21
1617 @include the automake config.h file if the application defines one
1619 text
1620 @d45 2
1621 a46 2
1622 #include "thread.h"
1623 #include "avl.h"
1624 d48 1
1625 a48 1
1626 #include "log.h"
1630 1.20
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
1634 quite significant.
1636 No functional differences.
1638 text
1639 @d21 4
1643 1.19
1645 @Fix some warnings, fix cflags.
1647 text
1648 @a86 1
1649 static int _logid = -1;
1650 d90 2
1651 d94 4
1652 d99 3
1653 d103 1
1654 d107 3
1655 d112 3
1656 d119 1
1657 d121 3
1658 a124 1
1659 static int _free_mutex(void *key);
1660 d152 1
1661 a161 1
1662 #ifdef DEBUG_MUTEXES
1663 d194 1
1664 d198 1
1665 d313 1
1666 d316 1
1667 a521 2
1668 static int rwlocknum = 0;
1670 d742 1
1671 d756 1
1672 d772 1
1673 d788 1
1677 1.18
1679 @Rename thread_t to avoid problems on OS X
1681 text
1682 @d91 2
1683 a92 1
1684 static mutex_t _threadtree_mutex = { -1, NULL, MUTEX_STATE_UNINIT, NULL, -1 };
1685 d96 4
1686 a99 2
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 };
1692 1.17
1694 @Lots of bugfixes contributed by Karl Heyes.
1696 text
1697 @d83 1
1698 a83 1
1699         thread_t *thread;
1700 d121 1
1701 a121 1
1702         thread_t *thread;
1703 d152 1
1704 a152 1
1705         thread = (thread_t *)malloc(sizeof(thread_t));
1706 d241 2
1707 a242 1
1708 thread_t *thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
1709 d245 1
1710 a245 1
1711         thread_t *thread;
1712 d248 1
1713 a248 1
1714         thread = (thread_t *)malloc(sizeof(thread_t));  
1715 d322 1
1716 a322 1
1717         thread_t *th = thread_self();
1718 d394 1
1719 a394 1
1720         thread_t *th = thread_self();
1721 d526 1
1722 a526 1
1723         thread_t *th = thread_self();
1724 d601 1
1725 a601 1
1726         thread_t *thread = start->thread;
1727 d636 1
1728 a636 1
1729 thread_t *thread_self(void)
1730 d639 1
1731 a639 1
1732         thread_t *th;
1733 d655 1
1734 a655 1
1735                 th = (thread_t *)node->key;
1736 d676 1
1737 a676 1
1738         thread_t *th;
1739 d705 1
1740 a705 1
1741 void thread_join(thread_t *thread)
1742 d735 1
1743 a735 1
1744         thread_t *t1, *t2;
1745 d737 2
1746 a738 2
1747         t1 = (thread_t *)a;
1748         t2 = (thread_t *)b;
1749 d765 1
1750 a765 1
1751         thread_t *t;
1752 d767 1
1753 a767 1
1754         t = (thread_t *)key;
1755 d781 1
1756 a781 1
1757     thread_t *t = key;
1761 1.16
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.
1768 text
1769 @d710 3
1773 1.15
1775 @Liberally sprinkle #ifdef THREAD_DEBUG around so libshout doesn't need to link
1776 with it.
1778 text
1779 @d105 1
1780 d258 1
1781 d556 1
1782 a556 1
1783                 avl_delete(_threadtree, th, _free_thread);
1784 d619 1
1785 d710 1
1786 d775 7
1790 1.14
1792 @Timing fixes
1794 text
1795 @a40 1
1796 #include "log.h"
1797 d43 3
1798 d51 1
1799 d69 1
1800 d124 1
1801 a125 2
1803 #ifdef THREAD_DEBUG
1804 d180 1
1805 a182 1
1806         log_shutdown();
1807 d205 2
1808 a206 1
1809         if (pthread_sigmask(SIG_BLOCK, &ss, NULL) != 0)
1810 d209 2
1811 d231 2
1812 a232 1
1813         if (pthread_sigmask(SIG_UNBLOCK, &ss, NULL) != 0)
1814 d235 2
1815 d266 1
1816 d269 1
1817 d272 1
1818 d274 1
1819 d549 1
1820 d551 1
1821 d611 1
1822 d613 1
1823 d625 1
1824 d627 1
1825 d641 1
1826 d643 1
1827 d663 1
1828 d665 1
1832 1.13
1834 @Various cleanups
1836 text
1837 @d571 1
1838 a571 1
1839         tv.tv_usec = (len % 1000000) / 1000;
1843 1.12
1845 @oddsock's xslt stats support, slightly cleaned up
1847 text
1848 @d231 1
1849 a231 1
1850 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
1851 d262 1
1852 a262 1
1853                 return -1;
1854 d265 1
1855 a265 2
1856 //      return thread->thread_id;
1857         return thread->sys_thread;
1858 d678 1
1859 a678 1
1860 void thread_join(long thread)
1861 d683 1
1862 a683 1
1863         i = pthread_join(thread, &ret);
1867 1.11
1869 @Cleaned up version of Ciaran Anscomb's relaying patch.
1871 text
1872 @a117 5
1873         /* this must be called to init pthreads-win32 */
1874 #ifdef _WIN32
1875         ptw32_processInitialize();
1876 #endif
1878 d127 1
1879 a127 1
1880         /* create all the interal mutexes, and initialize the mutex tree */
1884 1.10
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
1889 features).
1891 resampling (for live input, not yet for reencoding) is in there.
1893 several patches from Karl Heyes have been incorporated.
1895 text
1896 @d468 12
1897 d486 2
1903 @Don't use start after freeing it in thread startup code.
1905 text
1906 @d50 16
1907 a65 16
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)
1924 a257 1
1931 @win32 patches from Ed
1933 text
1934 @d577 1
1935 d591 1
1936 a591 1
1937         if (start->detached) {
1943 @More win32 fixes.
1945 text
1946 @d28 2
1947 d36 1
1948 a38 2
1949 #include <pthread.h>
1951 d46 1
1952 a46 1
1953 #define __FUNCTION__ __FILE__ ":" __LINE__
1959 @minor build fixes for win32 courtesy of Oddsock
1961 text
1962 @d117 5
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.
1983 text
1984 @d31 3
1985 d43 4
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
1994 per thread.
1996 text
1997 @d223 1
1998 a223 1
1999 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int stacksize, int detached, int line, char *file)
2000 a224 1
2001         pthread_attr_t attr;
2002 a245 2
2003         pthread_attr_init(&attr);
2004         pthread_attr_setstacksize(&attr, stacksize);
2005 d248 1
2006 a248 1
2007         if (pthread_create(&thread->sys_thread, &attr, _start_routine, start) == 0)
2008 a251 2
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.
2019 text
2020 @a58 3
2021 /* INTERNAL DATA */
2022 #define STACKSIZE 8192
2024 d223 1
2025 a223 1
2026 long thread_create_c(char *name, void *(*start_routine)(void *), void *arg, int detached, int line, char *file)
2027 d248 1
2028 a248 1
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.
2038 text
2039 @a26 1
2040 #include <sys/time.h>
2041 d30 1
2042 d42 16
2043 a57 4
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)
2048 d312 1
2049 a312 1
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);
2051 d334 1
2052 a334 1
2053                                         LOG_ERROR("DEADLOCK AVOIDED (%d == %d) on mutex [%s] in file %s line %d by thread %d [%s]", 
2054 d365 1
2055 a365 1
2056         LOG_DEBUG("Locked %p by thread %d", mutex, th ? th->thread_id : -1);
2057 d383 1
2058 a383 1
2059                 LOG_ERROR("No record for %u in unlock [%s:%d]", thread_self(), file, line);
2060 d386 1
2061 a386 1
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);
2063 d403 1
2064 a403 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, 
2066 d430 1
2067 a430 1
2068         LOG_DEBUG("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
2069 d524 1
2070 a524 1
2071                 LOG_INFO("Removing thread %d [%s] started at [%s:%d], reason: 'Thread Exited'", th->thread_id, th->name, th->file, th->line);
2072 d583 1
2073 a583 1
2074         LOG_INFO("Added thread %d [%s] started at [%s:%d]", thread->thread_id, thread->name, thread->file, thread->line);
2080 @Initial revision
2082 text
2083 @d534 1
2084 a534 1
2085         time_sleep.tv_nsec = len % 1000000;
2089 1.1.1.1
2091 @move to cvs
2093 text