1;;! component_model_async = true
2;;! component_model_threading = true
3
4;; Test that a thread which is not suspended cannot be resumed
5(component
6    (core module $libc
7        (memory (export "mem") 1)
8        (table (export "table") 2 funcref)
9    )
10    (core module $CM
11        (import "" "thread.new-indirect" (func $thread.new-indirect (param i32 i32) (result i32)))
12        (import "" "thread.yield-to-suspended" (func $thread.yield-to-suspended (param i32) (result i32)))
13        (import "" "thread.yield" (func $thread.yield (result i32)))
14        (import "libc" "mem" (memory 1))
15        (import "libc" "table" (table $table 2 funcref))
16
17        (func (export "run")
18          (local $id i32)
19          ;; start `$id` suspended
20          (local.set $id (call $thread.new-indirect (i32.const 0) (i32.const 0)))
21
22          ;; Resume it, which will come back here due to `$thread.yield`
23          (drop (call $thread.yield-to-suspended (local.get $id)))
24
25          ;; try to resume it again and this should trap.
26          (drop (call $thread.yield-to-suspended (local.get $id)))
27        )
28
29        (func $child (param i32)
30          (drop (call $thread.yield))
31        )
32        (elem (table $table) (i32.const 0) func $child)
33    )
34
35    (core instance $libc (instantiate $libc))
36    (core type $start-func-ty (func (param i32)))
37
38    (core func $task-cancel (canon task.cancel))
39    (core func $thread-new-indirect
40        (canon thread.new-indirect $start-func-ty (table $libc "table")))
41    (core func $thread-yield (canon thread.yield))
42    (core func $thread-yield-to-suspended (canon thread.yield-to-suspended))
43
44    (core instance $cm (instantiate $CM
45        (with "" (instance
46            (export "thread.new-indirect" (func $thread-new-indirect))
47            (export "thread.yield-to-suspended" (func $thread-yield-to-suspended))
48            (export "thread.yield" (func $thread-yield))
49        ))
50        (with "libc" (instance $libc))
51    ))
52
53    (func (export "run") async (canon lift (core func $cm "run")))
54)
55
56(assert_trap (invoke "run") "cannot resume thread which is not suspended")
57