aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--event.go113
-rw-r--r--msg.go20
-rw-r--r--netaddr.go51
-rw-r--r--network.go185
m---------salticidae0
-rw-r--r--stream.go118
-rw-r--r--test_msgnet/main.go41
-rw-r--r--test_p2p_stress/main.go60
8 files changed, 380 insertions, 208 deletions
diff --git a/event.go b/event.go
index 1c8a94e..7ebc643 100644
--- a/event.go
+++ b/event.go
@@ -3,50 +3,115 @@ package salticidae
// #include "salticidae/event.h"
// #include <signal.h>
import "C"
+import "runtime"
-type EventContext = *C.struct_eventcontext_t
+type CEventContext = *C.eventcontext_t
+type eventContext struct {
+ inner CEventContext
+ attached map[uintptr]interface{}
+}
+type EventContext = *eventContext
+
+func NewEventContext() EventContext {
+ res := &eventContext{
+ inner: C.eventcontext_new(),
+ attached: make(map[uintptr]interface{}),
+ }
+ runtime.SetFinalizer(res, func(self EventContext) { self.free() })
+ return res
+}
+
+func (self EventContext) attach(ptr rawptr_t, x interface{}) { self.attached[uintptr(ptr)] = x }
+func (self EventContext) detach(ptr rawptr_t) { delete(self.attached, uintptr(ptr)) }
+func (self EventContext) free() { C.eventcontext_free(self.inner) }
+func (self EventContext) Dispatch() { C.eventcontext_dispatch(self.inner) }
+func (self EventContext) Stop() { C.eventcontext_stop(self.inner) }
-func NewEventContext() EventContext { return C.eventcontext_new() }
-func (self EventContext) Free() { C.eventcontext_free(self) }
-func (self EventContext) Dispatch() { C.eventcontext_dispatch(self) }
-func (self EventContext) Stop() { C.eventcontext_stop(self) }
+type CThreadCall = *C.threadcall_t
+type threadCall struct { inner CThreadCall }
+type ThreadCall = *threadCall
-type ThreadCall = *C.struct_threadcall_t
type ThreadCallCallback = C.threadcall_callback_t
-func NewThreadCall(ec EventContext) ThreadCall { return C.threadcall_new(ec) }
+func NewThreadCall(ec EventContext) ThreadCall {
+ res := &threadCall{ inner: C.threadcall_new(ec.inner) }
+ runtime.SetFinalizer(res, func(self ThreadCall) { self.free() })
+ return res
+}
-func (self ThreadCall) Free() { C.threadcall_free(self) }
+func (self ThreadCall) free() { C.threadcall_free(self.inner) }
func (self ThreadCall) AsyncCall(callback ThreadCallCallback, userdata rawptr_t) {
- C.threadcall_async_call(self, callback, userdata)
+ C.threadcall_async_call(self.inner, callback, userdata)
}
-func (self ThreadCall) GetEC() EventContext { return C.threadcall_get_ec(self) }
+type CTimerEvent = *C.timerev_t
+type timerEvent struct {
+ inner CTimerEvent
+ ec EventContext
+}
+type TimerEvent = *timerEvent
-type TimerEvent = *C.timerev_t
type TimerEventCallback = C.timerev_callback_t
-func NewTimerEvent(ec EventContext, cb TimerEventCallback, userdata rawptr_t) TimerEvent {
- return C.timerev_new(ec, cb, userdata)
+func NewTimerEvent(_ec EventContext, cb TimerEventCallback, userdata rawptr_t) TimerEvent {
+ res := &timerEvent{
+ inner: C.timerev_new(_ec.inner, cb, userdata),
+ ec: _ec,
+ }
+ _ec.attach(rawptr_t(res.inner), res)
+ runtime.SetFinalizer(res, func(self TimerEvent) { self.free() })
+ return res
}
-func (self TimerEvent) Free() { C.timerev_free(self) }
+func (self TimerEvent) free() { C.timerev_free(self.inner) }
func (self TimerEvent) SetCallback(callback TimerEventCallback, userdata rawptr_t) {
- C.timerev_set_callback(self, callback, userdata)
+ C.timerev_set_callback(self.inner, callback, userdata)
}
-func (self TimerEvent) Add(t_sec float64) { C.timerev_add(self, C.double(t_sec)) }
-func (self TimerEvent) Clear() { C.timerev_clear(self) }
+func (self TimerEvent) Add(t_sec float64) { C.timerev_add(self.inner, C.double(t_sec)) }
+func (self TimerEvent) Del() {
+ self.ec.detach(rawptr_t(self.inner))
+ C.timerev_del(self.inner)
+}
+
+func (self TimerEvent) Clear() {
+ self.ec.detach(rawptr_t(self.inner))
+ C.timerev_clear(self.inner)
+}
+
+type CSigEvent = *C.sigev_t
+type sigEvent struct {
+ inner CSigEvent
+ ec EventContext
+}
+type SigEvent = *sigEvent
-type SigEvent = *C.sigev_t
type SigEventCallback = C.sigev_callback_t
-var SIGTERM = C.SIGTERM
-var SIGINT = C.SIGINT
-func NewSigEvent(ec EventContext, cb SigEventCallback, userdata rawptr_t) SigEvent {
- return C.sigev_new(ec, cb, userdata)
+var (
+ SIGTERM = C.SIGTERM
+ SIGINT = C.SIGINT
+)
+
+func NewSigEvent(_ec EventContext, cb SigEventCallback, userdata rawptr_t) SigEvent {
+ res := &sigEvent{
+ inner: C.sigev_new(_ec.inner, cb, userdata),
+ ec: _ec,
+ }
+ _ec.attach(rawptr_t(res.inner), res)
+ runtime.SetFinalizer(res, func(self SigEvent) { self.free() })
+ return res
}
-func (self SigEvent) Add(sig int) { C.sigev_add(self, C.int(sig)) }
-func (self SigEvent) Free() { C.sigev_free(self) }
+func (self SigEvent) free() { C.sigev_free(self.inner) }
+func (self SigEvent) Add(sig int) { C.sigev_add(self.inner, C.int(sig)) }
+func (self SigEvent) Del() {
+ self.ec.detach(rawptr_t(self.inner))
+ C.sigev_del(self.inner)
+}
+
+func (self SigEvent) Clear() {
+ self.ec.detach(rawptr_t(self.inner))
+ C.sigev_clear(self.inner)
+}
diff --git a/msg.go b/msg.go
index c3c0811..eb02fc3 100644
--- a/msg.go
+++ b/msg.go
@@ -3,20 +3,28 @@ package salticidae
// #include <stdlib.h>
// #include "salticidae/msg.h"
import "C"
+import "runtime"
-type Msg = *C.struct_msg_t
+type CMsg = *C.struct_msg_t
+type msg struct { inner CMsg }
+type Msg = *msg
+
+func MsgFromC(ptr *C.struct_msg_t) Msg { return &msg{ inner: ptr } }
func NewMsgMovedFromByteArray(opcode Opcode, _moved_payload ByteArray) Msg {
- return C.msg_new_moved_from_bytearray(C._opcode_t(opcode), _moved_payload)
+ res := &msg{ inner: C.msg_new_moved_from_bytearray(C._opcode_t(opcode), _moved_payload.inner) }
+ runtime.SetFinalizer(res, func(self Msg) { self.free() })
+ return res
}
-func (self Msg) Free() { C.msg_free(self) }
+func (self Msg) free() { C.msg_free(self.inner) }
func (self Msg) ConsumePayload() DataStream {
- return C.msg_consume_payload(self)
+ res := &dataStream{ inner: C.msg_consume_payload(self.inner) }
+ runtime.SetFinalizer(res, func(self DataStream) { self.free() })
+ return res
}
func (self Msg) GetOpcode() Opcode {
- return Opcode(C.msg_get_opcode(self))
+ return Opcode(C.msg_get_opcode(self.inner))
}
-
diff --git a/netaddr.go b/netaddr.go
index a631689..ab261b5 100644
--- a/netaddr.go
+++ b/netaddr.go
@@ -3,33 +3,50 @@ package salticidae
// #include <stdlib.h>
// #include "salticidae/netaddr.h"
import "C"
+import "runtime"
-type NetAddr = *C.netaddr_t
-type NetAddrArray = *C.netaddr_array_t
+type netAddr struct {
+ inner *C.netaddr_t
+}
+
+type NetAddr = *netAddr
+
+type netAddrArray struct {
+ inner *C.netaddr_array_t
+}
+
+type NetAddrArray = *netAddrArray
func NewAddrFromIPPortString(addr string) (res NetAddr) {
c_str := C.CString(addr)
- res = C.netaddr_new_from_sipport(c_str)
+ res = &netAddr{ inner: C.netaddr_new_from_sipport(c_str) }
C.free(rawptr_t(c_str))
+ runtime.SetFinalizer(res, func(self NetAddr) { self.free() })
return
}
-func (self NetAddr) Free() { C.netaddr_free(self) }
-
-func (self NetAddr) IsEq(other NetAddr) bool { return bool(C.netaddr_is_eq(self, other)) }
-
-func (self NetAddr) IsNull() bool { return bool(C.netaddr_is_null(self)) }
-
-func (self NetAddr) GetIP() uint32 { return uint32(C.netaddr_get_ip(self)) }
-
-func (self NetAddr) GetPort() uint16 { return uint16(C.netaddr_get_port(self)) }
-
-func NewAddrArrayFromAddrs(arr []NetAddr) NetAddrArray {
+func NewAddrArrayFromAddrs(arr []NetAddr) (res NetAddrArray) {
size := len(arr)
if size > 0 {
- base := (**C.netaddr_t)(&arr[0])
- return C.netaddr_array_new_from_addrs(base, C.size_t(size))
+ // FIXME: here we assume struct of a single pointer has the same memory
+ // footprint the pointer
+ base := (**C.netaddr_t)(rawptr_t(&arr[0]))
+ res = &netAddrArray{ inner: C.netaddr_array_new_from_addrs(base, C.size_t(size)) }
} else {
- return C.netaddr_array_new()
+ res = &netAddrArray{ inner: C.netaddr_array_new() }
}
+ runtime.SetFinalizer(res, func(self NetAddrArray) { self.free() })
+ return
}
+
+func (self NetAddr) free() { C.netaddr_free(self.inner) }
+
+func (self NetAddr) IsEq(other NetAddr) bool { return bool(C.netaddr_is_eq(self.inner, other.inner)) }
+
+func (self NetAddr) IsNull() bool { return bool(C.netaddr_is_null(self.inner)) }
+
+func (self NetAddr) GetIP() uint32 { return uint32(C.netaddr_get_ip(self.inner)) }
+
+func (self NetAddr) GetPort() uint16 { return uint16(C.netaddr_get_port(self.inner)) }
+
+func (self NetAddrArray) free() { C.netaddr_array_free(self.inner) }
diff --git a/network.go b/network.go
index d4d85cd..fdc513b 100644
--- a/network.go
+++ b/network.go
@@ -2,16 +2,30 @@ package salticidae
// #include "salticidae/network.h"
import "C"
+import "runtime"
-type MsgNetwork = *C.struct_msgnetwork_t
+type CMsgNetwork = *C.msgnetwork_t
+type msgNetwork struct { inner CMsgNetwork }
+type MsgNetwork = *msgNetwork
-type MsgNetworkConn = *C.struct_msgnetwork_conn_t
+func MsgNetworkFromC(ptr CMsgNetwork) MsgNetwork {
+ return &msgNetwork{ inner: ptr }
+}
+
+type CMsgNetworkConn = *C.msgnetwork_conn_t
+type msgNetworkConn struct { inner CMsgNetworkConn }
+type MsgNetworkConn = *msgNetworkConn
+
+func MsgNetworkConnFromC(ptr CMsgNetworkConn) MsgNetworkConn {
+ return &msgNetworkConn{ inner: ptr }
+}
type MsgNetworkConnMode = C.msgnetwork_conn_mode_t
+func (self MsgNetworkConn) free() { C.msgnetwork_conn_free(self.inner) }
func (self MsgNetworkConn) GetNet() MsgNetwork {
- return C.msgnetwork_conn_get_net(self)
+ return &msgNetwork{ inner: C.msgnetwork_conn_get_net(self.inner) }
}
var (
@@ -21,77 +35,115 @@ var (
)
func (self MsgNetworkConn) GetMode() MsgNetworkConnMode {
- return C.msgnetwork_conn_get_mode(self)
+ return C.msgnetwork_conn_get_mode(self.inner)
}
func (self MsgNetworkConn) GetAddr() NetAddr {
- return C.msgnetwork_conn_get_addr(self)
+ res := &netAddr{ inner: C.msgnetwork_conn_get_addr(self.inner) }
+ runtime.SetFinalizer(res, func(self NetAddr) { self.free() })
+ return res
}
-type MsgNetworkConfig = *C.struct_msgnetwork_config_t
+type CMsgNetworkConfig = *C.msgnetwork_config_t
+type msgNetworkConfig struct { inner CMsgNetworkConfig }
+type MsgNetworkConfig = *msgNetworkConfig
-func NewMsgNetworkConfig() MsgNetworkConfig { return C.msgnetwork_config_new() }
+func MsgNetworkConfigFromC(ptr CMsgNetworkConfig) MsgNetworkConfig {
+ return &msgNetworkConfig{ inner: ptr }
+}
+
+func NewMsgNetworkConfig() MsgNetworkConfig {
+ res := &msgNetworkConfig{ inner: C.msgnetwork_config_new() }
+ runtime.SetFinalizer(res, func(self MsgNetworkConfig) { self.free() })
+ return res
+}
-func (self MsgNetworkConfig) Free() { C.msgnetwork_config_free(self) }
+func (self MsgNetworkConfig) free() { C.msgnetwork_config_free(self.inner) }
func (self MsgNetworkConfig) BurstSize(size int) {
- C.msgnetwork_config_burst_size(self, C.size_t(size))
+ C.msgnetwork_config_burst_size(self.inner, C.size_t(size))
}
func (self MsgNetworkConfig) MaxListenBacklog(backlog int) {
- C.msgnetwork_config_max_listen_backlog(self, C.int(backlog))
+ C.msgnetwork_config_max_listen_backlog(self.inner, C.int(backlog))
}
func (self MsgNetworkConfig) ConnServerTimeout(timeout float64) {
- C.msgnetwork_config_conn_server_timeout(self, C.double(timeout))
+ C.msgnetwork_config_conn_server_timeout(self.inner, C.double(timeout))
}
func (self MsgNetworkConfig) SegBuffSize(size int) {
- C.msgnetwork_config_seg_buff_size(self, C.size_t(size))
+ C.msgnetwork_config_seg_buff_size(self.inner, C.size_t(size))
}
func (self MsgNetworkConfig) NWorker(nworker int) {
- C.msgnetwork_config_nworker(self, C.size_t(nworker))
+ C.msgnetwork_config_nworker(self.inner, C.size_t(nworker))
}
func (self MsgNetworkConfig) QueueCapacity(capacity int) {
- C.msgnetwork_config_queue_capacity(self, C.size_t(capacity))
+ C.msgnetwork_config_queue_capacity(self.inner, C.size_t(capacity))
}
func NewMsgNetwork(ec EventContext, config MsgNetworkConfig) MsgNetwork {
- return C.msgnetwork_new(ec, config)
+ res := &msgNetwork { inner: C.msgnetwork_new(ec.inner, config.inner) }
+ ec.attach(rawptr_t(res.inner), res)
+ runtime.SetFinalizer(res, func(self MsgNetwork) { self.free() })
+ return res
}
-func (self MsgNetwork) Free() { C.msgnetwork_free(self) }
-func (self MsgNetwork) Listen(addr NetAddr, err *Error) { C.msgnetwork_listen(self, addr, err) }
-func (self MsgNetwork) Start() { C.msgnetwork_start(self) }
-
-func (self MsgNetwork) SendMsgByMove(msg Msg, conn MsgNetworkConn) { C.msgnetwork_send_msg_by_move(self, msg, conn) }
-func (self MsgNetwork) Connect(addr NetAddr, err *Error) MsgNetworkConn { return C.msgnetwork_connect(self, addr, err) }
-func (self MsgNetwork) Terminate(conn MsgNetworkConn) { C.msgnetwork_terminate(self, conn) }
+func (self MsgNetwork) free() { C.msgnetwork_free(self.inner) }
+func (self MsgNetwork) Listen(addr NetAddr, err *Error) { C.msgnetwork_listen(self.inner, addr.inner, err) }
+func (self MsgNetwork) Start() { C.msgnetwork_start(self.inner) }
-func (self MsgNetworkConn) Copy() MsgNetworkConn { return C.msgnetwork_conn_copy(self) }
-func (self MsgNetworkConn) Free() { C.msgnetwork_conn_free(self) }
+func (self MsgNetwork) SendMsgByMove(msg Msg, conn MsgNetworkConn) { C.msgnetwork_send_msg_by_move(self.inner, msg.inner, conn.inner) }
+func (self MsgNetwork) Connect(addr NetAddr, err *Error) MsgNetworkConn {
+ res := &msgNetworkConn { inner: C.msgnetwork_connect(self.inner, addr.inner, err) }
+ runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.free() })
+ return res
+}
+func (self MsgNetwork) Terminate(conn MsgNetworkConn) { C.msgnetwork_terminate(self.inner, conn.inner) }
-type MsgNetworkMsgCallback = C.msgnetwork_msg_callback_t
-type MsgNetworkConnCallback = C.msgnetwork_conn_callback_t
-type MsgNetworkErrorCallback = C.msgnetwork_error_callback_t
func (self MsgNetwork) RegHandler(opcode Opcode, callback MsgNetworkMsgCallback, userdata rawptr_t) {
- C.msgnetwork_reg_handler(self, C._opcode_t(opcode), callback, userdata)
+ C.msgnetwork_reg_handler(self.inner, C._opcode_t(opcode), callback, userdata)
}
func (self MsgNetwork) RegConnHandler(callback MsgNetworkConnCallback, userdata rawptr_t) {
- C.msgnetwork_reg_conn_handler(self, callback, userdata)
+ C.msgnetwork_reg_conn_handler(self.inner, callback, userdata)
}
func (self MsgNetwork) RegErrorHandler(callback MsgNetworkErrorCallback, userdata rawptr_t) {
- C.msgnetwork_reg_error_handler(self, callback, userdata)
+ C.msgnetwork_reg_error_handler(self.inner, callback, userdata)
+}
+
+
+func (self MsgNetworkConn) Copy() MsgNetworkConn {
+ res := &msgNetworkConn { inner: C.msgnetwork_conn_copy(self.inner) }
+ runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.free() })
+ return res
+}
+func (self MsgNetworkConn) Free() { C.msgnetwork_conn_free(self.inner) }
+
+type MsgNetworkMsgCallback = C.msgnetwork_msg_callback_t
+type MsgNetworkConnCallback = C.msgnetwork_conn_callback_t
+type MsgNetworkErrorCallback = C.msgnetwork_error_callback_t
+
+type CPeerNetwork = *C.peernetwork_t
+type peerNetwork struct { inner CPeerNetwork }
+type PeerNetwork = *peerNetwork
+
+func PeerNetworkFromC(ptr CPeerNetwork) PeerNetwork {
+ return &peerNetwork{ inner: ptr }
}
-type PeerNetwork = *C.struct_peernetwork_t
-type PeerNetworkConn = *C.struct_peernetwork_conn_t
+type CPeerNetworkConn = *C.peernetwork_conn_t
+type peerNetworkConn struct { inner CPeerNetworkConn }
+type PeerNetworkConn = *peerNetworkConn
+
+func PeerNetworkConnFromC(ptr CPeerNetworkConn) PeerNetworkConn {
+ return &peerNetworkConn{ inner: ptr }
+}
type PeerNetworkIdMode = C.peernetwork_id_mode_t
@@ -100,57 +152,86 @@ var (
ID_MODE_IP_PORT_BASED = PeerNetworkIdMode(C.ID_MODE_IP_PORT_BASED)
)
-type PeerNetworkConfig = *C.struct_peernetwork_config_t
+type CPeerNetworkConfig = *C.peernetwork_config_t
+type peerNetworkConfig struct { inner CPeerNetworkConfig }
+type PeerNetworkConfig = *peerNetworkConfig
-func NewPeerNetworkConfig() PeerNetworkConfig { return C.peernetwork_config_new() }
+func PeerNetworkConfigFromC(ptr CPeerNetworkConfig) PeerNetworkConfig {
+ return &peerNetworkConfig{ inner: ptr }
+}
+
+func NewPeerNetworkConfig() PeerNetworkConfig {
+ res := &peerNetworkConfig { inner: C.peernetwork_config_new() }
+ runtime.SetFinalizer(res, func(self PeerNetworkConfig) { self.free() })
+ return res
+}
-func (self PeerNetworkConfig) Free() { C.peernetwork_config_free(self) }
+func (self PeerNetworkConfig) free() { C.peernetwork_config_free(self.inner) }
func (self PeerNetworkConfig) RetryConnDelay(t_sec float64) {
- C.peernetwork_config_retry_conn_delay(self, C.double(t_sec))
+ C.peernetwork_config_retry_conn_delay(self.inner, C.double(t_sec))
}
func (self PeerNetworkConfig) PingPeriod(t_sec float64) {
- C.peernetwork_config_ping_period(self, C.double(t_sec))
+ C.peernetwork_config_ping_period(self.inner, C.double(t_sec))
}
func (self PeerNetworkConfig) ConnTimeout(t_sec float64) {
- C.peernetwork_config_conn_timeout(self, C.double(t_sec))
+ C.peernetwork_config_conn_timeout(self.inner, C.double(t_sec))
}
func (self PeerNetworkConfig) IdMode(mode PeerNetworkIdMode) {
- C.peernetwork_config_id_mode(self, mode)
+ C.peernetwork_config_id_mode(self.inner, mode)
}
func (self PeerNetworkConfig) AsMsgNetworkConfig() MsgNetworkConfig {
- return C.peernetwork_config_as_msgnetwork_config(self)
+ return &msgNetworkConfig { inner: C.peernetwork_config_as_msgnetwork_config(self.inner) }
}
func NewPeerNetwork(ec EventContext, config PeerNetworkConfig) PeerNetwork {
- return C.peernetwork_new(ec, config)
+ res := &peerNetwork { inner: C.peernetwork_new(ec.inner, config.inner) }
+ ec.attach(rawptr_t(res.inner), res)
+ runtime.SetFinalizer(res, func(self PeerNetwork) { self.free() })
+ return res
}
-func (self PeerNetwork) Free() { C.peernetwork_free(self) }
+func (self PeerNetwork) free() { C.peernetwork_free(self.inner) }
-func (self PeerNetwork) AddPeer(paddr NetAddr) { C.peernetwork_add_peer(self, paddr) }
+func (self PeerNetwork) AddPeer(paddr NetAddr) { C.peernetwork_add_peer(self.inner, paddr.inner) }
-func (self PeerNetwork) HasPeer(paddr NetAddr) bool { return bool(C.peernetwork_has_peer(self, paddr)) }
+func (self PeerNetwork) HasPeer(paddr NetAddr) bool { return bool(C.peernetwork_has_peer(self.inner, paddr.inner)) }
-func (self PeerNetwork) GetPeerConn(paddr NetAddr, err *Error) PeerNetworkConn { return C.peernetwork_get_peer_conn(self, paddr, err) }
+func (self PeerNetwork) GetPeerConn(paddr NetAddr, err *Error) PeerNetworkConn {
+ res := &peerNetworkConn{ inner: C.peernetwork_get_peer_conn(self.inner, paddr.inner, err) }
+ runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.free() })
+ return res
+}
-func (self PeerNetwork) AsMsgNetwork() MsgNetwork { return C.peernetwork_as_msgnetwork(self) }
+func (self PeerNetwork) AsMsgNetwork() MsgNetwork { return &msgNetwork{ inner: C.peernetwork_as_msgnetwork(self.inner) } }
-func NewMsgNetworkConnFromPeerNetWorkConn(conn PeerNetworkConn) MsgNetworkConn { return C.msgnetwork_conn_new_from_peernetwork_conn(conn) }
+func NewMsgNetworkConnFromPeerNetWorkConn(conn PeerNetworkConn) MsgNetworkConn {
+ res := &msgNetworkConn{ inner: C.msgnetwork_conn_new_from_peernetwork_conn(conn.inner) }
+ runtime.SetFinalizer(res, func(self MsgNetworkConn) { self.free() })
+ return res
+}
-func (self PeerNetworkConn) Copy() PeerNetworkConn { return C.peernetwork_conn_copy(self) }
+func (self PeerNetworkConn) Copy() PeerNetworkConn {
+ res := &peerNetworkConn { inner: C.peernetwork_conn_copy(self.inner) }
+ runtime.SetFinalizer(res, func(self PeerNetworkConn) { self.free() })
+ return res
+}
-func (self PeerNetworkConn) Free() { C.peernetwork_conn_free(self) }
+func (self PeerNetworkConn) free() { C.peernetwork_conn_free(self.inner) }
-func (self PeerNetwork) SendMsgByMove(_moved_msg Msg, paddr NetAddr) { C.peernetwork_send_msg_by_move(self, _moved_msg, paddr) }
+func (self PeerNetwork) SendMsgByMove(_moved_msg Msg, paddr NetAddr) {
+ C.peernetwork_send_msg_by_move(self.inner, _moved_msg.inner, paddr.inner)
+}
func (self PeerNetwork) MulticastMsgByMove(_moved_msg Msg, paddrs []NetAddr) {
na := NewAddrArrayFromAddrs(paddrs)
- C.peernetwork_multicast_msg_by_move(self, _moved_msg, na)
+ C.peernetwork_multicast_msg_by_move(self.inner, _moved_msg.inner, na.inner)
}
-func (self PeerNetwork) Listen(listenAddr NetAddr, err *Error) { C.peernetwork_listen(self, listenAddr, err) }
+func (self PeerNetwork) Listen(listenAddr NetAddr, err *Error) {
+ C.peernetwork_listen(self.inner, listenAddr.inner, err)
+}
diff --git a/salticidae b/salticidae
-Subproject 77a765023bff4fa3d41001bdc1de9d106e35f34
+Subproject 74e4246565ba5814a92ed9f84b13b17226f219d
diff --git a/stream.go b/stream.go
index d66d085..4fe7d7b 100644
--- a/stream.go
+++ b/stream.go
@@ -3,95 +3,128 @@ package salticidae
// #include <stdlib.h>
// #include "salticidae/stream.h"
import "C"
+import "runtime"
-type ByteArray = *C.struct_bytearray_t
+type byteArray struct {
+ inner *C.struct_bytearray_t
+}
+type ByteArray = *byteArray
+
+func NewByteArray() ByteArray {
+ res := &byteArray{ inner: C.bytearray_new() }
+ runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
+ return res
+}
-func NewByteArray() ByteArray { return C.bytearray_new() }
-func (self ByteArray) Free() { C.bytearray_free(self) }
+func (self ByteArray) free() { C.bytearray_free(self.inner) }
func NewByteArrayMovedFromDataStream(src DataStream) ByteArray {
- return C.bytearray_new_moved_from_datastream(src)
+ res := &byteArray{ inner: C.bytearray_new_moved_from_datastream(src.inner) }
+ runtime.SetFinalizer(res, func(self ByteArray) { self.free() })
+ return res
+}
+
+type dataStream struct {
+ inner *C.struct_datastream_t
}
-type DataStream = *C.struct_datastream_t
+type DataStream = *dataStream
+
+func NewDataStream() DataStream {
+ res := &dataStream{ inner: C.datastream_new() }
+ runtime.SetFinalizer(res, func(self DataStream) { self.free() })
+ return res
+}
-func NewDataStream() DataStream { return C.datastream_new() }
-func NewDataStreamFromBytes(bytes []byte) DataStream {
+func NewDataStreamFromBytes(bytes []byte) (res DataStream) {
size := len(bytes)
if size > 0 {
base := (*C.uint8_t)(&bytes[0])
- return C.datastream_new_from_bytes(base, C.size_t(size))
+ res = &dataStream{ inner: C.datastream_new_from_bytes(base, C.size_t(size)) }
} else {
- return C.datastream_new()
+ res = &dataStream{ inner: C.datastream_new() }
}
+ runtime.SetFinalizer(res, func(self DataStream) { self.free() })
+ return
}
-func (self DataStream) Free() { C.datastream_free(self) }
+func (self DataStream) free() { C.datastream_free(self.inner) }
func (self DataStream) AssignByCopy(src DataStream) {
- C.datastream_assign_by_copy(self, src)
+ C.datastream_assign_by_copy(self.inner, src.inner)
}
func (self DataStream) AssignByMove(src DataStream) {
- C.datastream_assign_by_move(self, src)
+ C.datastream_assign_by_move(self.inner, src.inner)
}
// TODO: datastream_data
-func (self DataStream) Clear() { C.datastream_clear(self) }
+func (self DataStream) Clear() { C.datastream_clear(self.inner) }
-func (self DataStream) Size() int { return int(C.datastream_size(self)) }
+func (self DataStream) Size() int { return int(C.datastream_size(self.inner)) }
-func (self DataStream) PutU8(v uint8) bool { return bool(C.datastream_put_u8(self, C.uint8_t(v))) }
-func (self DataStream) PutU16(v uint16) bool { return bool(C.datastream_put_u16(self, C.uint16_t(v))) }
-func (self DataStream) PutU32(v uint32) bool { return bool(C.datastream_put_u32(self, C.uint32_t(v))) }
-func (self DataStream) PutU64(v uint32) bool { return bool(C.datastream_put_u64(self, C.uint64_t(v))) }
+func (self DataStream) PutU8(v uint8) bool { return bool(C.datastream_put_u8(self.inner, C.uint8_t(v))) }
+func (self DataStream) PutU16(v uint16) bool { return bool(C.datastream_put_u16(self.inner, C.uint16_t(v))) }
+func (self DataStream) PutU32(v uint32) bool { return bool(C.datastream_put_u32(self.inner, C.uint32_t(v))) }
+func (self DataStream) PutU64(v uint32) bool { return bool(C.datastream_put_u64(self.inner, C.uint64_t(v))) }
-func (self DataStream) PutI8(v int8) bool { return bool(C.datastream_put_i8(self, C.int8_t(v))) }
-func (self DataStream) PutI16(v int16) bool { return bool(C.datastream_put_i16(self, C.int16_t(v))) }
-func (self DataStream) PutI32(v int32) bool { return bool(C.datastream_put_i32(self, C.int32_t(v))) }
-func (self DataStream) PutI64(v int32) bool { return bool(C.datastream_put_i64(self, C.int64_t(v))) }
+func (self DataStream) PutI8(v int8) bool { return bool(C.datastream_put_i8(self.inner, C.int8_t(v))) }
+func (self DataStream) PutI16(v int16) bool { return bool(C.datastream_put_i16(self.inner, C.int16_t(v))) }
+func (self DataStream) PutI32(v int32) bool { return bool(C.datastream_put_i32(self.inner, C.int32_t(v))) }
+func (self DataStream) PutI64(v int32) bool { return bool(C.datastream_put_i64(self.inner, C.int64_t(v))) }
func (self DataStream) PutData(bytes []byte) bool {
size := len(bytes)
if size > 0 {
base := (*C.uint8_t)(&bytes[0])
- return bool(C.datastream_put_data(self, base, C.size_t(size)))
+ return bool(C.datastream_put_data(self.inner, base, C.size_t(size)))
} else { return true }
}
-func (self DataStream) GetU8(succ *bool) uint8 { return uint8(C.datastream_get_u8(self, (*C.bool)(succ))) }
-func (self DataStream) GetU16(succ *bool) uint16 { return uint16(C.datastream_get_u16(self, (*C.bool)(succ))) }
-func (self DataStream) GetU32(succ *bool) uint32 { return uint32(C.datastream_get_u32(self, (*C.bool)(succ))) }
-func (self DataStream) GetU64(succ *bool) uint64 { return uint64(C.datastream_get_u64(self, (*C.bool)(succ))) }
+func (self DataStream) GetU8(succ *bool) uint8 { return uint8(C.datastream_get_u8(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetU16(succ *bool) uint16 { return uint16(C.datastream_get_u16(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetU32(succ *bool) uint32 { return uint32(C.datastream_get_u32(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetU64(succ *bool) uint64 { return uint64(C.datastream_get_u64(self.inner, (*C.bool)(succ))) }
-func (self DataStream) GetI8(succ *bool) int8 { return int8(C.datastream_get_i8(self, (*C.bool)(succ))) }
-func (self DataStream) GetI16(succ *bool) int16 { return int16(C.datastream_get_i16(self, (*C.bool)(succ))) }
-func (self DataStream) GetI32(succ *bool) int32 { return int32(C.datastream_get_i32(self, (*C.bool)(succ))) }
-func (self DataStream) GetI64(succ *bool) int64 { return int64(C.datastream_get_i64(self, (*C.bool)(succ))) }
+func (self DataStream) GetI8(succ *bool) int8 { return int8(C.datastream_get_i8(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetI16(succ *bool) int16 { return int16(C.datastream_get_i16(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetI32(succ *bool) int32 { return int32(C.datastream_get_i32(self.inner, (*C.bool)(succ))) }
+func (self DataStream) GetI64(succ *bool) int64 { return int64(C.datastream_get_i64(self.inner, (*C.bool)(succ))) }
func (self DataStream) GetDataInPlace(length int) []byte {
- base := C.datastream_get_data_inplace(self, C.size_t(length))
+ base := C.datastream_get_data_inplace(self.inner, C.size_t(length))
return C.GoBytes(rawptr_t(base), C.int(length))
}
-type UInt256 = *C.uint256_t
+type uint256 struct {
+ inner *C.uint256_t
+}
+
+type UInt256 = *uint256
-func NewUInt256() UInt256 { return C.uint256_new() }
-func (self UInt256) Free() { C.uint256_free(self) }
-func (self UInt256) UInt256IsNull() bool { return bool(C.uint256_is_null(self)) }
-func (self UInt256) UInt256IsEq(other UInt256) bool { return bool(C.uint256_is_eq(self, other)) }
-func (self UInt256) Serialize(s DataStream) { C.uint256_serialize(self, s) }
-func (self UInt256) Unserialize(s DataStream) { C.uint256_unserialize(self, s) }
-func (self UInt256) IsEq(other UInt256) bool { return bool(C.uint256_is_eq(self, other)) }
+func NewUInt256() UInt256 {
+ res := &uint256{ inner: C.uint256_new() }
+ runtime.SetFinalizer(res, func(self UInt256) { self.free() })
+ return res
+}
+
+func (self UInt256) free() { C.uint256_free(self.inner) }
+func (self UInt256) UInt256IsNull() bool { return bool(C.uint256_is_null(self.inner)) }
+func (self UInt256) UInt256IsEq(other UInt256) bool { return bool(C.uint256_is_eq(self.inner, other.inner)) }
+func (self UInt256) Serialize(s DataStream) { C.uint256_serialize(self.inner, s.inner) }
+func (self UInt256) Unserialize(s DataStream) { C.uint256_unserialize(self.inner, s.inner) }
+func (self UInt256) IsEq(other UInt256) bool { return bool(C.uint256_is_eq(self.inner, other.inner)) }
func (self DataStream) GetHash() UInt256 {
- return C.datastream_get_hash(self)
+ res := &uint256{ inner: C.datastream_get_hash(self.inner) }
+ runtime.SetFinalizer(res, func(self UInt256) { self.free() })
+ return res
}
func (self DataStream) GetHex() string {
- tmp := C.datastream_get_hex(self)
+ tmp := C.datastream_get_hex(self.inner)
res := C.GoString(tmp)
C.free(rawptr_t(tmp))
return res
@@ -101,6 +134,5 @@ func (self UInt256) GetHex() string {
s := NewDataStream()
self.Serialize(s)
res := s.GetHex()
- s.Free()
return res
}
diff --git a/test_msgnet/main.go b/test_msgnet/main.go
index 4c885d3..fd561f7 100644
--- a/test_msgnet/main.go
+++ b/test_msgnet/main.go
@@ -29,9 +29,9 @@ func msgHelloSerialize(name string, text string) salticidae.Msg {
serialized.PutData(t)
serialized.PutData([]byte(name))
serialized.PutData([]byte(text))
+ s := salticidae.NewByteArrayMovedFromDataStream(serialized)
return salticidae.NewMsgMovedFromByteArray(
- MSG_OPCODE_HELLO,
- salticidae.NewByteArrayMovedFromDataStream(serialized))
+ MSG_OPCODE_HELLO, s)
}
func msgHelloUnserialize(msg salticidae.Msg) (name string, text string) {
@@ -39,12 +39,12 @@ func msgHelloUnserialize(msg salticidae.Msg) (name string, text string) {
length := binary.LittleEndian.Uint32(p.GetDataInPlace(4))
name = string(p.GetDataInPlace(int(length)))
text = string(p.GetDataInPlace(p.Size()))
- p.Free()
return
}
func msgAckSerialize() salticidae.Msg {
- return salticidae.NewMsgMovedFromByteArray(MSG_OPCODE_ACK, salticidae.NewByteArray())
+ s := salticidae.NewByteArray()
+ return salticidae.NewMsgMovedFromByteArray(MSG_OPCODE_ACK, s)
}
func checkError(err *salticidae.Error) {
@@ -71,8 +71,8 @@ func onTerm(_ C.int, _ unsafe.Pointer) {
//export onReceiveHello
func onReceiveHello(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.Pointer) {
- msg := salticidae.Msg(_msg)
- conn := salticidae.MsgNetworkConn(_conn)
+ msg := salticidae.MsgFromC(salticidae.CMsg(_msg))
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
net := conn.GetNet()
myName := bob.name
if net == alice.net {
@@ -86,7 +86,7 @@ func onReceiveHello(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ u
//export onReceiveAck
func onReceiveAck(_ *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.Pointer) {
- conn := salticidae.MsgNetworkConn(_conn)
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
net := conn.GetNet()
name := bob.name
if net == alice.net {
@@ -97,18 +97,18 @@ func onReceiveAck(_ *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe
//export connHandler
func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, _ unsafe.Pointer) {
- conn := salticidae.MsgNetworkConn(_conn)
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
net := conn.GetNet()
- n := &bob
+ n := bob
if net == alice.net {
- n = &alice
+ n = alice
}
name := n.name
if connected {
if conn.GetMode() == salticidae.CONN_MODE_ACTIVE {
- fmt.Printf("[%s] Connected, sending hello.", name)
+ fmt.Printf("[%s] Connected, sending hello.\n", name)
hello := msgHelloSerialize(name, "Hello there!")
- n.net.SendMsgByMove(hello, conn)
+ (*n.net).SendMsgByMove(hello, conn)
} else {
fmt.Printf("[%s] Accepted, waiting for greetings.\n", name)
}
@@ -116,8 +116,7 @@ func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, _ unsafe.P
fmt.Printf("[%s] Disconnected, retrying.\n", name)
addr := conn.GetAddr()
err := salticidae.NewError()
- net.Connect(addr, &err).Free()
- addr.Free()
+ net.Connect(addr, &err)
}
}
@@ -139,7 +138,6 @@ func genMyNet(ec salticidae.EventContext, name string) MyNet {
n.net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), nil)
n.net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), nil)
n.net.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), nil)
- netconfig.Free()
return n
}
@@ -161,24 +159,15 @@ func main() {
bob.net.Listen(bob_addr, &err)
checkError(&err)
- alice.net.Connect(bob_addr, &err).Free()
+ alice.net.Connect(bob_addr, &err)
checkError(&err)
- bob.net.Connect(alice_addr, &err).Free()
+ bob.net.Connect(alice_addr, &err)
checkError(&err)
- alice_addr.Free()
- bob_addr.Free()
-
ev_int := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm), nil)
ev_int.Add(salticidae.SIGINT)
ev_term := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm), nil)
ev_term.Add(salticidae.SIGTERM)
ec.Dispatch()
-
- alice.net.Free()
- bob.net.Free()
- ev_int.Free()
- ev_term.Free()
- ec.Free()
}
diff --git a/test_p2p_stress/main.go b/test_p2p_stress/main.go
index 7cda52d..404956f 100644
--- a/test_p2p_stress/main.go
+++ b/test_p2p_stress/main.go
@@ -1,6 +1,7 @@
package main
// #cgo CFLAGS: -I${SRCDIR}/../salticidae/include/
+// #cgo LDFLAGS: ${SRCDIR}/../salticidae/libsalticidae.so -Wl,-rpath=${SRCDIR}/salticidae/
// #include <stdlib.h>
// #include <arpa/inet.h>
// #include "salticidae/network.h"
@@ -68,7 +69,6 @@ func msgAckUnserialize(msg salticidae.Msg) salticidae.UInt256 {
p := msg.ConsumePayload()
hash := salticidae.NewUInt256()
hash.Unserialize(p)
- p.Free()
return hash
}
@@ -89,11 +89,13 @@ type TestContext struct {
func (self TestContext) Free() {
if self.timer != nil {
- self.timer.Free()
C.free(unsafe.Pointer(self.timer_ctx))
}
- if self.hash != nil {
- self.hash.Free()
+}
+
+func (self AppContext) Free() {
+ for _, tc:= range self.tc {
+ tc.Free()
}
}
@@ -105,16 +107,6 @@ type AppContext struct {
tc map[uint64] *TestContext
}
-func (self AppContext) Free() {
- self.addr.Free()
- self.net.Free()
- self.tcall.Free()
- for _, tc:= range self.tc {
- tc.Free()
- }
- self.ec.Free()
-}
-
func NewTestContext() TestContext {
return TestContext { ncompleted: 0 }
}
@@ -137,10 +129,6 @@ func sendRand(size int, app *AppContext, conn salticidae.MsgNetworkConn) {
msg, hash := msgRandSerialize(size)
addr := conn.GetAddr()
tc := app.getTC(addr2id(addr))
- addr.Free()
- if tc.hash != nil {
- salticidae.UInt256(tc.hash).Free()
- }
tc.hash = hash
app.net.AsMsgNetwork().SendMsgByMove(msg, conn)
}
@@ -149,6 +137,7 @@ var apps []AppContext
var threads sync.WaitGroup
var segBuffSize = 4096
var ec salticidae.EventContext
+var ids []*C.int
//export onTimeout
func onTimeout(_ *C.timerev_t, userdata unsafe.Pointer) {
@@ -156,7 +145,9 @@ func onTimeout(_ *C.timerev_t, userdata unsafe.Pointer) {
app := &apps[ctx.app_id]
tc := app.getTC(uint64(ctx.addr_id))
tc.ncompleted++
- app.net.AsMsgNetwork().Terminate(salticidae.MsgNetworkConn(ctx.conn))
+ app.net.AsMsgNetwork().Terminate(
+ salticidae.MsgNetworkConnFromC(
+ salticidae.CMsgNetworkConn(ctx.conn)))
var s string
for addr_id, v := range app.tc {
s += fmt.Sprintf(" %d(%d)", C.ntohs(C.ushort(addr_id >> 32)), v.ncompleted)
@@ -166,33 +157,29 @@ func onTimeout(_ *C.timerev_t, userdata unsafe.Pointer) {
//export onReceiveRand
func onReceiveRand(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userdata unsafe.Pointer) {
- msg := salticidae.Msg(_msg)
+ msg := salticidae.MsgFromC(salticidae.CMsg(_msg))
bytes := msgRandUnserialize(msg)
hash := bytes.GetHash()
- bytes.Free()
- conn := salticidae.MsgNetworkConn(_conn)
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
net := conn.GetNet()
ack := msgAckSerialize(hash)
- hash.Free()
net.SendMsgByMove(ack, conn)
}
//export onReceiveAck
func onReceiveAck(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userdata unsafe.Pointer) {
- hash := msgAckUnserialize(salticidae.Msg(_msg))
+ hash := msgAckUnserialize(salticidae.MsgFromC(salticidae.CMsg(_msg)))
id := *(* int)(userdata)
app := &apps[id]
- conn := salticidae.MsgNetworkConn(_conn)
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
_addr := conn.GetAddr()
addr := addr2id(_addr)
- _addr.Free()
tc := app.getTC(addr)
if !hash.IsEq(tc.hash) {
//fmt.Printf("%s %s\n", hash.GetHex(), tc.hash.GetHex())
panic("corrupted I/O!")
}
- hash.Free()
if tc.state == segBuffSize * 2 {
sendRand(tc.state, app, conn)
@@ -200,10 +187,9 @@ func onReceiveAck(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userd
ctx := C.timeout_callback_context_new()
ctx.app_id = C.int(id)
ctx.addr_id = C.uint64_t(addr)
- ctx.conn = (*C.struct_msgnetwork_conn_t)(conn.Copy())
+ ctx.conn = C.msgnetwork_conn_copy(_conn)
if tc.timer != nil {
- tc.timer.Free()
- salticidae.MsgNetworkConn(tc.timer_ctx.conn).Free()
+ C.msgnetwork_conn_free(tc.timer_ctx.conn)
C.free(unsafe.Pointer(tc.timer_ctx))
}
tc.timer = salticidae.NewTimerEvent(app.ec, salticidae.TimerEventCallback(C.onTimeout), unsafe.Pointer(ctx))
@@ -221,14 +207,13 @@ func onReceiveAck(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, userd
//export connHandler
func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, userdata unsafe.Pointer) {
- conn := salticidae.MsgNetworkConn(_conn)
+ conn := salticidae.MsgNetworkConnFromC(salticidae.CMsgNetworkConn(_conn))
id := *(*int)(userdata)
app := &apps[id]
if connected {
if conn.GetMode() == salticidae.CONN_MODE_ACTIVE {
addr := conn.GetAddr()
tc := app.getTC(addr2id(addr))
- addr.Free()
tc.state = 1
fmt.Printf("INFO: increasing phase\n")
sendRand(tc.state, app, conn)
@@ -246,7 +231,7 @@ func errorHandler(_err *C.struct_SalticidaeCError, fatal C.bool, _ unsafe.Pointe
//export onStopLoop
func onStopLoop(_ *C.threadcall_handle_t, userdata unsafe.Pointer) {
- ec := salticidae.EventContext(userdata)
+ ec := apps[*(*int)(userdata)].ec
ec.Stop()
}
@@ -256,7 +241,7 @@ func onTerm(_ C.int, _ unsafe.Pointer) {
a := &apps[i]
a.tcall.AsyncCall(
salticidae.ThreadCallCallback(C.onStopLoop),
- unsafe.Pointer(a.ec))
+ unsafe.Pointer(ids[i]))
}
threads.Wait()
ec.Stop()
@@ -277,7 +262,7 @@ func main() {
netconfig.ConnTimeout(5)
netconfig.PingPeriod(2)
apps = make([]AppContext, len(addrs))
- ids := make([](*C.int), len(addrs))
+ ids = make([](*C.int), len(addrs))
for i, addr := range addrs {
ec := salticidae.NewEventContext()
apps[i] = AppContext {
@@ -297,7 +282,6 @@ func main() {
net.RegErrorHandler(salticidae.MsgNetworkErrorCallback(C.errorHandler), _i)
net.Start()
}
- netconfig.Free()
threads.Add(len(apps))
for i, _ := range apps {
@@ -324,8 +308,4 @@ func main() {
ev_term.Add(salticidae.SIGTERM)
ec.Dispatch()
-
- ev_int.Free()
- ev_term.Free()
- ec.Free()
}