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

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 "NdbCondition.h"
  14. #include <pthread.h>
  15. #include <sys/types.h>
  16. #include <malloc.h>
  17. #include <NdbMutex.h>
  18. #include "NdbConditionOSE.h"
  19. struct NdbCondition
  20. {
  21.   PROCESS condserv_pid;
  22. };
  23. OS_PROCESS(ndbcond_serv){
  24.   union SIGNAL* sig;
  25.   union SIGNAL* sig2;
  26.   static const SIGSELECT sel_signal[] = {2, NDBCOND_SIGNAL, NDBCOND_BROADCAST};
  27.   static const SIGSELECT sel_cond[] = {2, NDBCOND_WAIT, NDBCOND_WAITTIMEOUT};
  28.   for(;;){
  29.     /* Receive condition wait signal */
  30.     sig = receive((SIGSELECT*)sel_cond);
  31.     if (sig != NIL){
  32.       switch (sig->sigNo){
  33.       case NDBCOND_WAIT:
  34.         /* Wait for a SIGNAL or BROADCAST from anyone */
  35.         sig2 = receive((SIGSELECT*)sel_signal);
  36.         if (sig2 != NIL){ 
  37.           switch(sig2->sigNo){
  38.           case NDBCOND_SIGNAL:
  39.             ((struct NdbCondWait*)sig)->status = NDBCOND_SIGNALED;
  40.             /* Send signal back to the one waiting for this condition */
  41.             send(&sig, sender(&sig));
  42.             break;
  43.           case NDBCOND_BROADCAST:
  44.             /* Not handled yet */
  45.             assert(1==0);
  46.             break;
  47.           default:
  48.             assert(1==0);
  49.             break;
  50.           }         
  51.           free_buf(&sig2);
  52.         }
  53.         break;
  54.       case NDBCOND_WAITTIMEOUT:
  55.         /* Wait for a SIGNAL or BROADCAST from anyone */
  56.         sig2 = receive_w_tmo(((struct NdbCondWaitTimeout*)sig)->timeout, (SIGSELECT*)sel_signal);
  57.         if (sig2 != NIL){ 
  58.           switch(sig2->sigNo){
  59.           case NDBCOND_SIGNAL:
  60.             ((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_SIGNALED;
  61.             /* Send signal back to the one waiting for this condition */
  62.             send(&sig, sender(&sig));
  63.             break;
  64.           case NDBCOND_BROADCAST:
  65.             /* Not handled yet */
  66.             assert(1==0);
  67.             break;
  68.           default:
  69.             assert(1==0);
  70.             break;
  71.           }         
  72.           free_buf(&sig2);
  73.         }else{
  74.           ((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_TIMEOUT;
  75.           send(&sig, sender(&sig)); 
  76.         }
  77.         break;
  78.       default:
  79.         assert(1==0);
  80.         break;
  81.       
  82.       }
  83.     }
  84.   } 
  85. }
  86. struct NdbCondition* 
  87. NdbCondition_Create(void)
  88. {
  89.   struct NdbCondition* tmpCond;
  90.  
  91.   
  92.   tmpCond = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
  93.   
  94.   if (tmpCond == NULL)
  95.     return NULL;
  96.   /**
  97.    * Start this process with a quite high 
  98.    * priority, we want it to be responsive 
  99.    */ 
  100.   tmpCond->condserv_pid = create_process(OS_PRI_PROC,    /* Process type */
  101.                                          "ndbcond_serv", /* Name */
  102.                                          ndbcond_serv,   /* Entry point */
  103.                                          2048,           /* Stack size */
  104.                                          10,             /* Priority */
  105.                                          0,              /* Time slice */
  106.                                          get_bid(current_process()), /* Block */
  107.                                          NULL,           /* Redir table */
  108.                                          0,
  109.                                          0);  
  110.   
  111.   start(tmpCond->condserv_pid);
  112.   return tmpCond;
  113. }
  114. int 
  115. NdbCondition_Wait(struct NdbCondition* p_cond,
  116.                   NdbMutex* p_mutex)
  117. {
  118.   static const SIGSELECT sel_cond[] = {1, NDBCOND_WAIT};
  119.   union SIGNAL* sig;
  120.   int result;
  121.   if (p_cond == NULL || p_mutex == NULL)
  122.     return 0;
  123.   
  124.   sig = alloc(sizeof(struct NdbCondWait), NDBCOND_WAIT);
  125.   send(&sig, p_cond->condserv_pid);
  126.   NdbMutex_Unlock(p_mutex);
  127.   
  128.   result = 1;
  129.   while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
  130.   if (sig != NIL){
  131.     if (sig->sigNo == NDBCOND_WAIT){
  132.       /* Condition is signaled */
  133.       result = 0;
  134.     }else{
  135.       assert(1==0);
  136.     }
  137.     free_buf(&sig);
  138.     
  139.   }
  140.   NdbMutex_Lock(p_mutex);
  141.   return result;
  142. }
  143. int 
  144. NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
  145.                          NdbMutex* p_mutex,
  146.                          int msecs){
  147.   static const SIGSELECT sel_cond[] = {1, NDBCOND_WAITTIMEOUT};
  148.   union SIGNAL* sig;
  149.   int result;  
  150.   if (p_cond == NULL || p_mutex == NULL)
  151.     return 0;
  152.   
  153.   sig = alloc(sizeof(struct NdbCondWaitTimeout), NDBCOND_WAITTIMEOUT);
  154.   ((struct NdbCondWaitTimeout*)sig)->timeout = msecs;
  155.   send(&sig, p_cond->condserv_pid);
  156.   NdbMutex_Unlock(p_mutex);
  157.   
  158.   result = 1;
  159.   while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
  160.   if (sig != NIL){
  161.     if (sig->sigNo == NDBCOND_WAITTIMEOUT){
  162.       /* Condition is signaled */
  163.       result = 0;
  164.     }else{
  165.       assert(1==0);
  166.     }
  167.     free_buf(&sig);
  168.     
  169.   }
  170.   
  171.   NdbMutex_Lock(p_mutex);
  172.   
  173.   return result;
  174. }
  175. int
  176. NdbCondition_Signal(struct NdbCondition* p_cond){
  177.   union SIGNAL* sig;
  178.   if (p_cond == NULL)
  179.     return 1;
  180.   sig = alloc(sizeof(struct NdbCondSignal), NDBCOND_SIGNAL);
  181.   send(&sig, p_cond->condserv_pid);
  182.                              
  183.   return 0;
  184. }
  185. int NdbCondition_Broadcast(struct NdbCondition* p_cond)
  186. {
  187.   union SIGNAL* sig;
  188.   if (p_cond == NULL)
  189.     return 1;
  190.   sig = alloc(sizeof(struct NdbCondBroadcast), NDBCOND_BROADCAST);
  191.   send(&sig, p_cond->condserv_pid);
  192.                              
  193.   return 0;
  194. }
  195. int NdbCondition_Destroy(struct NdbCondition* p_cond)
  196. {
  197.   if (p_cond == NULL)
  198.     return 1;
  199.   kill_proc(p_cond->condserv_pid);
  200.   free(p_cond);
  201.   return 0;
  202. }