diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2003-04-20 16:42:06 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2003-04-20 16:42:06 +0000 |
commit | ce4f3efd78c110c015c54eab05f201d1caac5f8d (patch) | |
tree | 668c555d5de70518b93426f45fe3e44d7f06663c /win32/contrib/pthreads/semaphore.c | |
parent | 80f6215b607f0ed76f7f75deaf4e4668bc6f244d (diff) | |
download | xine-lib-ce4f3efd78c110c015c54eab05f201d1caac5f8d.tar.gz xine-lib-ce4f3efd78c110c015c54eab05f201d1caac5f8d.tar.bz2 |
importing win32 contrib sources and msvc build environment
CVS patchset: 4641
CVS date: 2003/04/20 16:42:06
Diffstat (limited to 'win32/contrib/pthreads/semaphore.c')
-rw-r--r-- | win32/contrib/pthreads/semaphore.c | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/win32/contrib/pthreads/semaphore.c b/win32/contrib/pthreads/semaphore.c new file mode 100644 index 000000000..2f43d05c9 --- /dev/null +++ b/win32/contrib/pthreads/semaphore.c @@ -0,0 +1,557 @@ +/*
+ * -------------------------------------------------------------
+ *
+ * Module: semaphore.c
+ *
+ * Purpose:
+ * Semaphores aren't actually part of the PThreads standard.
+ * They are defined by the POSIX Standard:
+ *
+ * POSIX 1003.1b-1993 (POSIX.1b)
+ *
+ * -------------------------------------------------------------
+ *
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright (C) 1998
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA
+ */
+
+/* ignore warning "unreferenced formal parameter" */
+#ifdef _MSC_VER
+#pragma warning( disable : 4100 )
+#endif
+
+#include "pthread.h"
+#include "semaphore.h"
+#include "implement.h"
+
+int
+sem_init (sem_t * sem, int pshared, unsigned int value)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function initializes an unnamed semaphore. the
+ * initial value of the semaphore is 'value'
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * pshared
+ * if zero, this semaphore may only be shared between
+ * threads in the same process.
+ * if nonzero, the semaphore can be shared between
+ * processes
+ *
+ * value
+ * initial value of the semaphore counter
+ *
+ * DESCRIPTION
+ * This function initializes an unnamed semaphore. The
+ * initial value of the semaphore is set to 'value'.
+ *
+ * RESULTS
+ * 0 successfully created semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSPC a required resource has been exhausted,
+ * ENOSYS semaphores are not supported,
+ * EPERM the process lacks appropriate privilege
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s;
+
+ if (pshared != 0)
+ {
+ /*
+ * Creating a semaphore that can be shared between
+ * processes
+ */
+ result = EPERM;
+
+ }
+ else
+ {
+ s = (sem_t) calloc (1, sizeof (*s));
+
+#ifdef NEED_SEM
+
+ if (NULL == s)
+ {
+ result = ENOMEM;
+ }
+ else
+ {
+ s->value = value;
+ s->event = CreateEvent (NULL,
+ FALSE, /* manual reset */
+ FALSE, /* initial state */
+ NULL);
+ if (0 == s->Event)
+ {
+ result = ENOSPC;
+ }
+ else
+ {
+ if (value != 0)
+ {
+ SetEvent(s->event);
+ }
+
+ InitializeCriticalSection(&s->sem_lock_cs);
+ }
+
+#else /* NEED_SEM */
+
+ s->sem = CreateSemaphore (NULL, /* Always NULL */
+ value, /* Initial value */
+ 0x7FFFFFFFL, /* Maximum value */
+ NULL); /* Name */
+
+ if (0 == s->sem)
+ {
+ result = ENOSPC;
+ }
+
+#endif /* NEED_SEM */
+
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ *sem = s;
+
+ return 0;
+
+} /* sem_init */
+
+
+int
+sem_destroy (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function destroys an unnamed semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function destroys an unnamed semaphore.
+ *
+ * RESULTS
+ * 0 successfully destroyed semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EBUSY threads (or processes) are currently
+ * blocked on 'sem'
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+ sem_t s;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+ s = *sem;
+ *sem = NULL;
+
+#ifdef NEED_SEM
+
+ if (! CloseHandle(s->event))
+ {
+ *sem = s;
+ result = EINVAL;
+ }
+ else
+ {
+ DeleteCriticalSection(&s->sem_lock_cs);
+ free(s);
+ }
+
+#else /* NEED_SEM */
+
+ if (! CloseHandle (s->sem))
+ {
+ *sem = s;
+ result = EINVAL;
+ }
+
+#endif /* NEED_SEM */
+
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_destroy */
+
+
+int
+sem_trywait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function tries to wait on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function tries to wait on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * this function returns immediately with the error EAGAIN
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EAGAIN the semaphore was already locked,
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+#ifdef NEED_SEM
+
+ /*
+ * not yet implemented!
+ */
+ int result = EINVAL;
+ return -1;
+
+#else /* NEED_SEM */
+
+ int result = 0;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else if (WaitForSingleObject ((*sem)->sem, 0) == WAIT_TIMEOUT)
+ {
+ result = EAGAIN;
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+#endif /* NEED_SEM */
+
+} /* sem_trywait */
+
+
+#ifdef NEED_SEM
+
+void
+ptw32_decrease_semaphore(sem_t * sem)
+{
+ register sem_t s = *sem;
+
+ EnterCriticalSection(&s->sem_lock_cs);
+
+ if (s->value != 0)
+ {
+ s->value--;
+ if (s->value != 0)
+ {
+ SetEvent(s->event);
+ }
+ }
+ else
+ {
+ /* this case should not happen! */
+ }
+
+ LeaveCriticalSection(&s->sem_lock_cs);
+}
+
+BOOL
+ptw32_increase_semaphore(sem_t * sem, unsigned int n)
+{
+ BOOL result;
+ register sem_t s = *sem;
+
+ EnterCriticalSection(&s->sem_lock_cs);
+
+ if (s->value + n > s->value)
+ {
+ s->value += n;
+ SetEvent(s->event);
+ result = TRUE;
+ }
+ else
+ {
+ result = FALSE;
+ }
+
+ LeaveCriticalSection(&s->sem_lock_cs);
+ return result;
+}
+
+#endif /* NEED_SEM */
+
+int
+sem_wait (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function waits on a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function waits on a semaphore. If the
+ * semaphore value is greater than zero, it decreases
+ * its value by one. If the semaphore value is zero, then
+ * the calling thread (or process) is blocked until it can
+ * successfully decrease the value or until interrupted by
+ * a signal.
+ *
+ * RESULTS
+ * 0 successfully decreased semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ * EINTR the function was interrupted by a signal,
+ * EDEADLK a deadlock condition was detected.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+ else
+ {
+
+#ifdef NEED_SEM
+
+ result = pthreadCancelableWait ((*sem)->event);
+
+#else /* NEED_SEM */
+
+ result = pthreadCancelableWait ((*sem)->sem);
+
+#endif /* NEED_SEM */
+
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+#ifdef NEED_SEM
+
+ ptw32_decrease_semaphore(sem);
+
+#endif /* NEED_SEM */
+
+ return 0;
+
+} /* sem_wait */
+
+
+int
+sem_post (sem_t * sem)
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts a wakeup to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * DESCRIPTION
+ * This function posts a wakeup to a semaphore. If there
+ * are waiting threads (or processes), one is awakened;
+ * otherwise, the semaphore value is incremented by one.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore,
+ * ENOSYS semaphores are not supported,
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (sem == NULL || *sem == NULL)
+ {
+ result = EINVAL;
+ }
+
+#ifdef NEED_SEM
+
+ else if (! ptw32_increase_semaphore (sem, 1))
+
+#else /* NEED_SEM */
+
+ else if (! ReleaseSemaphore ((*sem)->sem, 1, 0))
+
+#endif /* NEED_SEM */
+
+ {
+ result = EINVAL;
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post */
+
+
+int
+sem_post_multiple (sem_t * sem, int count )
+ /*
+ * ------------------------------------------------------
+ * DOCPUBLIC
+ * This function posts multiple wakeups to a semaphore.
+ *
+ * PARAMETERS
+ * sem
+ * pointer to an instance of sem_t
+ *
+ * count
+ * counter, must be greater than zero.
+ *
+ * DESCRIPTION
+ * This function posts multiple wakeups to a semaphore. If there
+ * are waiting threads (or processes), n <= count are awakened;
+ * the semaphore value is incremented by count - n.
+ *
+ * RESULTS
+ * 0 successfully posted semaphore,
+ * -1 failed, error in errno
+ * ERRNO
+ * EINVAL 'sem' is not a valid semaphore
+ * or count is less than or equal to zero.
+ *
+ * ------------------------------------------------------
+ */
+{
+ int result = 0;
+
+ if (sem == NULL || *sem == NULL || count <= 0)
+ {
+ result = EINVAL;
+ }
+
+#ifdef NEED_SEM
+
+ else if (! ptw32_increase_semaphore (sem, count))
+
+#else /* NEED_SEM */
+
+ else if (! ReleaseSemaphore ((*sem)->sem, count, 0))
+
+#endif /* NEED_SEM */
+
+ {
+ result = EINVAL;
+ }
+
+ if (result != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ return 0;
+
+} /* sem_post_multiple */
+
+
+int
+sem_open (const char * name, int oflag, mode_t mode, unsigned int value)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_open */
+
+
+int
+sem_close (sem_t * sem)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_close */
+
+
+int
+sem_unlink (const char * name)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_unlink */
+
+
+int
+sem_getvalue (sem_t * sem, int * sval)
+{
+ errno = ENOSYS;
+ return -1;
+} /* sem_getvalue */
+
|