[xiph-commits] r16690 - in icecast/branches/kh: net thread

karl at svn.xiph.org karl at svn.xiph.org
Wed Nov 4 21:03:55 PST 2009


Author: karl
Date: 2009-11-04 21:03:55 -0800 (Wed, 04 Nov 2009)
New Revision: 16690

Modified:
   icecast/branches/kh/net/sock.c
   icecast/branches/kh/thread/thread.c
   icecast/branches/kh/thread/thread.h
Log:
subtree sync up. sock.c from kh17 was missed out, this should resolve #1617.
The thread changes allow for enabling extra checks on locks (mutex/rwlock),
on timeout or error report an abort is issued.  This is not enabled by
default but can be enabled by setting environment variable ICE_LOCK_ABORT to
1 for lock timeout or 2 for error checks as well.


Modified: icecast/branches/kh/net/sock.c
===================================================================
--- icecast/branches/kh/net/sock.c	2009-11-03 23:32:04 UTC (rev 16689)
+++ icecast/branches/kh/net/sock.c	2009-11-05 05:03:55 UTC (rev 16690)
@@ -561,7 +561,7 @@
             if (sock_recoverable (sock_error()))
                 return 0;
             return SOCK_ERROR;
-    }                                           
+    }
 }
 
 #else
@@ -953,21 +953,21 @@
     sock_t ret;
     socklen_t slen;
 
-    if (ip == NULL || len == 0 || !sock_valid_socket(serversock))
-        return SOCK_ERROR;
-
     slen = sizeof(sa);
     ret = accept(serversock, (struct sockaddr *)&sa, &slen);
 
     if (ret != SOCK_ERROR)
     {
+        if (ip)
+        {
 #ifdef HAVE_GETNAMEINFO
-        if (getnameinfo ((struct sockaddr *)&sa, slen, ip, len, NULL, 0, NI_NUMERICHOST))
-            snprintf (ip, len, "unknown");
+            if (getnameinfo ((struct sockaddr *)&sa, slen, ip, len, NULL, 0, NI_NUMERICHOST))
+                snprintf (ip, len, "unknown");
 #else
-        /* inet_ntoa is not reentrant, we should protect this */
-        strncpy(ip, inet_ntoa(sa.sin_addr), len);
+            /* inet_ntoa is not reentrant, we should protect this */
+            strncpy(ip, inet_ntoa(sa.sin_addr), len);
 #endif
+        }
         sock_set_nolinger(ret);
         sock_set_keepalive(ret);
     }

Modified: icecast/branches/kh/thread/thread.c
===================================================================
--- icecast/branches/kh/thread/thread.c	2009-11-03 23:32:04 UTC (rev 16689)
+++ icecast/branches/kh/thread/thread.c	2009-11-05 05:03:55 UTC (rev 16690)
@@ -45,9 +45,7 @@
 #include <timing/timing.h>
 #include <thread/thread.h>
 #include <avl/avl.h>
-#ifdef THREAD_DEBUG
 #include <log/log.h>
-#endif
 
 #ifdef _WIN32
 #define __FUNCTION__ __FILE__
@@ -93,7 +91,8 @@
 static long _next_thread_id = 0;
 static int _initialized = 0;
 static avl_tree *_threadtree = NULL;
-static int abort_on_mutex_timeout;
+static int lock_problem_abort;
+static int thread_log;
 
 
 #ifdef THREAD_DEBUG
@@ -125,8 +124,8 @@
 
 #else
 
-static mutex_t _threadtree_mutex = { PTHREAD_MUTEX_INITIALIZER };
-static mutex_t _library_mutex = { PTHREAD_MUTEX_INITIALIZER };
+static mutex_t _threadtree_mutex;
+static mutex_t _library_mutex;
 
 #endif
 
@@ -137,19 +136,23 @@
 
 /* mutex fuctions */
 static void _mutex_create(mutex_t *mutex);
-static void _mutex_lock(mutex_t *mutex);
-static void _mutex_unlock(mutex_t *mutex);
+static void _mutex_lock_c(mutex_t *mutex, const char *file, int line);
+static void _mutex_unlock_c(mutex_t *mutex, const char *file, int line);
 
 /* misc thread stuff */
 static void *_start_routine(void *arg);
 static void _catch_signals(void);
 static void _block_signals(void);
 
+#define _mutex_lock(x)      _mutex_lock_c((x),__FILE__,__LINE__)
+#define _mutex_unlock(x)    _mutex_unlock_c((x),__FILE__,__LINE__)
+
 /* LIBRARY INITIALIZATION */
 
 void thread_initialize(void)
 {
     thread_type *thread;
+    const char *dbg;
 
     /* set up logging */
 
@@ -178,11 +181,11 @@
 
     _threadtree = avl_tree_new(_compare_threads, NULL);
 
-    thread = (thread_type *)malloc(sizeof(thread_type));
+    thread = (thread_type *)calloc(1, sizeof(thread_type));
 
     thread->thread_id = _next_thread_id++;
     thread->line = 0;
-    thread->file = strdup("main.c");
+    thread->file = "main.c";
     thread->sys_thread = pthread_self();
     thread->create_time = time(NULL);
     thread->name = strdup("Main Thread");
@@ -191,12 +194,20 @@
 
     _catch_signals();
 
-    abort_on_mutex_timeout = 0;
-    if (getenv ("ICE_MUTEX_ABORT"))
-        abort_on_mutex_timeout = 1;
+    lock_problem_abort = 0;
+    dbg = getenv ("ICE_LOCK_ABORT");
+    if (dbg)
+        lock_problem_abort = atoi (dbg);
     _initialized = 1;
 }
 
+
+void thread_use_log_id (int log_id)
+{
+    thread_log = log_id;
+}
+
+
 void thread_shutdown(void)
 {
     if (_initialized == 1) {
@@ -275,7 +286,7 @@
 
 
 thread_type *thread_create_c(char *name, void *(*start_routine)(void *), 
-        void *arg, int detached, int line, char *file)
+        void *arg, int detached, int line, const char *file)
 {
     int ok = 1;
     thread_type *thread = NULL;
@@ -293,7 +304,7 @@
             break;
 
         thread->line = line;
-        thread->file = strdup(file);
+        thread->file = file;
 
         _mutex_lock (&_threadtree_mutex);    
         thread->thread_id = _next_thread_id++;
@@ -346,7 +357,17 @@
     mutex->line = -1;
 #endif
 
-    pthread_mutex_init(&mutex->sys_mutex, NULL);
+    if (lock_problem_abort == 2)
+    {
+        pthread_mutexattr_t attr;
+
+        pthread_mutexattr_init (&attr);
+        pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
+        pthread_mutex_init (&mutex->sys_mutex, &attr);
+        pthread_mutexattr_destroy (&attr);
+    }
+    else
+        pthread_mutex_init(&mutex->sys_mutex, NULL);
 }
 
 void thread_mutex_create_c(mutex_t *mutex, int line, const char *file)
@@ -365,9 +386,14 @@
 #endif
 }
 
-void thread_mutex_destroy (mutex_t *mutex)
+void thread_mutex_destroy_c (mutex_t *mutex, int line, const char *file)
 {
-    pthread_mutex_destroy(&mutex->sys_mutex);
+    int rc = pthread_mutex_destroy(&mutex->sys_mutex);
+    if (rc)
+    {
+        log_write (thread_log, 1, "thread/", "mutex", "destroy error triggered at %s:%d (%d)", file, line, rc);
+        abort();
+    }
 
 #ifdef THREAD_DEBUG
     _mutex_lock(&_mutextree_mutex);
@@ -381,7 +407,7 @@
 #ifdef THREAD_DEBUG
     LOG_DEBUG3("Lock on %s requested at %s:%d", mutex->name, file, line);
 #endif
-    _mutex_lock(mutex);
+    _mutex_lock_c(mutex, file, line);
 #ifdef THREAD_DEBUG
     mutex->lock_start = get_count();
     mutex->file = strdup (file);
@@ -392,7 +418,7 @@
 
 void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file)
 {
-    _mutex_unlock(mutex);
+    _mutex_unlock_c(mutex, file, line);
 #ifdef THREAD_DEBUG
     LOG_DEBUG4 ("lock %s, at %s:%d lasted %llu", mutex->name, mutex->file,
             mutex->line, get_count() - mutex->lock_start);
@@ -403,18 +429,25 @@
 
 void thread_cond_create_c(cond_t *cond, int line, char *file)
 {
-    pthread_cond_init(&cond->sys_cond, NULL);
+    int rc = pthread_cond_init(&cond->sys_cond, NULL);
+    if (rc)
+        log_write (thread_log, 1, "thread/", "cond", "create error triggered at %s:%d (%d)", file,line, rc);
 }
 
 void thread_cond_destroy(cond_t *cond)
 {
-    pthread_cond_destroy(&cond->sys_cond);
+    int rc = pthread_cond_destroy(&cond->sys_cond);
+    if (rc)
+        log_write (thread_log, 1, "thread/", "cond", "destroy error triggered at (%d)", rc);
 }
 
 void thread_cond_signal_c(cond_t *cond, int line, char *file)
 {
+    int rc;
     cond->set = 1;
-    pthread_cond_signal(&cond->sys_cond);
+    rc = pthread_cond_signal(&cond->sys_cond);
+    if (rc)
+        log_write (thread_log, 1, "thread/", "cond", "signal error triggered at %s:%d (%d)", file, line, rc);
 }
 
 void thread_cond_broadcast_c(cond_t *cond, int line, char *file)
@@ -431,11 +464,15 @@
         rc = pthread_cond_timedwait(&cond->sys_cond, &mutex->sys_mutex, ts);
     if (rc == 0 && cond->set == 1)
         cond->set = 0;
+    if (rc && rc != ETIMEDOUT)
+        log_write (thread_log, 1, "thread/", "mutex", "timedwait error triggered at %s:%d (%d)", file,line, rc);
 }
 
 void thread_cond_wait_c(cond_t *cond, mutex_t *mutex,int line, char *file)
 {
-    pthread_cond_wait(&cond->sys_cond, &mutex->sys_mutex);
+    int rc = pthread_cond_wait(&cond->sys_cond, &mutex->sys_mutex);
+    if (rc)
+        log_write (thread_log, 1, "thread/", "cond", "wait error triggered at %s:%d (%d)", file,line, rc);
 }
 
 void thread_rwlock_create_c(const char *name, rwlock_t *rwlock, int line, const char *file)
@@ -462,6 +499,20 @@
 #ifdef THREAD_DEBUG
     LOG_DEBUG3("rLock on %s requested at %s:%d", rwlock->name, file, line);
 #endif
+    if (lock_problem_abort)
+    {
+        struct timespec now;
+        int rc;
+        thread_get_timespec (&now);
+        now.tv_sec += 7;
+        rc = pthread_rwlock_timedrdlock (&rwlock->sys_rwlock, &now);
+        if (rc)
+        {
+            log_write (thread_log, 1, "thread/", "rwlock", "rlock error triggered at %s:%d (%d)", file, line, rc);
+            abort();
+        }
+        return;
+    }
     pthread_rwlock_rdlock(&rwlock->sys_rwlock);
 #ifdef THREAD_DEBUG
     LOG_DEBUG3("rLock on %s acquired at %s:%d", rwlock->name, file, line);
@@ -473,6 +524,20 @@
 #ifdef THREAD_DEBUG
     LOG_DEBUG3("wLock on %s requested at %s:%d", rwlock->name, file, line);
 #endif
+    if (lock_problem_abort)
+    {
+        struct timespec now;
+        int rc;
+        thread_get_timespec (&now);
+        now.tv_sec += 7;
+        rc = pthread_rwlock_timedwrlock (&rwlock->sys_rwlock, &now);
+        if (rc)
+        {
+            log_write (thread_log, 1, "thread/", "rwlock", "wlock error triggered at %s:%d (%d)", file, line, rc);
+            abort();
+        }
+        return;
+    }
     pthread_rwlock_wrlock(&rwlock->sys_rwlock);
 #ifdef THREAD_DEBUG
     LOG_DEBUG3("wLock on %s acquired at %s:%d", rwlock->name, file, line);
@@ -481,7 +546,13 @@
 
 void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, const char *file)
 {
-    pthread_rwlock_unlock(&rwlock->sys_rwlock);
+    int rc = pthread_rwlock_unlock(&rwlock->sys_rwlock);
+    if (rc)
+    {
+        log_write (thread_log, 1, "thread/", "rwlock", "unlock error triggered at %s:%d (%d)", file, line, rc);
+        abort ();
+    }
+
 #ifdef THREAD_DEBUG
     LOG_DEBUG3 ("unlock %s, at %s:%d", rwlock->name, file, line);
 #endif
@@ -517,7 +588,7 @@
     th->running = 0;
 #endif
 
-    if (th && th->detached)
+    if (th)
     {
 #ifdef THREAD_DEBUG
         LOG_DEBUG4("Removing thread %d [%s] started at [%s:%d]", th->thread_id,
@@ -574,7 +645,6 @@
 
     /* insert thread into thread tree here */
     _mutex_lock(&_threadtree_mutex);
-    thread->sys_thread = pthread_self();
     avl_insert(_threadtree, (void *)thread);
     _mutex_unlock(&_threadtree_mutex);
 
@@ -650,25 +720,45 @@
     th->name = strdup(name);
 }
 
-static void _mutex_lock(mutex_t *mutex) 
+static void _mutex_lock_c(mutex_t *mutex, const char *file, int line) 
 {
-    if (abort_on_mutex_timeout)
+    if (lock_problem_abort)
     {
         struct timespec now;
         int rc;
         thread_get_timespec (&now);
-        now.tv_sec += 4;
+        now.tv_sec += 7;
         rc = pthread_mutex_timedlock (&mutex->sys_mutex, &now);
-        if (rc == ETIMEDOUT)
+        if (rc)
+        {
+            if (file)
+                log_write (thread_log, 1, "thread/", "mutex", "lock error triggered at %s:%d (%d)", file,line, rc);
+            else
+                log_write (thread_log, 1, "thread/", "mutex", "lock error triggered no reference (%d)", rc);
+            if (mutex->file)
+                log_write (thread_log, 1, "thread/", "mutex", "last lock at %s:%d", mutex->file,mutex->line);
             abort();
+        }
+        mutex->file = file;
+        mutex->line = line;
         return;
     }
     pthread_mutex_lock(&mutex->sys_mutex);
 }
 
-static void _mutex_unlock(mutex_t *mutex)
+static void _mutex_unlock_c(mutex_t *mutex, const char *file, int line)
 {
-    pthread_mutex_unlock(&mutex->sys_mutex);
+    int rc;
+    mutex->file = NULL;
+    rc = pthread_mutex_unlock(&mutex->sys_mutex);
+    if (lock_problem_abort && rc)
+    {
+        if (file)
+            log_write (thread_log, 1, "thread/", "mutex", "unlock error triggered at %s:%d (%d)", file, line, rc);
+        else
+            log_write (thread_log, 1, "thread/", "mutex", "unlock error triggered no reference (%d)", rc);
+        abort ();
+    }
 }
 
 
@@ -754,8 +844,6 @@
 
     t = (thread_type *)key;
 
-    if (t->file)
-        free(t->file);
     if (t->name)
         free(t->name);
 

Modified: icecast/branches/kh/thread/thread.h
===================================================================
--- icecast/branches/kh/thread/thread.h	2009-11-03 23:32:04 UTC (rev 16689)
+++ icecast/branches/kh/thread/thread.h	2009-11-05 05:03:55 UTC (rev 16690)
@@ -34,7 +34,7 @@
     time_t create_time;
     
     /* the file and line which created this thread */
-    char *file;
+    const char *file;
     int line;
 
     /* is the thread running detached? */
@@ -60,12 +60,11 @@
     /* time the lock was taken */
     unsigned long long lock_start;
 
+#endif
     /* the file and line where the mutex was locked */
-    char *file;
+    const char *file;
     int line;    
 
-#endif
-
     /* the system specific mutex */
     pthread_mutex_t sys_mutex;
 } mutex_t;
@@ -89,7 +88,7 @@
     ** this rwlock was write locked
     */
     long thread_id;
-    char *file;
+    const char *file;
     int line;
 
     /* time the lock was taken */
@@ -120,6 +119,7 @@
 
 #define thread_create(n,x,y,z) thread_create_c(n,x,y,z,__LINE__,__FILE__)
 #define thread_mutex_create(x) thread_mutex_create_c(x,__LINE__,__FILE__)
+#define thread_mutex_destroy(x) thread_mutex_destroy_c(x,__LINE__,__FILE__)
 #define thread_mutex_lock(x) thread_mutex_lock_c(x,__LINE__,__FILE__)
 #define thread_mutex_unlock(x) thread_mutex_unlock_c(x,__LINE__,__FILE__)
 #define thread_cond_create(x) thread_cond_create_c(x,__LINE__,__FILE__)
@@ -141,13 +141,13 @@
 
 #ifdef _mangle
 # define thread_initialize _mangle(thread_initialize)
-# define thread_initialize_with_log_id _mangle(thread_initialize_with_log_id)
+# define thread_use_log_id _mangle(thread_use_log_id)
 # define thread_shutdown _mangle(thread_shutdown)
 # define thread_create_c _mangle(thread_create_c)
 # define thread_mutex_create_c _mangle(thread_mutex_create)
 # define thread_mutex_lock_c _mangle(thread_mutex_lock_c)
 # define thread_mutex_unlock_c _mangle(thread_mutex_unlock_c)
-# define thread_mutex_destroy _mangle(thread_mutex_destroy)
+# define thread_mutex_destroy _mangle(thread_mutex_destroy_c)
 # define thread_cond_create_c _mangle(thread_cond_create_c)
 # define thread_cond_signal_c _mangle(thread_cond_signal_c)
 # define thread_cond_broadcast_c _mangle(thread_cond_broadcast_c)
@@ -170,16 +170,16 @@
 
 /* init/shutdown of the library */
 void thread_initialize(void);
-void thread_initialize_with_log_id(int log_id);
 void thread_shutdown(void);
+void thread_use_log_id(int log_id);
 
 /* creation, destruction, locking, unlocking, signalling and waiting */
 thread_type *thread_create_c(char *name, void *(*start_routine)(void *), 
-        void *arg, int detached, int line, char *file);
+        void *arg, int detached, int line, const char *file);
 void thread_mutex_create_c(mutex_t *mutex, int line, const char *file);
 void thread_mutex_lock_c(mutex_t *mutex, int line, char *file);
 void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file);
-void thread_mutex_destroy(mutex_t *mutex);
+void thread_mutex_destroy_c (mutex_t *mutex, int line, const char *file);
 void thread_cond_create_c(cond_t *cond, int line, char *file);
 void thread_cond_signal_c(cond_t *cond, int line, char *file);
 void thread_cond_broadcast_c(cond_t *cond, int line, char *file);



More information about the commits mailing list