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

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 <ndb_global.h>
  14. #include "NdbCondition.h"
  15. #include <NdbMutex.h>
  16. struct NdbCondition
  17. {
  18.     long nWaiters;
  19.     NdbMutex* pNdbMutexWaitersLock;
  20.     HANDLE hSemaphore;
  21.     HANDLE hEventWaitersDone;
  22.     int bWasBroadcast;
  23. };
  24. struct NdbCondition* 
  25. NdbCondition_Create(void)
  26. {
  27.     int result = 0;
  28.     struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
  29.     if(!pNdbCondition)
  30.         return 0;
  31.     
  32.     pNdbCondition->nWaiters = 0;
  33.     pNdbCondition->bWasBroadcast = 0;
  34.     if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
  35.         result = -1;
  36.     else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
  37.         result = -1;
  38.     else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
  39.         result = -1;
  40.     assert(!result);
  41.     return pNdbCondition;
  42. }
  43. int 
  44. NdbCondition_Wait(struct NdbCondition* p_cond,
  45.                   NdbMutex* p_mutex)
  46. {
  47.     int result;
  48.     int bLastWaiter;
  49.     if(!p_cond || !p_mutex)
  50.         return 1;
  51.     
  52.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  53.     p_cond->nWaiters++;
  54.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  55.     
  56.     if(NdbMutex_Unlock(p_mutex))
  57.         return -1;
  58.     result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
  59.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  60.     p_cond->nWaiters--;
  61.     bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
  62.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  63.     
  64.     if(result==WAIT_OBJECT_0 && bLastWaiter)
  65.         SetEvent(p_cond->hEventWaitersDone);
  66.     
  67.     NdbMutex_Lock(p_mutex);
  68.     return result;
  69. }
  70. int 
  71. NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
  72.                          NdbMutex* p_mutex,
  73.                          int msecs)
  74. {
  75.     int result;
  76.     int bLastWaiter;
  77.     if (!p_cond || !p_mutex)
  78.         return 1;
  79.     
  80.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  81.     p_cond->nWaiters++;
  82.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  83.     if(msecs<0)
  84.         msecs = 0;
  85.     if(NdbMutex_Unlock(p_mutex))
  86.         return -1;
  87.     result = WaitForSingleObject(p_cond->hSemaphore, msecs);
  88.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  89.     p_cond->nWaiters--;
  90.     bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
  91.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  92.     if(result!=WAIT_OBJECT_0)
  93.         result = -1;
  94.     if(bLastWaiter)
  95.         SetEvent(p_cond->hEventWaitersDone); 
  96.     NdbMutex_Lock(p_mutex);
  97.     return result;
  98. }
  99. int 
  100. NdbCondition_Signal(struct NdbCondition* p_cond)
  101. {
  102.     int bHaveWaiters;
  103.     if(!p_cond)
  104.         return 1;
  105.     
  106.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  107.     bHaveWaiters = (p_cond->nWaiters > 0);
  108.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  109.     
  110.     if(bHaveWaiters)
  111.         return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
  112.     else
  113.         return 0;
  114. }
  115. int NdbCondition_Broadcast(struct NdbCondition* p_cond)
  116. {
  117.     int bHaveWaiters;
  118.     int result = 0;
  119.     if(!p_cond)
  120.         return 1;
  121.     
  122.     NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
  123.     bHaveWaiters = 0;
  124.     if(p_cond->nWaiters > 0)
  125.     {
  126.         p_cond->bWasBroadcast = !0;
  127.         bHaveWaiters = 1;
  128.     }
  129.     NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
  130.     if(bHaveWaiters)
  131.     {
  132.         if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
  133.             result = -1;
  134.         else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
  135.             result = -1;
  136.         p_cond->bWasBroadcast = 0;
  137.     }
  138.     return result;
  139. }
  140. int NdbCondition_Destroy(struct NdbCondition* p_cond)
  141. {
  142.     int result;
  143.     if(!p_cond)
  144.         return 1;
  145.     
  146.     CloseHandle(p_cond->hEventWaitersDone);
  147.     NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
  148.     result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1); 
  149.     free(p_cond);
  150.     return 0;
  151. }