summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-06-07 17:02:16 -0700
committerGarrett D'Amore <garrett@damore.org>2018-06-07 17:02:16 -0700
commitef4123ff70c74b47b66ef066ecf88d1ed3750dc3 (patch)
tree71a9722abd8aaabd0b17c3e6b32273747be4053f
parentfdc80f68ece48de5fa093071f5700d9237794952 (diff)
downloadnanomsg-ef4123ff70c74b47b66ef066ecf88d1ed3750dc3.tar.gz
fixes #958 Android NDK support
To build this you will need to use the Android appropriate version of cmake, and point it at the toolchain file that is included with the NDK.
-rw-r--r--CMakeLists.txt8
-rw-r--r--src/utils/sem.c138
-rw-r--r--src/utils/sem.h22
3 files changed, 88 insertions, 80 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a0446b1..308268f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -142,6 +142,9 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
if (CMAKE_SYSTEM_VERSION MATCHES "Microsoft")
add_definitions (-DNN_HAVE_WSL)
endif()
+elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
+ add_definitions (-DNN_HAVE_ANDROID)
+ add_definitions (-DNN_HAVE_LINUX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_definitions (-DNN_HAVE_OSX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
@@ -248,7 +251,10 @@ else ()
nn_check_sym (backtrace_symbols_fd execinfo.h NN_HAVE_BACKTRACE)
nn_check_struct_member(msghdr msg_control sys/socket.h NN_HAVE_MSG_CONTROL)
if (NN_HAVE_SEMAPHORE_RT OR NN_HAVE_SEMAPHORE_PTHREAD)
- add_definitions (-DNN_HAVE_SEMAPHORE)
+ if (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ # macOS doesn't have unnamed semaphores
+ add_definitions (-DNN_HAVE_SEMAPHORE)
+ endif()
endif ()
endif ()
diff --git a/src/utils/sem.c b/src/utils/sem.c
index 17943d5..06a0128 100644
--- a/src/utils/sem.c
+++ b/src/utils/sem.c
@@ -24,74 +24,8 @@
#include "err.h"
#include "fast.h"
-#if defined NN_HAVE_OSX
-void nn_sem_init (struct nn_sem *self)
-{
- int rc;
-
- rc = pthread_mutex_init (&self->mutex, NULL);
- errnum_assert (rc == 0, rc);
- rc = pthread_cond_init (&self->cond, NULL);
- errnum_assert (rc == 0, rc);
- self->signaled = 0;
-}
-
-void nn_sem_term (struct nn_sem *self)
-{
- int rc;
-
- rc = pthread_cond_destroy (&self->cond);
- errnum_assert (rc == 0, rc);
- rc = pthread_mutex_destroy (&self->mutex);
- errnum_assert (rc == 0, rc);
-}
-
-void nn_sem_post (struct nn_sem *self)
-{
- int rc;
-
- rc = pthread_mutex_lock (&self->mutex);
- errnum_assert (rc == 0, rc);
- nn_assert (self->signaled == 0);
- self->signaled = 1;
- rc = pthread_cond_signal (&self->cond);
- errnum_assert (rc == 0, rc);
- rc = pthread_mutex_unlock (&self->mutex);
- errnum_assert (rc == 0, rc);
-}
-
-int nn_sem_wait (struct nn_sem *self)
-{
- int rc;
-
- /* With OSX, semaphores are global named objects. They are not useful for
- our use case. To get a similar object we exploit the implementation
- detail of pthread_cond_wait() in Darwin kernel: It exits if signal is
- caught. Note that this behaviour is not mandated by POSIX
- and may break with future versions of Darwin. */
- rc = pthread_mutex_lock (&self->mutex);
- errnum_assert (rc == 0, rc);
- if (nn_fast (self->signaled)) {
- rc = pthread_mutex_unlock (&self->mutex);
- errnum_assert (rc == 0, rc);
- return 0;
- }
- rc = pthread_cond_wait (&self->cond, &self->mutex);
- errnum_assert (rc == 0, rc);
- if (nn_slow (!self->signaled)) {
- rc = pthread_mutex_unlock (&self->mutex);
- errnum_assert (rc == 0, rc);
- return -EINTR;
- }
- self->signaled = 0;
- rc = pthread_mutex_unlock (&self->mutex);
- errnum_assert (rc == 0, rc);
-
- return 0;
-}
-
-#elif defined NN_HAVE_WINDOWS
+#if defined NN_HAVE_WINDOWS
void nn_sem_init (struct nn_sem *self)
{
@@ -164,6 +98,74 @@ int nn_sem_wait (struct nn_sem *self)
}
#else
-#error
+
+/* Simulate semaphores with condition variables. */
+
+void nn_sem_init (struct nn_sem *self)
+{
+ int rc;
+
+ rc = pthread_mutex_init (&self->mutex, NULL);
+ errnum_assert (rc == 0, rc);
+ rc = pthread_cond_init (&self->cond, NULL);
+ errnum_assert (rc == 0, rc);
+ self->signaled = 0;
+}
+
+void nn_sem_term (struct nn_sem *self)
+{
+ int rc;
+
+ rc = pthread_cond_destroy (&self->cond);
+ errnum_assert (rc == 0, rc);
+ rc = pthread_mutex_destroy (&self->mutex);
+ errnum_assert (rc == 0, rc);
+}
+
+void nn_sem_post (struct nn_sem *self)
+{
+ int rc;
+
+ rc = pthread_mutex_lock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+ nn_assert (self->signaled == 0);
+ self->signaled = 1;
+ rc = pthread_cond_signal (&self->cond);
+ errnum_assert (rc == 0, rc);
+ rc = pthread_mutex_unlock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+}
+
+int nn_sem_wait (struct nn_sem *self)
+{
+ int rc;
+
+ /* With OSX, semaphores are global named objects. They are not useful for
+ our use case. To get a similar object we exploit the implementation
+ detail of pthread_cond_wait() in Darwin kernel: It exits if signal is
+ caught. Note that this behaviour is not mandated by POSIX
+ and may break with future versions of Darwin. */
+ rc = pthread_mutex_lock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+ if (nn_fast (self->signaled)) {
+ rc = pthread_mutex_unlock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+ return 0;
+ }
+ rc = pthread_cond_wait (&self->cond, &self->mutex);
+ errnum_assert (rc == 0, rc);
+ if (nn_slow (!self->signaled)) {
+ rc = pthread_mutex_unlock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+ return -EINTR;
+ }
+ self->signaled = 0;
+ rc = pthread_mutex_unlock (&self->mutex);
+ errnum_assert (rc == 0, rc);
+
+ return 0;
+}
+
+
#endif
diff --git a/src/utils/sem.h b/src/utils/sem.h
index 6cfc021..34c0428 100644
--- a/src/utils/sem.h
+++ b/src/utils/sem.h
@@ -39,17 +39,7 @@ void nn_sem_post (struct nn_sem *self);
/* Waits till sem object becomes unlocked and locks it. */
int nn_sem_wait (struct nn_sem *self);
-#if defined NN_HAVE_OSX
-
-#include <pthread.h>
-
-struct nn_sem {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int signaled;
-};
-
-#elif defined NN_HAVE_WINDOWS
+#if defined NN_HAVE_WINDOWS
#include "win.h"
@@ -65,6 +55,16 @@ struct nn_sem {
sem_t sem;
};
+#else /* Simulate semaphore with condition variable. */
+
+#include <pthread.h>
+
+struct nn_sem {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int signaled;
+};
+
#endif
#endif