-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patherl_interface.pony
128 lines (98 loc) · 4.25 KB
/
erl_interface.pony
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use "lib:otp_pony_node_c"
use "debug"
use @opn_set_tracelevel[None](level: I32)
use @opn_ei_self_pid[I32](_connection: Pointer[None], buffer: Pointer[U8] tag, num: Pointer[U32], serial: Pointer[U32], creation: Pointer[U32])
use @opn_ei_new[Pointer[None]](_this_nodename: Pointer[U8] tag, _cookie: Pointer[U8] tag, _creation: I16)
use @opn_ei_connect[I32](_connection: Pointer[None], nodename: Pointer[U8] tag)
use @opn_ei_receive[Pointer[None]](_connection: Pointer[None], _connection_id: Connection)
use @opn_ei_receive_tmo[Pointer[None]](_connection: Pointer[None], _connection_id: Connection, timeout_ms: U32, timed_out: Pointer[I32])
use @opn_ei_send_tmo[I32](_connection: Pointer[None], _connection_id: Connection, to: Pointer[None], what: Pointer[None], timeout_ms: U32, timed_out: Pointer[I32])
use @opn_ei_destroy[None](_connection: Pointer[None])
class EInterface
let _this_nodename: String
let _cookie: String
let _creation: I16
var _connection: Pointer[None] = Pointer[None]
var _connection_id: Connection = -1
new create(this_nodename': String, cookie': String, creation': I16 = 0) =>
_this_nodename = this_nodename'
_cookie = cookie'
_creation = creation'
fun set_tracelevel(level: I32) =>
@opn_set_tracelevel(level)
fun ref self_pid(): ErlangPid =>
let buffer: Array[U8] val = recover Array[U8].init(0, /*MAXATOMLEN_UTF8*/ (255*4) + 1 /*null*/) end
var num: U32 = 0
var serial: U32 = 0
var creation: U32 = 0
let res = @opn_ei_self_pid(_connection, buffer.cpointer(), addressof num, addressof serial, addressof creation)
if res != 0 then
// todo: strategy on failure
Debug.out("self_pid: decoding the pid failed")
end
let pid: ErlangPid val = recover ErlangPid(Strings.null_trimmed(buffer), num, serial, creation) end
pid
fun ref connect(nodename: String): (ConnectionSucceeded | ConnectionFailed) =>
// simple single connection for now
if connected() then
Debug.out("already connected once")
return ConnectionFailed
end
_connection = @opn_ei_new(_this_nodename.cstring(), _cookie.cstring(), _creation)
if _connection.is_null() then
return ConnectionFailed
end
_connection_id = @opn_ei_connect(_connection, nodename.cstring())
if _connection_id < 0 then
disconnect()
return ConnectionFailed
end
ConnectionSucceeded
fun ref receive(): (EMessage | ReceiveFailed) =>
if _connection_id < 0 then
return ReceiveFailed
end
let message_p = @opn_ei_receive(_connection, _connection_id)
if message_p == Pointer[None] then
return ReceiveFailed
end
EMessage.from_cpointer(message_p)
fun ref receive_with_timeout(timeout_ms: U32): (EMessage | ReceiveFailed | ReceiveTimedOut) =>
if _connection_id < 0 then
return ReceiveFailed
end
var timed_out: I32 = 0
let message_p = @opn_ei_receive_tmo(_connection, _connection_id, timeout_ms, addressof timed_out)
if timed_out != 0 then
return ReceiveTimedOut
end
if message_p == Pointer[None] then
return ReceiveFailed
end
EMessage.from_cpointer(message_p)
fun send_with_timeout(to: ErlangPid, what: EMessage, timeout_ms: U32): (SentOk | SendFailed | SendTimedOut) =>
if _connection_id < 0 then
return SendFailed
end
var timed_out: I32 = 0
let res = @opn_ei_send_tmo(_connection, _connection_id, to.cpointer(), what.cpointer(), timeout_ms, addressof timed_out)
if timed_out != 0 then
return SendTimedOut
end
if res != 0 then
return SendFailed
end
SentOk
fun ref disconnect() =>
if not connected() then
return
end
@opn_ei_destroy(addressof _connection)
_connection = Pointer[None]
_connection_id = -1
fun connected(): Bool =>
_connection != Pointer[None]
fun _final() =>
if _connection != Pointer[None] then
@opn_ei_destroy(addressof _connection)
end