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__ */