Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/pthread.cc')
-rw-r--r--winsup/cygwin/pthread.cc65
1 files changed, 64 insertions, 1 deletions
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index 57b746ba5..275e566ab 100644
--- a/winsup/cygwin/pthread.cc
+++ b/winsup/cygwin/pthread.cc
@@ -12,7 +12,9 @@
#include "winsup.h"
#include "thread.h"
-#include "errno.h"
+#include "cygerrno.h"
+#include <stdarg.h>
+#include <sys/fcntl.h>
extern "C"
{
@@ -157,6 +159,55 @@ sem_destroy (sem_t * sem)
return semaphore::destroy (sem);
}
+/* Mangle semaphore name to follow windows naming rules. Prepend "Global\"
+ if running on terminal service aware machine. Substitute invalid backslash
+ by forward slash characters, hoping not to collide. */
+static bool
+mangle_sem_name (char *mangled, const char *name)
+{
+ if (check_null_empty_str_errno (name))
+ return false;
+ int len = strlen (name);
+ if (len > MAX_PATH
+ || (wincap.has_terminal_services () && len > MAX_PATH - 7))
+ {
+ set_errno (EINVAL);
+ return false;
+ }
+ strcpy (mangled, wincap.has_terminal_services () ? "Global\\" : "");
+ char *d = mangled + strlen (mangled);
+ const char *s = name;
+ while (*s)
+ *d++ = (*s == '\\') ? '/' : *s++;
+ *d = '\0';
+ return true;
+}
+
+sem_t *
+sem_open (const char *name, int oflag, ...)
+{
+ mode_t mode = 0;
+ unsigned int value = 0;
+ if (oflag & O_CREAT)
+ {
+ va_list ap;
+ va_start (ap, oflag);
+ mode = va_arg (ap, mode_t);
+ value = va_arg (ap, unsigned int);
+ va_end (ap);
+ }
+ char mangled_name[MAX_PATH + 1];
+ if (!mangle_sem_name (mangled_name, name))
+ return NULL;
+ return semaphore::open (mangled_name, oflag, mode, value);
+}
+
+int
+sem_close (sem_t * sem)
+{
+ return semaphore::destroy (sem);
+}
+
int
sem_wait (sem_t * sem)
{
@@ -170,9 +221,21 @@ sem_trywait (sem_t * sem)
}
int
+sem_timedwait (sem_t * sem, const struct timespec *abstime)
+{
+ return semaphore::timedwait (sem, abstime);
+}
+
+int
sem_post (sem_t * sem)
{
return semaphore::post (sem);
}
+int
+sem_getvalue (sem_t * sem, int *sval)
+{
+ return semaphore::getvalue (sem, sval);
+}
+
}