home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / test1 / mysql_thr.c next >
C/C++ Source or Header  |  1999-10-12  |  7KB  |  256 lines

  1. /* Testing of connecting to MySQL from X threads */
  2.  
  3. #include <windows.h>
  4. #include <process.h>
  5. #include <stdio.h>
  6. #include <mysql.h>
  7. #include <errno.h>
  8.  
  9. #define TEST_COUNT 20
  10.  
  11. /*****************************************************************************
  12. ** The following is to emulate the posix thread interface
  13. *****************************************************************************/
  14.  
  15. typedef HANDLE  pthread_t;
  16. typedef struct thread_attr {
  17.     DWORD    dwStackSize ;
  18.     DWORD    dwCreatingFlag ;
  19.     int    priority ;
  20. } pthread_attr_t ;
  21.  
  22. typedef struct { int dummy; } pthread_condattr_t;
  23. typedef unsigned int uint;
  24.  
  25. typedef struct {
  26.   uint waiting;
  27.   HANDLE semaphore;
  28. } pthread_cond_t;
  29.  
  30. typedef CRITICAL_SECTION pthread_mutex_t;
  31.  
  32. #define pthread_mutex_init(A,B)  InitializeCriticalSection(A)
  33. #define pthread_mutex_lock(A)    (EnterCriticalSection(A),0)
  34. #define pthread_mutex_unlock(A)  LeaveCriticalSection(A)
  35. #define pthread_mutex_destroy(A) DeleteCriticalSection(A)
  36. #define pthread_handler_decl(A,B) unsigned __cdecl A(void *B)
  37. typedef unsigned (__cdecl *pthread_handler)(void *);
  38. #define pthread_self() GetCurrentThread()
  39.  
  40. static unsigned int thread_count;
  41. static pthread_cond_t COND_thread_count;
  42. static pthread_mutex_t LOCK_thread_count;
  43.  
  44. pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
  45.         THR_LOCK_lock,THR_LOCK_isam;
  46.  
  47. /*
  48. ** We have tried to use '_beginthreadex' instead of '_beginthread' here
  49. ** but in this case the program leaks about 512 characters for each
  50. ** created thread !
  51. */
  52.  
  53. int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
  54.            pthread_handler func, void *param)
  55. {
  56.   HANDLE hThread;
  57.  
  58.   hThread=(HANDLE)_beginthread(func,
  59.                    attr->dwStackSize ? attr->dwStackSize :
  60.                    65535,param);
  61.   if ((long) hThread == -1L)
  62.   {
  63.     return(errno ? errno : -1);
  64.   }
  65.   *thread_id=hThread;
  66.   return(0);
  67. }
  68.  
  69. void pthread_exit(unsigned A)
  70. {
  71.   _endthread();
  72. }
  73.  
  74. /*
  75. ** The following simple implementation of conds works as long as
  76. ** only one thread uses pthread_cond_wait at a time.
  77. ** This is coded very carefully to work with thr_lock.
  78. */
  79.  
  80. /*****************************************************************************
  81. ** The following is a simple implementation of posix conditions
  82. *****************************************************************************/
  83.  
  84. int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
  85. {
  86.   cond->waiting=0;
  87.   cond->semaphore=CreateSemaphore(NULL,0,0x7FFFFFFF,(char*) 0);
  88.   if (!cond->semaphore)
  89.     return ENOMEM;
  90.   return 0;
  91. }
  92.  
  93. int pthread_cond_destroy(pthread_cond_t *cond)
  94. {
  95.     return CloseHandle(cond->semaphore) ? 0 : EINVAL;
  96. }
  97.  
  98. int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
  99. {
  100.   InterlockedIncrement(&cond->waiting);
  101.   LeaveCriticalSection(mutex);
  102.   WaitForSingleObject(cond->semaphore,INFINITE);
  103.   InterlockedDecrement(&cond->waiting);
  104.   EnterCriticalSection(mutex);
  105.   return 0 ;
  106. }
  107.  
  108. int pthread_cond_signal(pthread_cond_t *cond)
  109. {
  110.   long prev_count;
  111.   if (cond->waiting)
  112.     ReleaseSemaphore(cond->semaphore,1,&prev_count);
  113.   return 0;
  114. }
  115.  
  116. int pthread_attr_init(pthread_attr_t *connect_att)
  117. {
  118.   connect_att->dwStackSize    = 0;
  119.   connect_att->dwCreatingFlag    = 0;
  120.   connect_att->priority        = 0;
  121.   return 0;
  122. }
  123.  
  124. int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
  125. {
  126.   connect_att->dwStackSize=stack;
  127.   return 0;
  128. }
  129.  
  130. int pthread_attr_setprio(pthread_attr_t *connect_att,int priority)
  131. {
  132.   connect_att->priority=priority;
  133.   return 0;
  134. }
  135.  
  136. int pthread_attr_destroy(pthread_attr_t *connect_att)
  137. {
  138.   return 0;
  139. }
  140.  
  141. /* from my_pthread.c */
  142.  
  143. #ifndef REMOVE_BUG
  144.  
  145. __declspec(thread) int THR_KEY_my_errno;
  146.  
  147. int _my_errno(void)
  148. {
  149.   return THR_KEY_my_errno;
  150. }
  151. #endif
  152.  
  153.  
  154. /*****************************************************************************
  155. ** The test program
  156. *****************************************************************************/
  157.  
  158. pthread_handler_decl(test_thread,arg)
  159. {
  160.   MYSQL mysql;
  161.   MYSQL_RES *res;
  162.  
  163.   mysql_init(&mysql);
  164.   if (!mysql_real_connect(&mysql,NULL,0,0,NULL,0,NULL,0))
  165.   {
  166.     fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql));
  167.     perror("");
  168.     goto end;
  169.   }
  170.   if (mysql_query(&mysql,"select 1") < 0)
  171.   {
  172.     fprintf(stderr,"Query failed (%s)\n",mysql_error(&mysql));
  173.     goto end;
  174.   }
  175.   if (!(res=mysql_store_result(&mysql)))
  176.   {
  177.     fprintf(stderr,"Couldn't get result from query failed\n",
  178.         mysql_error(&mysql));
  179.     goto end;
  180.   }
  181.   mysql_free_result(res);
  182.  
  183. end:
  184.  
  185.   Sleep(1000); /* Win32 sleep */
  186.   mysql_close(&mysql);
  187.  
  188.   pthread_mutex_lock(&LOCK_thread_count);
  189.   thread_count--;
  190.   pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
  191.   pthread_mutex_unlock(&LOCK_thread_count);
  192.   pthread_exit(0);
  193.   return 0;
  194. }
  195.  
  196. int main(int argc,char **argv)
  197. {
  198.   pthread_t tid;
  199.   pthread_attr_t thr_attr;
  200.   int i,error;
  201.  
  202.   if ((error=pthread_cond_init(&COND_thread_count,NULL)))
  203.   {
  204.     fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)",
  205.         error,errno);
  206.     exit(1);
  207.   }
  208.   pthread_mutex_init(&LOCK_thread_count,NULL);
  209.   if ((error=pthread_attr_init(&thr_attr)))
  210.   {
  211.     fprintf(stderr,"Got error: %d from pthread_attr_init (errno: %d)",
  212.         error,errno);
  213.     exit(1);
  214.   }
  215.   if ((error=pthread_attr_setstacksize(&thr_attr,65536L)))
  216.   {
  217.     fprintf(stderr,"Got error: %d from pthread_attr_setstacksize (errno: %d)",
  218.         error,errno);
  219.     exit(1);
  220.   }
  221.  
  222.   printf("Init ok. Creating %d threads\n",TEST_COUNT);
  223.  
  224.   for (i=1 ; i <= TEST_COUNT ; i++)
  225.   {
  226.     int *param= &i;
  227.     if ((error=pthread_mutex_lock(&LOCK_thread_count)))
  228.     {
  229.       fprintf(stderr,"\nGot error: %d from pthread_mutex_lock (errno: %d)",
  230.           error,errno);
  231.       exit(1);
  232.     }
  233.     if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param)))
  234.     {
  235.       fprintf(stderr,"\nGot error: %d from pthread_create (errno: %d)\n",
  236.           error,errno);
  237.       pthread_mutex_unlock(&LOCK_thread_count);
  238.       exit(1);
  239.     }
  240.     thread_count++;
  241.     pthread_mutex_unlock(&LOCK_thread_count);
  242.   }
  243.  
  244.   if ((error=pthread_mutex_lock(&LOCK_thread_count)))
  245.     fprintf(stderr,"\nGot error: %d from pthread_mutex_lock\n",error);
  246.   while (thread_count)
  247.   {
  248.     if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count)))
  249.       fprintf(stderr,"\nGot error: %d from pthread_cond_wait\n",error);
  250.   }
  251.   pthread_mutex_unlock(&LOCK_thread_count);
  252.   pthread_attr_destroy(&thr_attr);
  253.   printf("\nend\n");
  254.   return 0;
  255. }
  256.