summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/lib.txt3
-rw-r--r--lib/core/rlocks.nim50
-rw-r--r--lib/system/syslocks.nim16
-rw-r--r--web/news.txt6
-rw-r--r--web/website.ini2
5 files changed, 74 insertions, 3 deletions
diff --git a/doc/lib.txt b/doc/lib.txt
index 90cf36240..5ff6de7fd 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -46,6 +46,9 @@ Core
 * `locks <locks.html>`_
   Locks and condition variables for Nim.
 
+* `rlocks <rlocks.html>`_
+  Reentrant locks for Nim.
+
 * `macros <macros.html>`_
   Contains the AST API and documentation of Nim for writing macros.
 
diff --git a/lib/core/rlocks.nim b/lib/core/rlocks.nim
new file mode 100644
index 000000000..14f04592b
--- /dev/null
+++ b/lib/core/rlocks.nim
@@ -0,0 +1,50 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2016 Anatoly Galiulin
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module contains Nim's support for reentrant locks.
+
+include "system/syslocks"
+
+type
+  RLock* = SysLock ## Nim lock, re-entrant
+
+proc initRLock*(lock: var RLock) {.inline.} =
+  ## Initializes the given lock.
+  when defined(posix):
+    var a: SysLockAttr
+    initSysLockAttr(a)
+    setSysLockType(a, SysLockType_Reentrant())
+    initSysLock(lock, a.addr)
+  else:
+    initSysLock(lock)
+
+proc deinitRLock*(lock: var RLock) {.inline.} =
+  ## Frees the resources associated with the lock.
+  deinitSys(lock)
+
+proc tryAcquire*(lock: var RLock): bool =
+  ## Tries to acquire the given lock. Returns `true` on success.
+  result = tryAcquireSys(lock)
+
+proc acquire*(lock: var RLock) =
+  ## Acquires the given lock.
+  acquireSys(lock)
+
+proc release*(lock: var RLock) =
+  ## Releases the given lock.
+  releaseSys(lock)
+
+template withRLock*(lock: var RLock, code: untyped): untyped =
+  ## Acquires the given lock and then executes the code.
+  block:
+    acquire(lock)
+    defer:
+      release(lock)
+    {.locks: [lock].}:
+      code
diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim
index 7a113b9d4..a91a5e7d4 100644
--- a/lib/system/syslocks.nim
+++ b/lib/system/syslocks.nim
@@ -7,7 +7,7 @@
 #    distribution, for details about the copyright.
 #
 
-## Low level system locks and condition vars.
+# Low level system locks and condition vars.
 
 when defined(Windows):
   type
@@ -75,12 +75,24 @@ else:
   type
     SysLock {.importc: "pthread_mutex_t", pure, final,
                header: "<sys/types.h>".} = object
+    SysLockAttr {.importc: "pthread_mutexattr_t", pure, final
+               header: "<sys/types.h>".} = object
     SysCond {.importc: "pthread_cond_t", pure, final,
                header: "<sys/types.h>".} = object
+    SysLockType = distinct cint
+
+  proc SysLockType_Reentrant: SysLockType =
+    {.emit: "`result` = PTHREAD_MUTEX_RECURSIVE;".}
 
-  proc initSysLock(L: var SysLock, attr: pointer = nil) {.
+  proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {.
     importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
 
+  proc initSysLockAttr(a: var SysLockAttr) {.
+    importc: "pthread_mutexattr_init", header: "<pthread.h>", noSideEffect.}
+
+  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,
diff --git a/web/news.txt b/web/news.txt
index d8c591d53..bf665c85c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -11,6 +11,12 @@ Changes affecting backwards compatibility
 - ``--out`` and ``--nimcache`` command line arguments are now relative to
   current directory. Previously they were relative to project directory.
 
+Library Additions
+-----------------
+
+- The rlocks module has been added providing reentrant lock synchronization
+  primitive
+
 
 2016-01-27 Nim in Action is now available!
 ==========================================
diff --git a/web/website.ini b/web/website.ini
index 46564d19f..d1f8a04bf 100644
--- a/web/website.ini
+++ b/web/website.ini
@@ -54,7 +54,7 @@ srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
 srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings"
 srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
 srcdoc2: "pure/memfiles;pure/subexes;pure/collections/critbits"
-srcdoc2: "deprecated/pure/asyncio;deprecated/pure/actors;core/locks;pure/oids;pure/endians;pure/uri"
+srcdoc2: "deprecated/pure/asyncio;deprecated/pure/actors;core/locks;core/rlocks;pure/oids;pure/endians;pure/uri"
 srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite"
 srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
 srcdoc2: "packages/docutils/rstgen;pure/logging;pure/options;pure/asyncdispatch;pure/asyncnet"