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