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

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * -------------------------------------------------------------
  3.  *
  4.  * Module: my_semaphore.c  (Original: semaphore.c from pthreads library)
  5.  *
  6.  * Purpose:
  7.  * Semaphores aren't actually part of the PThreads standard.
  8.  * They are defined by the POSIX Standard:
  9.  *
  10.  * POSIX 1003.1b-1993 (POSIX.1b)
  11.  *
  12.  * -------------------------------------------------------------
  13.  *
  14.  * Pthreads-win32 - POSIX Threads Library for Win32
  15.  * Copyright (C) 1998
  16.  *
  17.  * This library is free software; you can redistribute it and/or
  18.  * modify it under the terms of the GNU Library General Public
  19.  * License as published by the Free Software Foundation; either
  20.  * version 2 of the License, or (at your option) any later version.
  21.  *
  22.  * This library is distributed in the hope that it will be useful,
  23.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  25.  * Library General Public License for more details.
  26.  *
  27.  * You should have received a copy of the GNU Library General Public
  28.  * License along with this library; if not, write to the Free
  29.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  30.  * MA 02111-1307, USA
  31.  */
  32. /*
  33.   NEED_SEM is not used in MySQL and should only be needed under
  34.   Windows CE.
  35.   The big changes compared to the original version was to not allocate
  36.   any additional memory in sem_init() but to instead store everthing
  37.   we need in sem_t.
  38.   TODO:
  39.   To get HAVE_CREATESEMAPHORE we have to define the struct
  40.   in my_semaphore.h
  41. */
  42. #include "mysys_priv.h"
  43. #ifdef __WIN__
  44. #include "my_semaphore.h"
  45. #include <errno.h>
  46. /*
  47.  DOCPUBLIC
  48.       This function initializes an unnamed semaphore. the
  49.       initial value of the semaphore is 'value'
  50.  PARAMETERS
  51.       sem Pointer to an instance of sem_t
  52.       pshared If zero, this semaphore may only be shared between
  53. threads in the same process.
  54. If nonzero, the semaphore can be shared between
  55. processes
  56.       value Initial value of the semaphore counter
  57.  RESULTS
  58.       0 Successfully created semaphore,
  59.      -1 Failed, error in errno
  60.  ERRNO
  61.       EINVAL 'sem' is not a valid semaphore,
  62.       ENOSPC A required resource has been exhausted,
  63.       ENOSYS Semaphores are not supported,
  64.       EPERM The process lacks appropriate privilege
  65. */
  66. int
  67. sem_init (sem_t *sem, int pshared, unsigned int value)
  68. {
  69.   int result = 0;
  70.   if (pshared != 0)
  71.   {
  72.     /*
  73.       We don't support creating a semaphore that can be shared between
  74.       processes
  75.      */
  76.     result = EPERM;
  77.   }
  78.   else
  79.   {
  80. #ifndef HAVE_CREATESEMAPHORE
  81.     sem->value = value;
  82.     sem->event = CreateEvent(NULL,
  83.      FALSE, /* manual reset */
  84.      FALSE, /* initial state */
  85.      NULL);
  86.     if (!sem->event)
  87.       result = ENOSPC;
  88.     else
  89.     {
  90.       if (value)
  91. SetEvent(sem->event);
  92.       InitializeCriticalSection(&sem->sem_lock_cs);
  93.     }
  94. #else /* HAVE_CREATESEMAPHORE */
  95.     *sem = CreateSemaphore (NULL,  /* Always NULL */
  96.     value,  /* Initial value */
  97.     0x7FFFFFFFL, /* Maximum value */
  98.     NULL);  /* Name */
  99.     if (!*sem)
  100.       result = ENOSPC;
  101. #endif /* HAVE_CREATESEMAPHORE */
  102.   }
  103.   if (result != 0)
  104.   {
  105.     errno = result;
  106.     return -1;
  107.   }
  108.   return 0;
  109. } /* sem_init */
  110. /*
  111.   DOCPUBLIC
  112.        This function destroys an unnamed semaphore.
  113.   PARAMETERS
  114.        sem Pointer to an instance of sem_t
  115.  RESULTS
  116.        0 Successfully destroyed semaphore,
  117.        -1 Failed, error in errno
  118.  ERRNO
  119.        EINVAL 'sem' is not a valid semaphore,
  120.        ENOSYS Semaphores are not supported,
  121.        EBUSY Threads (or processes) are currently blocked on 'sem'
  122. */
  123. int
  124. sem_destroy (sem_t * sem)
  125. {
  126.   int result = 0;
  127. #ifdef EXTRA_DEBUG
  128.   if (sem == NULL || *sem == NULL)
  129.   {
  130.     errno=EINVAL;
  131.     return;
  132.   }
  133. #endif /* EXTRA_DEBUG */
  134. #ifndef HAVE_CREATESEMAPHORE
  135.   if (! CloseHandle(sem->event))
  136.     result = EINVAL;
  137.   else
  138.     DeleteCriticalSection(&sem->sem_lock_cs);
  139. #else /* HAVE_CREATESEMAPHORE */
  140.   if (!CloseHandle(*sem))
  141.     result = EINVAL;
  142. #endif /* HAVE_CREATESEMAPHORE */
  143.   if (result)
  144.   {
  145.     errno = result;
  146.     return -1;
  147.   }
  148.   *sem=0; /* Safety */
  149.   return 0;
  150. } /* sem_destroy */
  151. /*
  152.  DOCPUBLIC
  153.       This function tries to wait on a semaphore. If the
  154.       semaphore value is greater than zero, it decreases
  155.       its value by one. If the semaphore value is zero, then
  156.       this function returns immediately with the error EAGAIN
  157.  PARAMETERS
  158.       sem Pointer to an instance of sem_t
  159.  RESULTS
  160.       0 Successfully decreased semaphore,
  161.       -1 Failed, error in errno
  162.  ERRNO
  163.       EAGAIN The semaphore was already locked,
  164.       EINVAL 'sem' is not a valid semaphore,
  165.       ENOSYS Semaphores are not supported,
  166.       EINTR The function was interrupted by a signal,
  167.       EDEADLK A deadlock condition was detected.
  168. */
  169. int
  170. sem_trywait(sem_t * sem)
  171. {
  172. #ifndef HAVE_CREATESEMAPHORE
  173.   /* not yet implemented! */
  174.   int errno = EINVAL;
  175.   return -1;
  176. #else /* HAVE_CREATESEMAPHORE */
  177. #ifdef EXTRA_DEBUG
  178.   if (sem == NULL || *sem == NULL)
  179.   {
  180.     errno=EINVAL;
  181.     return -1;
  182.   }
  183. #endif /* EXTRA_DEBUG */
  184.   if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
  185.   {
  186.     errno= EAGAIN;
  187.     return -1;
  188.   }
  189.   return 0;
  190. #endif /* HAVE_CREATESEMAPHORE */
  191. } /* sem_trywait */
  192. #ifndef HAVE_CREATESEMAPHORE
  193. static void
  194. ptw32_decrease_semaphore(sem_t * sem)
  195. {
  196.   EnterCriticalSection(&sem->sem_lock_cs);
  197.   DBUG_ASSERT(sem->value != 0);
  198.   sem->value--;
  199.   if (sem->value != 0)
  200.     SetEvent(sem->event);
  201.   LeaveCriticalSection(&sem->sem_lock_cs);
  202. }
  203. static BOOL
  204. ptw32_increase_semaphore(sem_t * sem, unsigned int n)
  205. {
  206.   BOOL result=FALSE;
  207.   EnterCriticalSection(&sem->sem_lock_cs);
  208.   if (sem->value + n > sem->value)
  209.   {
  210.     sem->value += n;
  211.     SetEvent(sem->event);
  212.     result = TRUE;
  213.   }
  214.   LeaveCriticalSection(&sem->sem_lock_cs);
  215.   return result;
  216. }
  217. #endif /* HAVE_CREATESEMAPHORE */
  218. /*
  219.  ------------------------------------------------------
  220.  DOCPUBLIC
  221.       This function waits on a semaphore. If the
  222.       semaphore value is greater than zero, it decreases
  223.       its value by one. If the semaphore value is zero, then
  224.       the calling thread (or process) is blocked until it can
  225.       successfully decrease the value or until interrupted by
  226.       a signal.
  227.  PARAMETERS
  228.       sem Pointer to an instance of sem_t
  229.  RESULTS
  230.       0 Successfully decreased semaphore,
  231.      -1 Failed, error in errno
  232.  ERRNO
  233.       EINVAL 'Sem' is not a valid semaphore,
  234.       ENOSYS Semaphores are not supported,
  235.       EINTR The function was interrupted by a signal,
  236.       EDEADLK A deadlock condition was detected.
  237. */
  238. int
  239. sem_wait(sem_t *sem)
  240. {
  241.   int result;
  242. #ifdef EXTRA_DEBUG
  243.   if (sem == NULL || *sem == NULL)
  244.   {
  245.     errno=EINVAL;
  246.     return -1;
  247.   }
  248. #endif /* EXTRA_DEBUG */
  249. #ifndef HAVE_CREATESEMAPHORE
  250.   result=WaitForSingleObject(sem->event, INFINITE);
  251. #else
  252.   result=WaitForSingleObject(*sem, INFINITE);
  253. #endif
  254.   if (result == WAIT_FAILED || result == WAIT_ABANDONED_0)
  255.     result = EINVAL;
  256.   else if (result == WAIT_TIMEOUT)
  257.     result = ETIMEDOUT;
  258.   else
  259.     result=0;
  260.   if (result)
  261.   {
  262.     errno = result;
  263.     return -1;
  264.   }
  265. #ifndef HAVE_CREATESEMAPHORE
  266.   ptw32_decrease_semaphore(sem);
  267. #endif /* HAVE_CREATESEMAPHORE */
  268.   return 0;
  269. }
  270. /*
  271.  ------------------------------------------------------
  272.  DOCPUBLIC
  273.       This function posts a wakeup to a semaphore. If there
  274.       are waiting threads (or processes), one is awakened;
  275.       otherwise, the semaphore value is incremented by one.
  276.  PARAMETERS
  277.       sem Pointer to an instance of sem_t
  278.  RESULTS
  279.       0 Successfully posted semaphore,
  280.       -1 Failed, error in errno
  281.  ERRNO
  282.       EINVAL 'sem' is not a valid semaphore,
  283.       ENOSYS Semaphores are not supported,
  284. */
  285. int
  286. sem_post (sem_t * sem)
  287. {
  288. #ifdef EXTRA_DEBUG
  289.   if (sem == NULL || *sem == NULL)
  290.   {
  291.     errno=EINVAL;
  292.     return -1;
  293.   }
  294. #endif /* EXTRA_DEBUG */
  295. #ifndef HAVE_CREATESEMAPHORE
  296.   if (! ptw32_increase_semaphore(sem, 1))
  297. #else /* HAVE_CREATESEMAPHORE */
  298.   if (! ReleaseSemaphore(*sem, 1, 0))
  299. #endif /* HAVE_CREATESEMAPHORE */
  300.   {
  301.     errno=EINVAL;
  302.     return -1;
  303.   }
  304.   return 0;
  305. }
  306. /*
  307.  ------------------------------------------------------
  308.  DOCPUBLIC
  309.       This function posts multiple wakeups to a semaphore. If there
  310.       are waiting threads (or processes), n <= count are awakened;
  311.       the semaphore value is incremented by count - n.
  312.  PARAMETERS
  313.       sem Pointer to an instance of sem_t
  314.       count Counter, must be greater than zero.
  315.  RESULTS
  316.       0 Successfully posted semaphore,
  317.       -1 Failed, error in errno
  318.  ERRNO
  319.       EINVAL 'sem' is not a valid semaphore or count is less
  320. than or equal to zero.
  321. */
  322. int
  323. sem_post_multiple (sem_t * sem, unsigned int count)
  324. {
  325. #ifdef EXTRA_DEBUG
  326.   if (sem == NULL || *sem == NULL || count <= 0)
  327.   {
  328.     errno=EINVAL;
  329.     return -1;
  330.   }
  331. #endif /* EXTRA_DEBUG */
  332. #ifndef HAVE_CREATESEMAPHORE
  333.   if (! ptw32_increase_semaphore (sem, count))
  334. #else /* HAVE_CREATESEMAPHORE */
  335.   if (! ReleaseSemaphore(*sem, count, 0))
  336. #endif /* HAVE_CREATESEMAPHORE */
  337.   {
  338.     errno = EINVAL;
  339.     return -1;
  340.   }
  341.   return 0;
  342. }
  343. int
  344. sem_getvalue (sem_t *sem, unsigned int *sval)
  345. {
  346.   errno = ENOSYS;
  347.   return -1;
  348. } /* sem_getvalue */
  349. #endif /* __WIN__ */