diff options
Diffstat (limited to 'tests/isolate')
-rw-r--r-- | tests/isolate/tisolate.nim | 41 | ||||
-rw-r--r-- | tests/isolate/tisolate2.nim | 22 | ||||
-rw-r--r-- | tests/isolate/tisolated_lock.nim | 67 |
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) |