NdbCondition.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <winsock2.h>
  14. #include <ws2tcpip.h>
  15. #include <windows.h>
  16. #include <sys/types.h>
  17. #include "NdbCondition.h"
  18. #include <NdbMutex.h>
  19. struct NdbCondition
  20. {
  21.     long nWaiters;
  22.     NdbMutex* pNdbMutexWaitersLock;
  23.     HANDLE hSemaphore;
  24.     HANDLE hEventWaitersDone;
  25.     int bWasBroadcast;
  26. };
  27. struct NdbCondition* 
  28. NdbCondition_Create(void)
  29. {
  30.     int result = 0;
  31.     struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
  32.     if(!pNdbCondition)
  33.         return 0;
  34.     
  35.     pNdbCondition->nWaiters = 0;
  36.     pNdbCondition->bWasBroadcast = 0;
  37.     if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
  38.         result = -1;
  39.     else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
  40.         result = -1;
  41.     else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
  42.         result = -1;
  43.     assert(!result);
  44.     return pNdbCondition;
  45. }
  46. int 
  47. NdbCondition_Wait(struct NdbCondition* p_cond,
  48.                   NdbMutex* p_mutex)
  49. {
  50.     int result;
  51.     int bLastWaiter;
  52.     if(!p_cond || !p_mutex)
  53.         return 1;
  54.     
  55.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  56.     p_cond->nWaiters++;
  57.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  58.     
  59.     if(NdbMutex_Unlock(p_mutex))
  60.         return -1;
  61.     result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
  62.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  63.     p_cond->nWaiters--;
  64.     bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
  65.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  66.     
  67.     if(result==WAIT_OBJECT_0 && bLastWaiter)
  68.         SetEvent(p_cond->hEventWaitersDone);
  69.     
  70.     NdbMutex_Lock(p_mutex);
  71.     return result;
  72. }
  73. int 
  74. NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
  75.                          NdbMutex* p_mutex,
  76.                          int msecs)
  77. {
  78.     int result;
  79.     int bLastWaiter;
  80.     if (!p_cond || !p_mutex)
  81.         return 1;
  82.     
  83.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  84.     p_cond->nWaiters++;
  85.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  86.     if(msecs<0)
  87.         msecs = 0;
  88.     if(NdbMutex_Unlock(p_mutex))
  89.         return -1;
  90.     result = WaitForSingleObject(p_cond->hSemaphore, msecs);
  91.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  92.     p_cond->nWaiters--;
  93.     bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
  94.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  95.     if(result!=WAIT_OBJECT_0)
  96.         result = -1;
  97.     if(bLastWaiter)
  98.         SetEvent(p_cond->hEventWaitersDone); 
  99.     NdbMutex_Lock(p_mutex);
  100.     return result;
  101. }
  102. int 
  103. NdbCondition_Signal(struct NdbCondition* p_cond)
  104. {
  105.     int bHaveWaiters;
  106.     if(!p_cond)
  107.         return 1;
  108.     
  109.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  110.     bHaveWaiters = (p_cond->nWaiters > 0);
  111.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  112.     
  113.     if(bHaveWaiters)
  114.         return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
  115.     else
  116.         return 0;
  117. }
  118. int NdbCondition_Broadcast(struct NdbCondition* p_cond)
  119. {
  120.     int bHaveWaiters;
  121.     int result = 0;
  122.     if(!p_cond)
  123.         return 1;
  124.     
  125.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  126.     bHaveWaiters = 0;
  127.     if(p_cond->nWaiters > 0)
  128.     {
  129.         p_cond->bWasBroadcast = !0;
  130.         bHaveWaiters = 1;
  131.     }
  132.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  133.     if(bHaveWaiters)
  134.     {
  135.         if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
  136.             result = -1;
  137.         else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
  138.             result = -1;
  139.         p_cond->bWasBroadcast = 0;
  140.     }
  141.     return result;
  142. }
  143. int NdbCondition_Destroy(struct NdbCondition* p_cond)
  144. {
  145.     int result;
  146.     if(!p_cond)
  147.         return 1;
  148.     
  149.     CloseHandle(p_cond->hEventWaitersDone);
  150.     NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
  151.     result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1); 
  152.     free(p_cond);
  153.     return 0;
  154. }