27 #if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX) 
   29 #include <tds_sysdep_public.h> 
   33 #include <freetds/pushvis.h> 
   36 #define TDS_RAW_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 
   40     pthread_mutex_lock(mtx);
 
   45     return pthread_mutex_trylock(mtx);
 
   50     pthread_mutex_unlock(mtx);
 
   55     return pthread_mutex_init(mtx, NULL);
 
   60     pthread_mutex_destroy(mtx);
 
   68     return pthread_cond_destroy(cond);
 
   72     return pthread_cond_signal(cond);
 
   76     return pthread_cond_wait(cond, mtx);
 
   80 #define TDS_HAVE_MUTEX 1 
   83 typedef pthread_t tds_thread_id;
 
   84 typedef void *(*tds_thread_proc)(
void *arg);
 
   85 #define TDS_THREAD_PROC_DECLARE(name, arg) \ 
   87 #define TDS_THREAD_RESULT(n) ((void*)(intptr_t)(n)) 
   89 static inline int tds_thread_create(
tds_thread *ret, tds_thread_proc proc, 
void *arg)
 
   91     return pthread_create(ret, NULL, proc, arg);
 
   94 static inline int tds_thread_create_detached(tds_thread_proc proc, 
void *arg)
 
   97     int ret = pthread_create(&th, NULL, proc, arg);
 
  103 static inline int tds_thread_join(
tds_thread th, 
void **ret)
 
  105     return pthread_join(th, ret);
 
  108 static inline tds_thread_id tds_thread_get_current_id(
void)
 
  110     return pthread_self();
 
  113 static inline int tds_thread_is_current(tds_thread_id th)
 
  115     return pthread_equal(th, pthread_self());
 
  118 #include <freetds/popvis.h> 
  120 #elif defined(_WIN32) 
  122 #include <freetds/windows.h> 
  127 #define ETIMEDOUT 138 
  136     CRITICAL_SECTION crit;
 
  139 #define TDS_RAW_MUTEX_INITIALIZER { NULL, 0, 0 } 
  155         EnterCriticalSection(&mtx->crit);
 
  156         mtx->thread_id = GetCurrentThreadId();
 
  158         tds_win_mutex_lock(mtx);
 
  167     LeaveCriticalSection(&mtx->crit);
 
  173         DeleteCriticalSection(&mtx->crit);
 
  178 #define TDS_HAVE_MUTEX 1 
  181 typedef void *TDS_CONDITION_VARIABLE;
 
  184     TDS_CONDITION_VARIABLE cv;
 
  193     return tds_raw_cond_timedwait(cond, mtx, -1);
 
  197 typedef DWORD  tds_thread_id;
 
  198 typedef DWORD (WINAPI *tds_thread_proc)(
void *arg);
 
  199 #define TDS_THREAD_PROC_DECLARE(name, arg) \ 
  200     DWORD WINAPI name(void *arg) 
  201 #define TDS_THREAD_RESULT(n) ((DWORD)(int)(n)) 
  203 static inline int tds_thread_create(
tds_thread *ret, tds_thread_proc proc, 
void *arg)
 
  205     *ret = CreateThread(NULL, 0, proc, arg, 0, NULL);
 
  206     return *ret != NULL ? 0 : 11 ;
 
  209 static inline int tds_thread_create_detached(tds_thread_proc proc, 
void *arg)
 
  211     HANDLE h = CreateThread(NULL, 0, proc, arg, 0, NULL);
 
  218 static inline int tds_thread_join(
tds_thread th, 
void **ret)
 
  220     if (WaitForSingleObject(th, INFINITE) == WAIT_OBJECT_0) {
 
  223             if (!GetExitCodeThread(th, &r))
 
  225             *ret = (
void*) (((
char*)0) + r);
 
  235 static inline tds_thread_id tds_thread_get_current_id(
void)
 
  237     return GetCurrentThreadId();
 
  240 static inline int tds_thread_is_current(tds_thread_id th)
 
  242     return th == GetCurrentThreadId();
 
  247 #include <tds_sysdep_public.h> 
  254 #define TDS_RAW_MUTEX_INITIALIZER {} 
  290 #define tds_raw_cond_signal(cond) \ 
  291     FreeTDS_Condition_not_compiled 
  293 #define tds_raw_cond_wait(cond, mtx) \ 
  294     FreeTDS_Condition_not_compiled 
  296 #define tds_raw_cond_timedwait(cond, mtx, timeout_sec) \ 
  297     FreeTDS_Condition_not_compiled 
  302 typedef int tds_thread_id;
 
  304 typedef void *(*tds_thread_proc)(
void *arg);
 
  305 #define TDS_THREAD_PROC_DECLARE(name, arg) \ 
  306     void *name(void *arg) 
  307 #define TDS_THREAD_RESULT(n) ((void*)(intptr_t)(n)) 
  309 #define tds_thread_create(ret, proc, arg) \ 
  310     FreeTDS_Thread_not_compiled 
  312 #define tds_thread_create_detached(proc, arg) \ 
  313     FreeTDS_Thread_not_compiled 
  315 #define tds_thread_join(th, ret) \ 
  316     FreeTDS_Thread_not_compiled 
  318 static inline tds_thread_id tds_thread_get_current_id(
void)
 
  323 static inline int tds_thread_is_current(tds_thread_id th)
 
  330 #  define tds_cond_init tds_raw_cond_init 
  331 #  define tds_cond_destroy tds_raw_cond_destroy 
  332 #  define tds_cond_signal tds_raw_cond_signal 
  333 #  if !ENABLE_EXTRA_CHECKS 
  334 #    define TDS_MUTEX_INITIALIZER TDS_RAW_MUTEX_INITIALIZER 
  335 #    define tds_mutex tds_raw_mutex 
  336 #    define tds_mutex_lock tds_raw_mutex_lock 
  337 #    define tds_mutex_trylock tds_raw_mutex_trylock 
  338 #    define tds_mutex_unlock tds_raw_mutex_unlock 
  339 #    define tds_mutex_check_owned(mtx) do {} while(0) 
  340 #    define tds_mutex_init tds_raw_mutex_init 
  341 #    define tds_mutex_free tds_raw_mutex_free 
  342 #    define tds_cond_wait tds_raw_cond_wait 
  343 #    define tds_cond_timedwait tds_raw_cond_timedwait 
  347 typedef struct tds_mutex
 
  351     volatile tds_thread_id locked_by;
 
  354 #   define TDS_MUTEX_INITIALIZER { TDS_RAW_MUTEX_INITIALIZER, 0 } 
  356 static inline void tds_mutex_lock(tds_mutex *mtx)
 
  359     tds_raw_mutex_lock(&mtx->mtx);
 
  360     assert(!mtx->locked);
 
  362     mtx->locked_by = tds_thread_get_current_id();
 
  365 static inline int tds_mutex_trylock(tds_mutex *mtx)
 
  369     ret = tds_raw_mutex_trylock(&mtx->mtx);
 
  371         assert(!mtx->locked);
 
  373         mtx->locked_by = tds_thread_get_current_id();
 
  378 static inline void tds_mutex_unlock(tds_mutex *mtx)
 
  380     assert(mtx && mtx->locked);
 
  382     tds_raw_mutex_unlock(&mtx->mtx);
 
  385 static inline void tds_mutex_check_owned(tds_mutex *mtx)
 
  389     ret = tds_raw_mutex_trylock(&mtx->mtx);
 
  392     assert(tds_thread_is_current(mtx->locked_by));
 
  395 static inline int tds_mutex_init(tds_mutex *mtx)
 
  398     return tds_raw_mutex_init(&mtx->mtx);
 
  401 static inline void tds_mutex_free(tds_mutex *mtx)
 
  403     assert(mtx && !mtx->locked);
 
  404     tds_raw_mutex_free(&mtx->mtx);
 
  407 static inline int tds_cond_wait(
tds_condition *cond, tds_mutex *mtx)
 
  410     assert(mtx && mtx->locked);
 
  412     ret = tds_raw_cond_wait(cond, &mtx->mtx);
 
  414     mtx->locked_by = tds_thread_get_current_id();
 
  418 static inline int tds_cond_timedwait(
tds_condition *cond, tds_mutex *mtx, 
int timeout_sec)
 
  421     assert(mtx && mtx->locked);
 
  423     ret = tds_raw_cond_timedwait(cond, &mtx->mtx, timeout_sec);
 
  425     mtx->locked_by = tds_thread_get_current_id();