summary refs log tree commit diff stats
path: root/tests/isolate
diff options
context:
space:
mode:
Diffstat (limited to 'tests/isolate')
-rw-r--r--tests/isolate/tisolate.nim41
-rw-r--r--tests/isolate/tisolate2.nim22
-rw-r--r--tests/isolate/tisolated_lock.nim67
3 files changed, 130 insertions, 0 deletions
diff --git a/tests/isolate/tisolate.nim b/tests/isolate/tisolate.nim
new file mode 100644
index 000000000..a0e71e321
--- /dev/null
+++ b/tests/isolate/tisolate.nim
@@ -0,0 +1,41 @@
+discard """
+  errormsg: "expression cannot be isolated: select(a, b)"
+  line: 39
+"""
+
+import std / isolation
+
+import json, streams
+
+proc myParseJson(s: Stream; filename: string): JsonNode =
+  {.cast(noSideEffect).}:
+    result = parseJson(s, filename)
+
+
+proc f(): seq[int] =
+  @[1, 2, 3]
+
+type
+  Node = ref object
+    x: string
+
+proc g(): Node = nil
+
+proc select(a, b: Node): Node =
+  a
+
+proc main =
+  discard isolate f()
+
+
+  discard isolate g()
+
+  discard isolate select(Node(x: "a"), nil)
+  discard isolate select(Node(x: "a"), Node(x: "b"))
+
+  discard isolate myParseJson(newFileStream("my.json"), "my.json")
+
+  var a, b: Node
+  discard isolate select(a, b)
+
+main()
diff --git a/tests/isolate/tisolate2.nim b/tests/isolate/tisolate2.nim
new file mode 100644
index 000000000..9bf92d82e
--- /dev/null
+++ b/tests/isolate/tisolate2.nim
@@ -0,0 +1,22 @@
+discard """
+  errormsg: "expression cannot be isolated: a_to_b(a)"
+  line: 22
+"""
+
+# bug #19013
+import std/isolation
+
+type Z = ref object
+  i: int
+
+type A = object
+  z: Z
+
+type B = object
+  z: Z
+
+func a_to_b(a: A): B =
+  result = B(z: a.z)
+
+let a = A(z: Z(i: 3))
+let b = isolate(a_to_b(a))
diff --git a/tests/isolate/tisolated_lock.nim b/tests/isolate/tisolated_lock.nim
new file mode 100644
index 000000000..312abf0f6
--- /dev/null
+++ b/tests/isolate/tisolated_lock.nim
@@ -0,0 +1,67 @@
+discard """
+  cmd: "nim $target --threads:on $options $file"
+  action: "compile"
+"""
+
+import std / [os, locks, atomics, isolation]
+
+type
+  MyList {.acyclic.} = ref object
+    data: string
+    next: Isolated[MyList]
+
+template withMyLock*(a: Lock, body: untyped) =
+  acquire(a)
+  {.gcsafe.}:
+    try:
+      body
+    finally:
+      release(a)
+
+var head: Isolated[MyList]
+var headL: Lock
+
+var shouldStop: Atomic[bool]
+
+initLock headL
+
+proc send(x: sink string) =
+  withMyLock headL:
+    head = isolate MyList(data: x, next: move head)
+
+proc worker() {.thread.} =
+  var workItem = MyList(nil)
+  var echoed = 0
+  while true:
+    withMyLock headL:
+      var h = extract head
+      if h != nil:
+        workItem = h
+        # workitem is now isolated:
+        head = move h.next
+      else:
+        workItem = nil
+    # workItem is isolated, so we can access it outside
+    # the lock:
+    if workItem.isNil:
+      if shouldStop.load:
+        break
+      else:
+        # give producer time to breath:
+        os.sleep 30
+    else:
+      if echoed < 100:
+        echo workItem.data
+      inc echoed
+
+var thr: Thread[void]
+createThread(thr, worker)
+
+send "abc"
+send "def"
+for i in 0 ..< 10_000:
+  send "xzy"
+  send "zzz"
+shouldStop.store true
+
+joinThread(thr)