Skip to content

Commit 08a693c

Browse files
committed
Fix destructor not being called
NIFs keep a reference to the allocated resource by default on allocation. We need to release that reference before returning, otherwise it will never be GC'd.
1 parent 6be60fa commit 08a693c

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

lib/libp2p.ex

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,37 @@ defmodule Libp2p do
1212
@typedoc """
1313
A handle to a Go resource.
1414
"""
15-
@type handle :: integer
15+
@opaque handle :: integer
1616

1717
@typedoc """
1818
A handle to a host.Host.
1919
"""
20-
@type host :: handle
20+
@opaque host :: handle
2121

2222
@typedoc """
2323
A handle to a peerstore.Peerstore.
2424
"""
25-
@type peerstore :: handle
25+
@opaque peerstore :: handle
2626

2727
@typedoc """
2828
A handle to a peer.ID.
2929
"""
30-
@type peer_id :: handle
30+
@opaque peer_id :: handle
3131

3232
@typedoc """
3333
A handle to a []multiaddr.MultiAddr.
3434
"""
35-
@type addrs :: handle
35+
@opaque addrs :: handle
3636

3737
@typedoc """
3838
A handle to a stream.
3939
"""
40-
@type stream :: handle
40+
@opaque stream :: handle
4141

4242
@typedoc """
4343
A handle to an Option.
4444
"""
45-
@type option :: handle
45+
@opaque option :: handle
4646

4747
@typedoc """
4848
An error returned by this module.

libp2p/libp2p.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "main.h"
22
#include "utils.h"
3+
#include <stdbool.h>
34
#include <erl_nif.h>
45

56
#define ERL_FUNCTION(FUNCTION_NAME) static ERL_NIF_TERM FUNCTION_NAME(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
@@ -31,7 +32,6 @@
3132
#FUNCTION_NAME, ARITY, FUNCTION_NAME \
3233
}
3334

34-
const uint64_t PID_LENGTH = 1024;
3535
const uint64_t BUFFER_SIZE = 4096;
3636

3737
/*************/
@@ -46,22 +46,24 @@ ErlNifResourceType *Multiaddr_arr;
4646
ErlNifResourceType *Stream;
4747

4848
// Resource type helpers
49-
void handle_cleanup(ErlNifEnv *env, void *arg)
49+
void handle_cleanup(ErlNifEnv *env, void *obj)
5050
{
51-
uintptr_t handle = (uintptr_t)arg;
52-
DeleteHandle(handle);
51+
uintptr_t *handle = obj;
52+
DeleteHandle(*handle);
5353
}
5454

55+
#define OPEN_RESOURCE_TYPE(NAME) ((NAME) = enif_open_resource_type(env, NULL, (#NAME), handle_cleanup, flags, NULL))
56+
5557
static int open_resource_types(ErlNifEnv *env, ErlNifResourceFlags flags)
5658
{
57-
int ok = 0;
58-
ok &= NULL == (Option = enif_open_resource_type(env, NULL, "Option_type", handle_cleanup, flags, NULL));
59-
ok &= NULL == (Host = enif_open_resource_type(env, NULL, "Host_type", handle_cleanup, flags, NULL));
60-
ok &= NULL == (Peerstore = enif_open_resource_type(env, NULL, "Peerstore_type", handle_cleanup, flags, NULL));
61-
ok &= NULL == (peer_ID = enif_open_resource_type(env, NULL, "peer_ID_type", handle_cleanup, flags, NULL));
62-
ok &= NULL == (Multiaddr_arr = enif_open_resource_type(env, NULL, "Multiaddr_arr_type", handle_cleanup, flags, NULL));
63-
ok &= NULL == (Stream = enif_open_resource_type(env, NULL, "Stream_type", handle_cleanup, flags, NULL));
64-
return ok ? 1 : 0;
59+
int failed = false;
60+
failed |= NULL == OPEN_RESOURCE_TYPE(Option);
61+
failed |= NULL == OPEN_RESOURCE_TYPE(Host);
62+
failed |= NULL == OPEN_RESOURCE_TYPE(Peerstore);
63+
failed |= NULL == OPEN_RESOURCE_TYPE(peer_ID);
64+
failed |= NULL == OPEN_RESOURCE_TYPE(Multiaddr_arr);
65+
failed |= NULL == OPEN_RESOURCE_TYPE(Stream);
66+
return failed;
6567
}
6668

6769
static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info)
@@ -111,6 +113,8 @@ static ERL_NIF_TERM get_handle_result(ErlNifEnv *env, ErlNifResourceType *type,
111113
IF_ERROR(obj == NULL, "couldn't create resource");
112114
*obj = handle;
113115
ERL_NIF_TERM term = enif_make_resource(env, obj);
116+
// NOTE: we need to release our reference, so it can be GC'd
117+
enif_release_resource(obj);
114118
return make_ok_tuple2(env, term);
115119
}
116120

libp2p/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ func HostNew(options []C.uintptr_t) C.uintptr_t {
7777
//export HostClose
7878
func (h C.uintptr_t) HostClose() {
7979
handle := cgo.Handle(h)
80-
defer handle.Delete()
8180
handle.Value().(host.Host).Close()
8281
}
8382

@@ -167,7 +166,6 @@ func (s C.uintptr_t) StreamWrite(data []byte) int {
167166
//export StreamClose
168167
func (s C.uintptr_t) StreamClose() {
169168
handle := cgo.Handle(s)
170-
defer handle.Delete()
171169
handle.Value().(network.Stream).Close()
172170
}
173171

0 commit comments

Comments
 (0)