1// Copyright 2025 International Digital Economy Academy
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15///|
16type Thread
17
18///|
19extern "c" fn uv_thread_make() -> type Thread
Thread = "moonbit_uv_thread_make"
20
21///|
22extern "c" fn uv_thread_create(thread : type Thread
Thread, cb : () -> Unit
Unit) -> Int
Int = "moonbit_uv_thread_create"
23
24///|
25pub fn type Thread
Thread::(cb : () -> Unit) -> Thread raise Errno
new(() -> Unit
cb : () -> Unit
Unit) -> type Thread
Thread raise type! Errno Status
Errno {
26 let Thread
thread = () -> Thread
uv_thread_make()
27 let Int
status = (thread : Thread, cb : () -> Unit) -> Int
uv_thread_create(Thread
thread, () -> Unit
cb)
28 if Int
status (x : Int, y : Int) -> Bool
!= 0 {
29 raise type! Errno Status
Errno::(errno : Int) -> Errno
of_int(Int
status)
30 }
31 return Thread
thread
32}
33
34///|
35extern "c" fn uv_thread_join(thread : type Thread
Thread) -> Int
Int = "moonbit_uv_thread_join"
36
37///|
38extern "c" fn uv_thread_self(thread : type Thread
Thread) -> Int
Int = "moonbit_uv_thread_self"
39
40///|
41extern "c" fn uv_thread_equal(thread : type Thread
Thread, other : type Thread
Thread) -> Int
Int = "moonbit_uv_thread_equal"
42
43///|
44pub impl trait Eq {
op_equal(Self, Self) -> Bool
}
Trait for types whose elements can test for equality
Eq for type Thread
Thread with (self : Thread, other : Thread) -> Bool
op_equal(Thread
self : type Thread
Thread, Thread
other : type Thread
Thread) -> Bool
Bool {
45 return (thread : Thread, other : Thread) -> Int
uv_thread_equal(Thread
self, Thread
other) (x : Int, y : Int) -> Bool
!= 0
46}
47
48///|
49extern "c" fn uv_thread_copy(thread : type Thread
Thread, other : type Thread
Thread) -> Unit
Unit = "moonbit_uv_thread_copy"
50
51///|
52pub fn type Thread
Thread::(self : Thread) -> Unit raise Errno
join(Thread
self : type Thread
Thread) -> Unit
Unit raise type! Errno Status
Errno {
53 let Int
status = (thread : Thread) -> Int
uv_thread_join(Thread
self)
54 if Int
status (x : Int, y : Int) -> Bool
!= 0 {
55 raise type! Errno Status
Errno::(errno : Int) -> Errno
of_int(Int
status)
56 }
57}
58
59///|
60pub fn type Thread
Thread::() -> Thread raise Errno
self() -> type Thread
Thread raise type! Errno Status
Errno {
61 let Thread
thread = () -> Thread
uv_thread_make()
62 let Int
status = (thread : Thread) -> Int
uv_thread_self(Thread
thread)
63 if Int
status (self_ : Int, other : Int) -> Bool
< 0 {
64 raise type! Errno Status
Errno::(errno : Int) -> Errno
of_int(Int
status)
65 }
66 return Thread
thread
67}
68
69///|
70pub fn type Thread
Thread::(self : Thread, other : Thread) -> Bool
equal(Thread
self : type Thread
Thread, Thread
other : type Thread
Thread) -> Bool
Bool {
71 return (thread : Thread, other : Thread) -> Int
uv_thread_equal(Thread
self, Thread
other) (x : Int, y : Int) -> Bool
!= 0
72}
73
74///|
75pub impl trait Share {
share(Self) -> Self
}
Shares an object safely between threads.
In MoonBit, the default reference counting (RC) for objects is not atomic,
so it is not safe to share most objects directly between threads.
To enable safe sharing, we use a separate atomic reference counter (ARC)
stored alongside the actual object data. The MoonBit object itself is
managed by non-atomic RC, but the shared payload is managed by ARC.
When you want to share an object:
- The MoonBit object holds a pointer to a heap-allocated block containing
both the ARC and the payload (e.g., a mutex or thread handle).
- Copying the MoonBit object only copies the pointer; the ARC is incremented
atomically (guarded by a mutex if needed).
- When a copy is dropped, the ARC is decremented atomically. When ARC
reaches zero, the payload is freed.
Example: uv_thread_t stores an arc field and a uv_mutex_t object in a
heap-allocated block. All increments/decrements of arc are protected by
the mutex to ensure thread safety.
Diagram:
(thread 0) (thread 1)
+--------+ +--------+
| rc (M) | | rc (M) |
+--------+ +--------+
\ /
---> +---------+ <---/
| arc (F) |
+---------+
| mutex |
+---------+
| payload |
+----+----+
The Share trait provides a share method to allow implementor of this
trait to create a new MoonBit object pointing to the same shared payload,
incrementing the ARC safely.
Share for type Thread
Thread with (self : Thread) -> Thread
share(Thread
self : type Thread
Thread) -> type Thread
Thread {
76 let Thread
other = () -> Thread
uv_thread_make()
77 (thread : Thread, other : Thread) -> Unit
uv_thread_copy(Thread
self, Thread
other)
78 return Thread
other
79}
80