thr_mutex.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This library is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU Library General Public
  5.    License as published by the Free Software Foundation; either
  6.    version 2 of the License, or (at your option) any later version.
  7.    
  8.    This library is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.    Library General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU Library General Public
  14.    License along with this library; if not, write to the Free
  15.    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  16.    MA 02111-1307, USA */
  17. /* This makes a wrapper for mutex handling to make it easier to debug mutex */
  18. #include <global.h>
  19. #if defined(HAVE_LINUXTHREADS) && !defined (__USE_UNIX98)
  20. #define __USE_UNIX98 /* To get rw locks under Linux */
  21. #endif
  22. #include <m_string.h>
  23. #if defined(THREAD) && defined(SAFE_MUTEX)
  24. #undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
  25. #include <my_pthread.h>
  26. #ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
  27. /* Remove wrappers */
  28. #undef pthread_mutex_init
  29. #undef pthread_mutex_lock
  30. #undef pthread_mutex_unlock
  31. #undef pthread_mutex_destroy
  32. #undef pthread_cond_wait
  33. #undef pthread_cond_timedwait
  34. #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
  35. #define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b))
  36. #endif
  37. #endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */
  38. int safe_mutex_init(safe_mutex_t *mp,
  39.     const pthread_mutexattr_t *attr __attribute__((unused)))
  40. {
  41.   bzero((char*) mp,sizeof(*mp));
  42. #ifdef HAVE_LINUXTHREADS /* Some extra safety */
  43.   {
  44.     pthread_mutexattr_t tmp;
  45.     pthread_mutexattr_init(&tmp);
  46.     pthread_mutexattr_setkind_np(&tmp,PTHREAD_MUTEX_ERRORCHECK_NP);
  47.     pthread_mutex_init(&mp->global,&tmp);
  48.     pthread_mutex_init(&mp->mutex, &tmp);
  49.     pthread_mutexattr_destroy(&tmp);
  50.   }
  51. #else
  52.   pthread_mutex_init(&mp->global,NULL);
  53.   pthread_mutex_init(&mp->mutex,attr);
  54. #endif
  55.   return 0;
  56. }
  57. int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
  58. {
  59.   int error;
  60.   pthread_mutex_lock(&mp->global);
  61.   if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
  62.   {
  63.     fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %dn",
  64.     file,line,mp->file,mp->line);
  65.     fflush(stderr);
  66.     abort();
  67.   }
  68.   pthread_mutex_unlock(&mp->global);
  69.   error=pthread_mutex_lock(&mp->mutex);
  70.   if (error || (error=pthread_mutex_lock(&mp->global)))
  71.   {
  72.     fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %dn",
  73.     error, file, line);
  74.     fflush(stderr);
  75.     abort();
  76.   }
  77.   if (mp->count++)
  78.   {
  79.     fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 timen", file,line);
  80.     fflush(stderr);
  81.     abort();
  82.   }
  83.   mp->thread=pthread_self();
  84.   mp->file= (char*) file;
  85.   mp->line=line;
  86.   pthread_mutex_unlock(&mp->global);
  87.   return error;
  88. }
  89. int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
  90. {
  91.   int error;
  92.   pthread_mutex_lock(&mp->global);
  93.   if (mp->count == 0)
  94.   {
  95.     fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %dn            Last used at %s, line: %dn",
  96.     file,line,mp->file ? mp->file : "",mp->line);
  97.     fflush(stderr);
  98.     abort();
  99.   }
  100.   if (!pthread_equal(pthread_self(),mp->thread))
  101.   {
  102.     fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d  that was locked by another thread at: %s, line: %dn",
  103.     file,line,mp->file,mp->line);
  104.     fflush(stderr);
  105.     abort();
  106.   }
  107.   mp->count--;
  108. #ifdef __WIN__
  109.   pthread_mutex_unlock(&mp->mutex);
  110.   error=0;
  111. #else
  112.   error=pthread_mutex_unlock(&mp->mutex);
  113.   if (error)
  114.   {
  115.     fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %dn", error, file, line);
  116.     fflush(stderr);
  117.     abort();
  118.   }
  119. #endif /* __WIN__ */
  120.   pthread_mutex_unlock(&mp->global);
  121.   return error;
  122. }
  123. int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
  124.    uint line)
  125. {
  126.   int error;
  127.   pthread_mutex_lock(&mp->global);
  128.   if (mp->count == 0)
  129.   {
  130.     fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %dn",file,line);
  131.     fflush(stderr);
  132.     abort();
  133.   }
  134.   if (!pthread_equal(pthread_self(),mp->thread))
  135.   {
  136.     fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d  that was locked by another thread at: %s, line: %dn",
  137.     file,line,mp->file,mp->line);
  138.     fflush(stderr);
  139.     abort();
  140.   }
  141.   if (mp->count-- != 1)
  142.   {
  143.     fprintf(stderr,"safe_mutex:  Count was %d on locked mutex at %s, line %dn",
  144.     mp->count+1, file, line);
  145.     fflush(stderr);
  146.     abort();
  147.   }
  148.   pthread_mutex_unlock(&mp->global);
  149.   error=pthread_cond_wait(cond,&mp->mutex);
  150.   pthread_mutex_lock(&mp->global);
  151.   if (error)
  152.   {
  153.     fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %dn", error, file, line);
  154.     fflush(stderr);
  155.     abort();
  156.   }
  157.   if (mp->count++)
  158.   {
  159.     fprintf(stderr,
  160.     "safe_mutex:  Count was %d in thread %lx when locking mutex at %s, line %dn",
  161.     mp->count-1, my_thread_id(), file, line);
  162.     fflush(stderr);
  163.     abort();
  164.   }
  165.   mp->thread=pthread_self();
  166.   mp->file= (char*) file;
  167.   mp->line=line;
  168.   pthread_mutex_unlock(&mp->global);
  169.   return error;
  170. }
  171. int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
  172. struct timespec *abstime,
  173. const char *file, uint line)
  174. {
  175.   int error;
  176.   pthread_mutex_lock(&mp->global);
  177.   if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread))
  178.   {
  179.     fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutexn",file,line);
  180.     fflush(stderr);
  181.     abort();
  182.   }
  183.   mp->count--; /* Mutex will be released */
  184.   pthread_mutex_unlock(&mp->global);
  185.   error=pthread_cond_timedwait(cond,&mp->mutex,abstime);
  186. #ifdef EXTRA_DEBUG
  187.   if (error && (error != EINTR && error != ETIMEDOUT))
  188.   {
  189.     fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_timedwait at %s, line %dn", error, file, line);
  190.   }
  191. #endif
  192.   pthread_mutex_lock(&mp->global);
  193.   if (mp->count++)
  194.   {
  195.     fprintf(stderr,
  196.     "safe_mutex:  Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)n",
  197.     mp->count-1, my_thread_id(), file, line, error);
  198.     fflush(stderr);
  199.     abort();
  200.   }
  201.   mp->thread=pthread_self();
  202.   mp->file= (char*) file;
  203.   mp->line=line;
  204.   pthread_mutex_unlock(&mp->global);
  205.   return error;
  206. }
  207. int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
  208. {
  209.   int error=0;
  210.   if (mp->count != 0)
  211.   {
  212.     fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %dn",
  213.     mp->file,mp->line, file, line);
  214.     fflush(stderr);
  215.     abort();
  216.   }
  217. #ifdef __WIN__ 
  218.   pthread_mutex_destroy(&mp->global);
  219.   pthread_mutex_destroy(&mp->mutex);
  220. #else
  221.   if (pthread_mutex_destroy(&mp->global))
  222.     error=1;
  223.   if (pthread_mutex_destroy(&mp->mutex))
  224.     error=1;
  225. #endif
  226.   return error;
  227. }
  228. #endif /* THREAD && SAFE_MUTEX */