From c9d9d4edd69664dd3e91776cb0cedd193cb2ba73 Mon Sep 17 00:00:00 2001 From: Karl Heyes Date: Tue, 7 Jul 2009 20:27:19 +0000 Subject: [PATCH] various bits collected over time. Nothing of major change, the main bits are for cleaning up compiler warnings, to sync up with trunk but to try some small changes for mutex waiting. svn path=/icecast/branches/kh/net/; revision=16214 --- src/net/sock.c | 12 ++++++- src/net/sock.h | 2 +- src/thread/thread.c | 88 +++++++++++++++++++++++++++++++++++---------- src/thread/thread.h | 14 +++++--- 4 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/net/sock.c b/src/net/sock.c index dd1486c9..e7f345d8 100644 --- a/src/net/sock.c +++ b/src/net/sock.c @@ -540,17 +540,27 @@ int sock_read_line(sock_t sock, char *buff, const int len) int sock_connected (sock_t sock, int timeout) { struct pollfd check; + int val = SOCK_ERROR; + socklen_t size = sizeof val; check.fd = sock; check.events = POLLOUT; switch (poll (&check, 1, timeout*1000)) { case 0: return SOCK_TIMEOUT; + default: + /* on windows getsockopt.val is defined as char* */ + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) &val, &size) == 0) + { + if (val == 0) + return 1; + sock_set_error (val); + } + /* fall through */ case -1: if (sock_recoverable (sock_error())) return 0; return SOCK_ERROR; - default: return 1; } } diff --git a/src/net/sock.h b/src/net/sock.h index c6921544..62746cf1 100644 --- a/src/net/sock.h +++ b/src/net/sock.h @@ -30,7 +30,7 @@ #ifdef HAVE_UNISTD_H #include -#elif _WIN32 +#elif _WIN32 #include #endif diff --git a/src/thread/thread.c b/src/thread/thread.c index daec79aa..09030057 100644 --- a/src/thread/thread.c +++ b/src/thread/thread.c @@ -38,6 +38,7 @@ #include +#include #include #include #ifdef THREAD_DEBUG @@ -88,6 +89,7 @@ typedef struct thread_start_tag { static long _next_thread_id = 0; static int _initialized = 0; static avl_tree *_threadtree = NULL; +static int abort_on_mutex_timeout; #ifdef THREAD_DEBUG @@ -185,6 +187,9 @@ void thread_initialize(void) _catch_signals(); + abort_on_mutex_timeout = 0; + if (getenv ("ICE_MUTEX_ABORT")) + abort_on_mutex_timeout = 1; _initialized = 1; } @@ -345,7 +350,7 @@ void thread_mutex_create_c(mutex_t *mutex, int line, const char *file) _mutex_create(mutex); #ifdef THREAD_DEBUG - mutex->name = malloc (strlen (name)+20); + mutex->name = malloc (strlen (file)+20); sprintf (mutex->name, "%s:%d", file, line); _mutex_lock(&_mutextree_mutex); mutex->mutex_id = _next_mutex_id++; @@ -364,7 +369,6 @@ void thread_mutex_destroy (mutex_t *mutex) _mutex_lock(&_mutextree_mutex); avl_delete(_mutextree, mutex, _free_mutex); _mutex_unlock(&_mutextree_mutex); - free (mutex->name); #endif } @@ -396,17 +400,16 @@ void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file) void thread_cond_create_c(cond_t *cond, int line, char *file) { pthread_cond_init(&cond->sys_cond, NULL); - pthread_mutex_init(&cond->cond_mutex, NULL); } void thread_cond_destroy(cond_t *cond) { - pthread_mutex_destroy(&cond->cond_mutex); pthread_cond_destroy(&cond->sys_cond); } void thread_cond_signal_c(cond_t *cond, int line, char *file) { + cond->set = 1; pthread_cond_signal(&cond->sys_cond); } @@ -415,23 +418,20 @@ void thread_cond_broadcast_c(cond_t *cond, int line, char *file) pthread_cond_broadcast(&cond->sys_cond); } -void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file) +void thread_cond_timedwait_c(cond_t *cond, mutex_t *mutex, struct timespec *ts, int line, char *file) { - struct timespec time; + int rc = 0; - time.tv_sec = millis/1000; - time.tv_nsec = (millis - time.tv_sec*1000)*1000000; - - pthread_mutex_lock(&cond->cond_mutex); - pthread_cond_timedwait(&cond->sys_cond, &cond->cond_mutex, &time); - pthread_mutex_unlock(&cond->cond_mutex); + cond->set = 0; + while (cond->set == 0 && rc == 0) + rc = pthread_cond_timedwait(&cond->sys_cond, &mutex->sys_mutex, ts); + if (rc == 0 && cond->set == 1) + cond->set = 0; } -void thread_cond_wait_c(cond_t *cond, int line, char *file) +void thread_cond_wait_c(cond_t *cond, mutex_t *mutex,int line, char *file) { - pthread_mutex_lock(&cond->cond_mutex); - pthread_cond_wait(&cond->sys_cond, &cond->cond_mutex); - pthread_mutex_unlock(&cond->cond_mutex); + pthread_cond_wait(&cond->sys_cond, &mutex->sys_mutex); } void thread_rwlock_create_c(const char *name, rwlock_t *rwlock, int line, const char *file) @@ -518,11 +518,10 @@ void thread_exit_c(long val, int line, char *file) #ifdef THREAD_DEBUG LOG_DEBUG4("Removing thread %d [%s] started at [%s:%d]", th->thread_id, th->name, th->file, th->line); - +#endif _mutex_lock(&_threadtree_mutex); avl_delete(_threadtree, th, _free_thread); _mutex_unlock(&_threadtree_mutex); -#endif } pthread_exit ((void*)val); @@ -649,6 +648,17 @@ void thread_rename(const char *name) static void _mutex_lock(mutex_t *mutex) { + if (abort_on_mutex_timeout) + { + struct timespec now; + int rc; + thread_get_timespec (&now); + now.tv_sec += 4; + rc = pthread_mutex_timedlock (&mutex->sys_mutex, &now); + if (rc == ETIMEDOUT) + abort(); + return; + } pthread_mutex_lock(&mutex->sys_mutex); } @@ -777,3 +787,45 @@ void thread_spin_unlock (spin_t *spin) } #endif + +#ifdef HAVE_CLOCK_GETTIME +void thread_get_timespec (struct timespec *now) +{ + clock_gettime (CLOCK_REALTIME, now); +} +#elif HAVE_GETTIMEOFDAY +void thread_get_timespec (struct timespec *now) +{ + struct timeval mtv; + + gettimeofday (&mtv, NULL); + now->tv_sec = mtv.tv_sec; + now->tv_nsec = mtv.tv_usec*1000; +} +#elif HAVE_FTIME +void thread_get_timespec (struct timespec *now) +{ + struct timeb t; + + ftime (&t); + now->tv_sec = t.time; + now->tv_nsec = t.millitm * 1000000; +} +#endif + + +void thread_time_add_ms (struct timespec *ts, unsigned long value) +{ + if (value > 999) + { + ts->tv_sec += value/1000; + value %= 1000; + } + ts->tv_nsec += (value*1000000); + if (ts->tv_nsec > 999999999) + { + ts->tv_sec++; + ts->tv_nsec -= 1000000000; + } +} + diff --git a/src/thread/thread.h b/src/thread/thread.h index 69939b23..812bbc41 100644 --- a/src/thread/thread.h +++ b/src/thread/thread.h @@ -76,7 +76,7 @@ typedef struct { char *name; #endif - pthread_mutex_t cond_mutex; + int set; pthread_cond_t sys_cond; } cond_t; @@ -126,7 +126,7 @@ typedef mutex_t spin_t; #define thread_cond_signal(x) thread_cond_signal_c(x,__LINE__,__FILE__) #define thread_cond_broadcast(x) thread_cond_broadcast_c(x,__LINE__,__FILE__) #define thread_cond_wait(x) thread_cond_wait_c(x,__LINE__,__FILE__) -#define thread_cond_timedwait(x,t) thread_cond_wait_c(x,t,__LINE__,__FILE__) +#define thread_cond_timedwait(x,m,t) thread_cond_timedwait_c(x,m,t,__LINE__,__FILE__) #define thread_rwlock_create(x) thread_rwlock_create_c(__FILE__,(x),__LINE__,__FILE__) #define thread_rwlock_rlock(x) thread_rwlock_rlock_c(x,__LINE__,__FILE__) #define thread_rwlock_wlock(x) thread_rwlock_wlock_c(x,__LINE__,__FILE__) @@ -183,8 +183,8 @@ void thread_mutex_destroy(mutex_t *mutex); 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); -void thread_cond_wait_c(cond_t *cond, int line, char *file); -void thread_cond_timedwait_c(cond_t *cond, int millis, int line, char *file); +void thread_cond_wait_c(cond_t *cond, mutex_t *mutex, int line, char *file); +void thread_cond_timedwait_c(cond_t *cond, mutex_t *mutex, struct timespec *ts, int line, char *file); void thread_cond_destroy(cond_t *cond); void thread_rwlock_create_c(const char *name, rwlock_t *rwlock, int line, const char *file); void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, const char *file); @@ -210,4 +210,10 @@ void thread_rename(const char *name); /* waits until thread_exit is called for another thread */ void thread_join(thread_type *thread); +void thread_get_timespec (struct timespec *now); +void thread_time_add_ms (struct timespec *now, unsigned long value); + +#define THREAD_TIME_MS(X) ((X)->tv_sec*1000+(X)->tv_nsec/1000000) +#define THREAD_TIME_SEC(X) ((X)->tv_sec) + #endif /* __THREAD_H__ */