summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorYuriy Glukhov <yglukhov@users.noreply.github.com>2017-05-12 13:11:58 +0300
committerAndreas Rumpf <rumpf_a@web.de>2017-05-12 12:11:58 +0200
commit534d8a6b59bce5eadd543929d01ccb2f40747fcb (patch)
treea479cdd567cabc52b09b938bb3a9749b07d8121d /lib
parent77cadd07f9079ef9c5f3907cbe273b075aa1f76d (diff)
downloadNim-534d8a6b59bce5eadd543929d01ccb2f40747fcb.tar.gz
Fixed syslocks for ios (#5804)
Diffstat (limited to 'lib')
-rw-r--r--lib/system/syslocks.nim110
1 files changed, 88 insertions, 22 deletions
diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim
index fb354880f..f61b887ad 100644
--- a/lib/system/syslocks.nim
+++ b/lib/system/syslocks.nim
@@ -99,7 +99,7 @@ elif defined(genode):
 
 else:
   type
-    SysLock {.importc: "pthread_mutex_t", pure, final,
+    SysLockObj {.importc: "pthread_mutex_t", pure, final,
                header: """#include <sys/types.h>
                           #include <pthread.h>""".} = object
       when defined(linux) and defined(amd64):
@@ -111,7 +111,7 @@ else:
       when defined(linux) and defined(amd64):
         abi: array[4 div sizeof(cint), cint]  # actually a cint
 
-    SysCond {.importc: "pthread_cond_t", pure, final,
+    SysCondObj {.importc: "pthread_cond_t", pure, final,
                header: """#include <sys/types.h>
                           #include <pthread.h>""".} = object
       when defined(linux) and defined(amd64):
@@ -119,8 +119,62 @@ else:
 
     SysLockType = distinct cint
 
-  proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {.
+  proc initSysLockAux(L: var SysLockObj, attr: ptr SysLockAttr) {.
     importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
+  proc deinitSysAux(L: var SysLockObj) {.noSideEffect,
+    importc: "pthread_mutex_destroy", header: "<pthread.h>".}
+
+  proc acquireSysAux(L: var SysLockObj) {.noSideEffect,
+    importc: "pthread_mutex_lock", header: "<pthread.h>".}
+  proc tryAcquireSysAux(L: var SysLockObj): cint {.noSideEffect,
+    importc: "pthread_mutex_trylock", header: "<pthread.h>".}
+
+  proc releaseSysAux(L: var SysLockObj) {.noSideEffect,
+    importc: "pthread_mutex_unlock", header: "<pthread.h>".}
+
+  when defined(ios):
+    # iOS will behave badly if sync primitives are moved in memory. In order
+    # to prevent this once and for all, we're doing an extra malloc when
+    # initializing the primitive.
+    type
+      SysLock = ptr SysLockObj
+      SysCond = ptr SysCondObj
+
+    when not declared(c_malloc):
+      proc c_malloc(size: csize): pointer {.
+        importc: "malloc", header: "<stdlib.h>".}
+      proc c_free(p: pointer) {.
+        importc: "free", header: "<stdlib.h>".}
+
+    proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) =
+      L = cast[SysLock](c_malloc(sizeof(SysLockObj)))
+      initSysLockAux(L[], attr)
+
+    proc deinitSys(L: var SysLock) =
+      deinitSysAux(L[])
+      c_free(L)
+
+    template acquireSys(L: var SysLock) =
+      acquireSysAux(L[])
+    template tryAcquireSys(L: var SysLock): bool =
+      tryAcquireSysAux(L[]) == 0'i32
+    template releaseSys(L: var SysLock) =
+      releaseSysAux(L[])
+  else:
+    type
+      SysLock = SysLockObj
+      SysCond = SysCondObj
+
+    template initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) =
+      initSysLockAux(L, attr)
+    template deinitSys(L: var SysLock) =
+      deinitSysAux(L)
+    template acquireSys(L: var SysLock) =
+      acquireSysAux(L)
+    template tryAcquireSys(L: var SysLock): bool =
+      tryAcquireSysAux(L) == 0'i32
+    template releaseSys(L: var SysLock) =
+      releaseSysAux(L)
 
   when insideRLocksModule:
     proc SysLockType_Reentrant: SysLockType =
@@ -130,27 +184,39 @@ else:
     proc setSysLockType(a: var SysLockAttr, t: SysLockType) {.
       importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.}
 
-  proc acquireSys(L: var SysLock) {.noSideEffect,
-    importc: "pthread_mutex_lock", header: "<pthread.h>".}
-  proc tryAcquireSysAux(L: var SysLock): cint {.noSideEffect,
-    importc: "pthread_mutex_trylock", header: "<pthread.h>".}
-
-  proc tryAcquireSys(L: var SysLock): bool {.inline.} =
-    result = tryAcquireSysAux(L) == 0'i32
-
-  proc releaseSys(L: var SysLock) {.noSideEffect,
-    importc: "pthread_mutex_unlock", header: "<pthread.h>".}
-  proc deinitSys(L: var SysLock) {.noSideEffect,
-    importc: "pthread_mutex_destroy", header: "<pthread.h>".}
-
-  when not insideRLocksModule:
-    proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {.
+  else:
+    proc initSysCondAux(cond: var SysCondObj, cond_attr: pointer) {.
       importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
-    proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
+    proc deinitSysCondAux(cond: var SysCondObj) {.noSideEffect,
+      importc: "pthread_cond_destroy", header: "<pthread.h>".}
+
+    proc waitSysCondAux(cond: var SysCondObj, lock: var SysLockObj) {.
       importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
-    proc signalSysCond(cond: var SysCond) {.
+    proc signalSysCondAux(cond: var SysCondObj) {.
       importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
-    proc deinitSysCond(cond: var SysCond) {.noSideEffect,
-      importc: "pthread_cond_destroy", header: "<pthread.h>".}
+
+    when defined(ios):
+      proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) =
+        cond = cast[SysCond](c_malloc(sizeof(SysCondObj)))
+        initSysCondAux(cond[], cond_attr)
+
+      proc deinitSysCond(cond: var SysCond) =
+        deinitSysCondAux(cond[])
+        c_free(cond)
+
+      template waitSysCond(cond: var SysCond, lock: var SysLock) =
+        waitSysCondAux(cond[], lock[])
+      template signalSysCond(cond: var SysCond) =
+        signalSysCondAux(cond[])
+    else:
+      template initSysCond(cond: var SysCond, cond_attr: pointer = nil) =
+        initSysCondAux(cond, cond_attr)
+      template deinitSysCond(cond: var SysCond) =
+        deinitSysCondAux(cond)
+
+      template waitSysCond(cond: var SysCond, lock: var SysLock) =
+        waitSysCondAux(cond, lock)
+      template signalSysCond(cond: var SysCond) =
+        signalSysCondAux(cond)
 
 {.pop.}