aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in5
-rw-r--r--xbmc/osx/Makefile1
-rw-r--r--xbmc/osx/SemaphoreDarwin.cpp70
-rw-r--r--xbmc/osx/SemaphoreDarwin.h23
-rw-r--r--xbmc/posix/Makefile11
-rw-r--r--xbmc/posix/SemaphorePOSIX.cpp75
-rw-r--r--xbmc/posix/SemaphorePOSIX.h23
-rw-r--r--xbmc/utils/ISemaphore.h27
-rw-r--r--xbmc/utils/Semaphore.cpp56
-rw-r--r--xbmc/utils/Semaphore.hpp22
10 files changed, 312 insertions, 1 deletions
diff --git a/Makefile.in b/Makefile.in
index 87097c3ba0..3d67c982b5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -243,6 +243,8 @@ xbmc/lib/libsquish/libsquish-@ARCH@.a: force
$(MAKE) -C xbmc/lib/libsquish
xbmc/linux/linux.a: force
$(MAKE) -C xbmc/linux
+xbmc/posix/posix.a: force
+ $(MAKE) -C xbmc/posix
xbmc/screensavers/screensaver.a: force
$(MAKE) -C xbmc/screensavers
xbmc/settings/settings.a: force
@@ -388,7 +390,8 @@ OBJSXBMC= \
xbmc/lib/libsquish/libsquish-@ARCH@.a \
xbmc/screensavers/screensaver.a \
xbmc/settings/settings.a \
- xbmc/visualizations/visualization.a
+ xbmc/visualizations/visualization.a \
+ xbmc/posix/posix.a
ifeq (@HAVE_XBMC_NONFREE@,1)
OBJSXBMC+= \
diff --git a/xbmc/osx/Makefile b/xbmc/osx/Makefile
index f12cd4a596..dfb26f5dbd 100644
--- a/xbmc/osx/Makefile
+++ b/xbmc/osx/Makefile
@@ -16,6 +16,7 @@ SRCS = \
ZeroconfBrowserOSX.cpp \
WinSystemOSX.mm \
WinSystemOSXGL.mm \
+ SemaphoreDarwin.cpp
LIB=osx.a
diff --git a/xbmc/osx/SemaphoreDarwin.cpp b/xbmc/osx/SemaphoreDarwin.cpp
new file mode 100644
index 0000000000..d902d45712
--- /dev/null
+++ b/xbmc/osx/SemaphoreDarwin.cpp
@@ -0,0 +1,70 @@
+
+#include "SemaphoreDarwin.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <unistd.h>
+#include <cerrno>
+#include <climits>
+#include <cstdio>
+#include <ctime>
+#include <CoreVideo/CVHostTime.h>
+
+#define SEM_NAME_LEN (NAME_MAX-4)
+
+CSemaphoreDarwin::CSemaphoreDarwin(uint32_t initialCount)
+ : ISemaphore()
+{
+ m_szName = new char[SEM_NAME_LEN];
+
+ snprintf(m_szName, SEM_NAME_LEN, "/xbmc-sem-%d-%" PRIu64,
+ getpid(), CVGetCurrentHostTime());
+
+ m_pSem = sem_open(m_szName, O_CREAT, 0600, initialCount);
+}
+
+CSemaphoreDarwin::~CSemaphoreDarwin()
+{
+ sem_close(m_pSem);
+ sem_unlink(m_szName);
+ delete [] m_szName;
+}
+
+bool CSemaphoreDarwin::Wait()
+{
+ return (0 == sem_wait(m_pSem));
+}
+
+SEM_GRAB CSemaphoreDarwin::TimedWait(uint32_t millis)
+{
+ uint64_t end = CVGetCurrentHostTime() + (millis * 1000000LL);
+ do {
+ if (0 == sem_trywait(m_pSem))
+ return SEM_GRAB_SUCCESS;
+ if (errno != EAGAIN)
+ return SEM_GRAB_FAILED;
+ usleep(1000);
+ } while (CVGetCurrentHostTime() < end);
+
+ return SEM_GRAB_TIMEOUT;
+}
+
+bool CSemaphoreDarwin::TryWait()
+{
+ return (0 == sem_trywait(m_pSem));
+}
+
+bool CSemaphoreDarwin::Post()
+{
+ return (0 == sem_post(m_pSem));
+}
+
+int CSemaphoreDarwin::GetCount() const
+{
+ int val;
+ if (0 == sem_getvalue(m_pSem, &val))
+ return val;
+ return -1;
+}
+
diff --git a/xbmc/osx/SemaphoreDarwin.h b/xbmc/osx/SemaphoreDarwin.h
new file mode 100644
index 0000000000..4cd517e386
--- /dev/null
+++ b/xbmc/osx/SemaphoreDarwin.h
@@ -0,0 +1,23 @@
+
+#ifndef SEMAPHORE_DARWIN_H__
+#define SEMAPHORE_DARWIN_H__
+
+#include "ISemaphore.h"
+#include <Semaphore.h>
+
+class CSemaphoreDarwin : public ISemaphore
+{
+ char* m_szName;
+ sem_t* m_pSem;
+ public:
+ CSemaphoreDarwin(uint32_t initialCount);
+ virtual ~CSemaphoreDarwin();
+ virtual bool Wait();
+ virtual SEM_GRAB TimedWait(uint32_t millis);
+ virtual bool TryWait();
+ virtual bool Post();
+ virtual int GetCount() const;
+};
+
+#endif // SEMAPHORE_DARWIN_H__
+
diff --git a/xbmc/posix/Makefile b/xbmc/posix/Makefile
new file mode 100644
index 0000000000..365cf328ef
--- /dev/null
+++ b/xbmc/posix/Makefile
@@ -0,0 +1,11 @@
+INCLUDES+= -I../utils
+
+SRCS= \
+ SemaphorePOSIX.cpp
+
+LIB=posix.a
+
+include ../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
+
+
diff --git a/xbmc/posix/SemaphorePOSIX.cpp b/xbmc/posix/SemaphorePOSIX.cpp
new file mode 100644
index 0000000000..b71a02cf3c
--- /dev/null
+++ b/xbmc/posix/SemaphorePOSIX.cpp
@@ -0,0 +1,75 @@
+
+#include "SemaphorePOSIX.h"
+#include <sys/stat.h>
+#include <fcntl.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <unistd.h>
+#include <cerrno>
+#include <climits>
+#include <cstdio>
+#include <ctime>
+
+#define SEM_NAME_LEN (NAME_MAX-4)
+
+CSemaphorePOSIX::CSemaphorePOSIX(uint32_t initialCount)
+ : ISemaphore()
+{
+ struct timespec now = {};
+ m_szName = new char[SEM_NAME_LEN];
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ snprintf(m_szName, SEM_NAME_LEN, "/xbmc-sem-%d-%" PRIu64 "-%" PRIu64,
+ getpid(), (uint64_t)now.tv_sec, (uint64_t)now.tv_nsec);
+
+ m_pSem = sem_open(m_szName, O_CREAT, 0600, initialCount);
+}
+
+CSemaphorePOSIX::~CSemaphorePOSIX()
+{
+ sem_close(m_pSem);
+ sem_unlink(m_szName);
+ delete [] m_szName;
+}
+
+bool CSemaphorePOSIX::Wait()
+{
+ return (0 == sem_wait(m_pSem));
+}
+
+SEM_GRAB CSemaphorePOSIX::TimedWait(uint32_t millis)
+{
+ struct timespec to =
+ {
+ millis / 1000,
+ (millis % 1000) * 1000000
+ };
+
+ if (0 == sem_timedwait(m_pSem, &to))
+ return SEM_GRAB_SUCCESS;
+
+ if (errno == ETIMEDOUT)
+ return SEM_GRAB_TIMEOUT;
+
+ return SEM_GRAB_FAILED;
+}
+
+bool CSemaphorePOSIX::TryWait()
+{
+ return (0 == sem_trywait(m_pSem));
+}
+
+bool CSemaphorePOSIX::Post()
+{
+ return (0 == sem_post(m_pSem));
+}
+
+int CSemaphorePOSIX::GetCount() const
+{
+ int val;
+ if (0 == sem_getvalue(m_pSem, &val))
+ return val;
+ return -1;
+}
+
diff --git a/xbmc/posix/SemaphorePOSIX.h b/xbmc/posix/SemaphorePOSIX.h
new file mode 100644
index 0000000000..02a24ecb6d
--- /dev/null
+++ b/xbmc/posix/SemaphorePOSIX.h
@@ -0,0 +1,23 @@
+
+#ifndef SEMAPHORE_POSIX_H__
+#define SEMAPHORE_POSIX_H__
+
+#include "ISemaphore.h"
+#include <semaphore.h>
+
+class CSemaphorePOSIX : public ISemaphore
+{
+ char* m_szName;
+ sem_t* m_pSem;
+ public:
+ CSemaphorePOSIX(uint32_t initialCount);
+ virtual ~CSemaphorePOSIX();
+ virtual bool Wait();
+ virtual SEM_GRAB TimedWait(uint32_t millis);
+ virtual bool TryWait();
+ virtual bool Post();
+ virtual int GetCount() const;
+};
+
+#endif // SEMAPHORE_POSIX_H__
+
diff --git a/xbmc/utils/ISemaphore.h b/xbmc/utils/ISemaphore.h
new file mode 100644
index 0000000000..a260640422
--- /dev/null
+++ b/xbmc/utils/ISemaphore.h
@@ -0,0 +1,27 @@
+
+#ifndef ISEMAPHORE_H__
+#define ISEMAPHORE_H__
+
+#include <stdint.h>
+
+enum SEM_GRAB
+{
+ SEM_GRAB_SUCCESS,
+ SEM_GRAB_FAILED,
+ SEM_GRAB_TIMEOUT
+};
+
+class ISemaphore
+{
+ public:
+ ISemaphore() {}
+ virtual ~ISemaphore() {}
+ virtual bool Wait() = 0;
+ virtual SEM_GRAB TimedWait(uint32_t millis) = 0;
+ virtual bool TryWait() = 0;
+ virtual bool Post() = 0;
+ virtual int GetCount() const = 0;
+};
+
+#endif // ISEMAPHORE_H__
+
diff --git a/xbmc/utils/Semaphore.cpp b/xbmc/utils/Semaphore.cpp
new file mode 100644
index 0000000000..1407ae88cd
--- /dev/null
+++ b/xbmc/utils/Semaphore.cpp
@@ -0,0 +1,56 @@
+
+#include "Semaphore.h"
+#ifdef __linux__
+#include "SemaphorePOSIX.h"
+#endif
+
+CSemaphore::CSemaphore(uint32_t initialCount/*=1*/)
+ : ISemaphore()
+{
+#ifdef _SEMAPHORE_H
+ m_pSemaphore = new CSemaphorePOSIX(initialCount);
+#else
+#error No supported semaphore implementation available
+#endif
+}
+
+CSemaphore::CSemaphore(const CSemaphore& sem)
+ : ISemaphore()
+{
+#ifdef _SEMAPHORE_H
+ m_pSemaphore = new CSemaphorePOSIX(sem.GetCount());
+#else
+#error No supported semaphore implementation available
+#endif
+}
+
+CSemaphore::~CSemaphore()
+{
+ delete m_pSemaphore;
+}
+
+bool CSemaphore::Wait()
+{
+ return m_pSemaphore->Wait();
+}
+
+SEM_GRAB CSemaphore::TimedWait(uint32_t millis)
+{
+ return m_pSemaphore->TimedWait(millis);
+}
+
+bool CSemaphore::TryWait()
+{
+ return m_pSemaphore->TryWait();
+}
+
+bool CSemaphore::Post()
+{
+ return m_pSemaphore->Post();
+}
+
+int CSemaphore::GetCount() const
+{
+ return m_pSemaphore->GetCount();
+}
+
diff --git a/xbmc/utils/Semaphore.hpp b/xbmc/utils/Semaphore.hpp
new file mode 100644
index 0000000000..47214dc6a1
--- /dev/null
+++ b/xbmc/utils/Semaphore.hpp
@@ -0,0 +1,22 @@
+
+#ifndef SEMAPHORE_H__
+#define SEMAPHORE_H__
+
+#include "ISemaphore.h"
+
+class CSemaphore : public ISemaphore
+{
+ ISemaphore* m_pSemaphore;
+ public:
+ CSemaphore(uint32_t initialCount=1);
+ CSemaphore(const CSemaphore& sem);
+ virtual ~CSemaphore();
+ virtual bool Wait();
+ virtual SEM_GRAB TimedWait(uint32_t millis);
+ virtual bool TryWait();
+ virtual bool Post();
+ virtual int GetCount() const;
+};
+
+#endif // SEMAPHORE_H__
+