summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/loop.c2
-rw-r--r--src/multiplex.c63
-rw-r--r--src/multiplex.h11
-rw-r--r--src/packet_cache.c28
-rw-r--r--src/packet_cache.h4
-rw-r--r--src/packet_pool.c48
-rw-r--r--src/packet_pool.h6
-rw-r--r--src/packet_stream.c89
-rw-r--r--src/packet_stream.h4
-rw-r--r--src/rpc.c6
-rw-r--r--src/socket/socket.h3
-rw-r--r--src/util/packet.h7
-rw-r--r--subprojects/libalabaster.wrap4
13 files changed, 178 insertions, 97 deletions
diff --git a/src/loop.c b/src/loop.c
index e4c2271..a879a11 100644
--- a/src/loop.c
+++ b/src/loop.c
@@ -25,11 +25,9 @@ s32 nn_event_loop_run_once(struct nn_event_loop *loop)
void nn_event_loop_sleep(struct nn_event_loop *loop, nn_os_tstamp delay)
{
- al_assert(delay >= NNWT_TS_FROM_USEC(1000));
u64 prev = nn_get_timestamp(), now;
while (delay >= 0.0) {
nn_event_loop_run_once(loop);
- nn_thread_sleep(NNWT_TS_FROM_USEC(1000));
now = nn_get_timestamp();
delay -= NNWT_TS_FROM_USEC(now - prev);
prev = now;
diff --git a/src/multiplex.c b/src/multiplex.c
index 0911540..b1db007 100644
--- a/src/multiplex.c
+++ b/src/multiplex.c
@@ -1,6 +1,7 @@
#define AL_LOG_SECTION "multiplex"
//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
+#include <al/atomic.h>
#include "multiplex.h"
@@ -92,25 +93,53 @@ void nn_multiplex_socket_close(struct nn_multiplex_socket *multi)
nn_socket_cleanup(&multi->sock);
}
-static struct nn_multiplex_direct multiplex_direct_global = { 0 };
+static struct nn_multiplex_direct direct_global = { 0 };
void nn_multiplex_direct_init(bool (*connection_callback)(void *, u8, struct nn_packet_stream *), void *userdata)
{
- multiplex_direct_global.closing_bridge = al_alloc_object(struct nn_packet_stream);
- multiplex_direct_global.connection_callback = connection_callback;
- multiplex_direct_global.userdata = userdata;
+ direct_global.connection_callback = connection_callback;
+ direct_global.userdata = userdata;
+}
+
+static void queue_packet_callback(void *userdata, struct nn_packet_stream *stream, struct nn_packet *packet)
+{
+ struct nn_multiplex_bridge *bridge = (struct nn_multiplex_bridge *)userdata;
+ (void)stream;
+ al_array_push(bridge->queue, packet);
}
static void direct_connect(struct nn_packet_stream *client, u8 id)
{
- struct nn_packet_stream *server = al_alloc_object(struct nn_packet_stream);
- nn_packet_stream_init(server, NULL, NULL, NULL);
- multiplex_direct_global.connection_callback(multiplex_direct_global.userdata, id, server);
- server->direct = client;
- client->direct = server;
- // Explicitly signal connected on the server first.
- nn_packet_stream_set_connected(server);
+ struct nn_multiplex_bridge *bridge = al_alloc_object(struct nn_multiplex_bridge);
+ bridge->broken = false;
+ al_array_init(bridge->queue);
+ bridge->bridge = al_alloc_object(struct nn_packet_stream);
+ nn_packet_stream_init(bridge->bridge, NULL, NULL, NULL);
+ // Server-side client, emulates the result of socket_accept().
+ struct nn_packet_stream *cl = al_alloc_object(struct nn_packet_stream);
+ nn_packet_stream_init(cl, NULL, NULL, NULL);
+ cl->is_direct = true;
+ client->is_direct = true;
+ atomic_store(void)(&cl->direct, client, AL_ATOMIC_RELAXED);
+ atomic_store(void)(&client->direct, cl, AL_ATOMIC_RELAXED);
+ cl->bridge = bridge;
+ cl->packet_callback = queue_packet_callback;
+ cl->userdata = bridge;
+ // The order of connect client -> global callback -> connect server-side client cannot change.
nn_packet_stream_set_connected(client);
+ direct_global.connection_callback(direct_global.userdata, id, cl);
+ nn_packet_stream_set_connected(cl);
+ // Resend any packets that might have been sent in client->connection_callback().
+ struct nn_packet *packet;
+ al_array_foreach(bridge->queue, i, packet) {
+ al_assert(cl->packet_callback != queue_packet_callback);
+ cl->packet_callback(cl->userdata, cl, packet);
+ if (bridge->broken) break;
+ }
+ bridge->queue.count = 0;
+ if (bridge->broken) {
+ nn_multiplex_bridge_free(bridge);
+ }
}
void nn_multiplex_direct_connect(struct nn_packet_stream *client, u8 id)
@@ -124,12 +153,10 @@ void nn_multiplex_direct_reconnect(struct nn_packet_stream *client)
direct_connect(client, client->id);
}
-struct nn_packet_stream *nn_multiplex_direct_get_bridge(void)
-{
- return multiplex_direct_global.closing_bridge;
-}
-
-void nn_multiplex_direct_close(void)
+void nn_multiplex_bridge_free(struct nn_multiplex_bridge *bridge)
{
- al_free(multiplex_direct_global.closing_bridge);
+ nn_packet_stream_free(bridge->bridge);
+ al_free(bridge->bridge);
+ al_array_free(bridge->queue);
+ al_free(bridge);
}
diff --git a/src/multiplex.h b/src/multiplex.h
index 946e570..255591a 100644
--- a/src/multiplex.h
+++ b/src/multiplex.h
@@ -8,11 +8,16 @@
#include "packet_stream.h"
struct nn_multiplex_direct {
- struct nn_packet_stream *closing_bridge;
bool (*connection_callback)(void *, u8 id, struct nn_packet_stream *stream);
void *userdata;
};
+struct nn_multiplex_bridge {
+ bool broken;
+ struct nn_packet_stream *bridge;
+ array(struct nn_packet *) queue;
+};
+
struct nn_multiplex_socket;
struct nn_multiplex_connection {
struct nn_socket sock;
@@ -36,5 +41,5 @@ void nn_multiplex_socket_close(struct nn_multiplex_socket *multi);
void nn_multiplex_direct_init(bool (*connection_callback)(void *, u8, struct nn_packet_stream *), void *userdata);
void nn_multiplex_direct_connect(struct nn_packet_stream *client, u8 id);
void nn_multiplex_direct_reconnect(struct nn_packet_stream *client);
-struct nn_packet_stream *nn_multiplex_direct_get_bridge(void);
-void nn_multiplex_direct_close(void);
+
+void nn_multiplex_bridge_free(struct nn_multiplex_bridge *bridge);
diff --git a/src/packet_cache.c b/src/packet_cache.c
index 2e907b3..8398d6c 100644
--- a/src/packet_cache.c
+++ b/src/packet_cache.c
@@ -10,12 +10,6 @@ void nn_packet_cache_init(struct nn_packet_cache *cache, u32 size)
nn_mutex_init(&cache->mutex);
}
-bool nn_packet_cache_available(struct nn_packet_cache *cache)
-{
- nn_mutex_lock(&cache->mutex);
- return !cache->disabled;
-}
-
void nn_packet_cache_send_packet(struct nn_packet_cache *cache, struct nn_packet *packet)
{
al_assert(!cache->disabled);
@@ -57,16 +51,6 @@ struct nn_packet *nn_packet_cache_at(struct nn_packet_cache *cache, u32 index)
return al_array_at(cache->cache, index);
}
-void nn_packet_cache_lock(struct nn_packet_cache *cache)
-{
- nn_mutex_lock(&cache->mutex);
-}
-
-void nn_packet_cache_unlock(struct nn_packet_cache *cache)
-{
- nn_mutex_unlock(&cache->mutex);
-}
-
void nn_packet_cache_disable(struct nn_packet_cache *cache)
{
nn_mutex_lock(&cache->mutex);
@@ -77,6 +61,12 @@ void nn_packet_cache_disable(struct nn_packet_cache *cache)
nn_mutex_unlock(&cache->mutex);
}
+bool nn_packet_cache_disabled(struct nn_packet_cache *cache)
+{
+ nn_mutex_lock(&cache->mutex);
+ return cache->disabled;
+}
+
void nn_packet_cache_enable(struct nn_packet_cache *cache)
{
nn_mutex_lock(&cache->mutex);
@@ -84,8 +74,14 @@ void nn_packet_cache_enable(struct nn_packet_cache *cache)
nn_mutex_unlock(&cache->mutex);
}
+void nn_packet_cache_unlock(struct nn_packet_cache *cache)
+{
+ nn_mutex_unlock(&cache->mutex);
+}
+
void nn_packet_cache_free(struct nn_packet_cache *cache)
{
+ al_assert(!cache->cache.count);
al_array_free(cache->cache);
nn_mutex_destroy(&cache->mutex);
nn_cond_destroy(&cache->cond);
diff --git a/src/packet_cache.h b/src/packet_cache.h
index 5d2535c..833ca23 100644
--- a/src/packet_cache.h
+++ b/src/packet_cache.h
@@ -14,12 +14,12 @@ struct nn_packet_cache {
};
void nn_packet_cache_init(struct nn_packet_cache *cache, u32 size);
-bool nn_packet_cache_available(struct nn_packet_cache *cache);
void nn_packet_cache_send_packet(struct nn_packet_cache *cache, struct nn_packet *packet);
void nn_packet_cache_flush(struct nn_packet_cache *cache);
bool nn_packet_cache_wait(struct nn_packet_cache *cache, u32 *count);
struct nn_packet *nn_packet_cache_at(struct nn_packet_cache *cache, u32 index);
-void nn_packet_cache_unlock(struct nn_packet_cache *cache);
void nn_packet_cache_disable(struct nn_packet_cache *cache);
+bool nn_packet_cache_disabled(struct nn_packet_cache *cache);
void nn_packet_cache_enable(struct nn_packet_cache *cache);
+void nn_packet_cache_unlock(struct nn_packet_cache *cache);
void nn_packet_cache_free(struct nn_packet_cache *cache);
diff --git a/src/packet_pool.c b/src/packet_pool.c
index 7d9ac4d..9fcbf18 100644
--- a/src/packet_pool.c
+++ b/src/packet_pool.c
@@ -2,6 +2,7 @@
static void return_internal(struct nn_packet_pool *pool, struct nn_packet *packet)
{
+ al_assert(!packet->opaque);
nn_packet_reset(packet);
al_array_push(pool->empty, packet);
}
@@ -30,21 +31,22 @@ static void signal_callback(struct ev_loop *loop, ev_async *w, s32 revents)
pool->sending.count = 0;
}
-void nn_packet_pool_init(struct nn_packet_pool *pool, u32 size,
+void nn_packet_pool_init(struct nn_packet_pool *pool, u32 size, u32 init,
struct nn_event_loop *loop, void (*callback)(void *, struct nn_packet *), void *userdata)
{
pool->loop = loop;
- pool->size = size;
+ pool->size = init;
+ pool->allowed = size;
pool->grow = false;
pool->flushing = false;
pool->disabled = false;
nn_cond_init(&pool->cond);
nn_mutex_init(&pool->mutex);
al_array_init(pool->ready);
- al_array_reserve(pool->ready, size);
+ al_array_reserve(pool->ready, pool->size);
al_array_init(pool->empty);
- al_array_reserve(pool->empty, size);
- for (u32 i = 0; i < size; i++) {
+ al_array_reserve(pool->empty, pool->size);
+ for (u32 i = 0; i < pool->size; i++) {
al_array_push(pool->empty, nn_packet_create());
}
al_array_init(pool->sending);
@@ -59,28 +61,28 @@ struct nn_packet *nn_packet_pool_get(struct nn_packet_pool *pool)
{
nn_mutex_lock(&pool->mutex);
if (!pool->disabled && !pool->empty.count) {
- if (pool->grow) {
+ if (pool->grow || pool->size < pool->allowed) {
al_array_push(pool->empty, nn_packet_create());
+ pool->size++;
} else {
nn_cond_wait(&pool->cond, &pool->mutex);
}
}
- if (pool->disabled) {
+ if (pool->disabled) { // Check disabled after wait().
nn_mutex_unlock(&pool->mutex);
return NULL;
}
+ al_assert(pool->empty.count > 0);
struct nn_packet *packet = al_array_pop(pool->empty);
nn_mutex_unlock(&pool->mutex);
return packet;
}
-void nn_packet_pool_submit(struct nn_packet_pool *pool, struct nn_packet *packet)
+bool nn_packet_pool_submit(struct nn_packet_pool *pool, struct nn_packet *packet)
{
nn_mutex_lock(&pool->mutex);
if (pool->disabled) {
- return_internal(pool, packet);
- nn_mutex_unlock(&pool->mutex);
- return;
+ return false;
}
al_array_push(pool->ready, packet);
bool flush = pool->ready.count >= pool->size / 2;
@@ -89,6 +91,7 @@ void nn_packet_pool_submit(struct nn_packet_pool *pool, struct nn_packet *packet
ev_async_send(pool->loop->ev, &pool->signal);
}
nn_mutex_unlock(&pool->mutex);
+ return true;
}
void nn_packet_pool_flush(struct nn_packet_pool *pool)
@@ -127,22 +130,26 @@ void nn_packet_pool_disable(struct nn_packet_pool *pool)
// This makes disable()/enable() required to be called from the loop thread.
ev_async_stop(pool->loop->ev, &pool->signal);
pool->flushing = false;
- struct nn_packet *packet;
- al_array_foreach(pool->ready, i, packet) {
- nn_packet_reset(packet);
- al_array_push(pool->empty, packet);
- }
- pool->ready.count = 0;
if (nn_cond_is_waiting(&pool->cond)) {
nn_cond_signal(&pool->cond);
}
nn_mutex_unlock(&pool->mutex);
}
+struct nn_packet *nn_packet_pool_pop(struct nn_packet_pool *pool)
+{
+ al_assert(pool->disabled);
+ struct nn_packet *packet = NULL;
+ if (pool->ready.count > 0) {
+ al_array_pop_at(pool->ready, 0, packet);
+ }
+ return packet;
+}
+
void nn_packet_pool_enable(struct nn_packet_pool *pool)
{
nn_mutex_lock(&pool->mutex);
- al_assert(pool->disabled);
+ al_assert(pool->disabled && !pool->ready.count);
pool->disabled = false;
ev_async_start(pool->loop->ev, &pool->signal);
nn_mutex_unlock(&pool->mutex);
@@ -163,12 +170,11 @@ void nn_packet_pool_free(struct nn_packet_pool *pool)
}
al_array_free(pool->empty);
al_array_foreach(pool->ready, i, packet) {
+ al_assert(!packet->opaque);
nn_packet_free(packet);
}
al_array_free(pool->ready);
- al_array_foreach(pool->sending, i, packet) {
- nn_packet_free(packet);
- }
+ al_assert(!pool->sending.count);
al_array_free(pool->sending);
nn_mutex_destroy(&pool->mutex);
nn_cond_destroy(&pool->cond);
diff --git a/src/packet_pool.h b/src/packet_pool.h
index 8e21c12..27e6254 100644
--- a/src/packet_pool.h
+++ b/src/packet_pool.h
@@ -25,6 +25,7 @@ enum {
struct nn_packet_pool {
struct nn_event_loop *loop;
u32 size;
+ u32 allowed;
bool grow;
bool flushing;
bool disabled;
@@ -38,14 +39,15 @@ struct nn_packet_pool {
void *userdata;
};
-void nn_packet_pool_init(struct nn_packet_pool *pool, u32 size,
+void nn_packet_pool_init(struct nn_packet_pool *pool, u32 size, u32 init,
struct nn_event_loop *loop, void (*callback)(void *, struct nn_packet *), void *userdata);
struct nn_packet *nn_packet_pool_get(struct nn_packet_pool *pool);
-void nn_packet_pool_submit(struct nn_packet_pool *pool, struct nn_packet *packet);
+bool nn_packet_pool_submit(struct nn_packet_pool *pool, struct nn_packet *packet);
void nn_packet_pool_flush(struct nn_packet_pool *pool);
void nn_packet_pool_lock(struct nn_packet_pool *pool);
void nn_packet_pool_return(struct nn_packet_pool *pool, struct nn_packet *packet);
void nn_packet_pool_unlock(struct nn_packet_pool *pool);
void nn_packet_pool_disable(struct nn_packet_pool *pool);
+struct nn_packet *nn_packet_pool_pop(struct nn_packet_pool *pool);
void nn_packet_pool_enable(struct nn_packet_pool *pool);
void nn_packet_pool_free(struct nn_packet_pool *pool);
diff --git a/src/packet_stream.c b/src/packet_stream.c
index ef53daf..93ce0d2 100644
--- a/src/packet_stream.c
+++ b/src/packet_stream.c
@@ -1,3 +1,5 @@
+#include <al/atomic.h>
+
#include "multiplex.h"
#include "packet_stream.h"
@@ -199,11 +201,13 @@ void nn_packet_stream_init(struct nn_packet_stream *stream,
void (*connection_closed_callback)(void *, struct nn_packet_stream *), void *userdata)
{
init_io_state(stream);
+ stream->sock.type = NNWT_SOCKET_INVALID;
stream->revent.data = stream;
stream->wevent.data = stream;
ev_init_n(&stream->revent, stream_read_callback);
ev_init_n(&stream->wevent, stream_write_callback);
- stream->direct = NULL;
+ stream->is_direct = false;
+ stream->bridge = NULL;
stream->connection_callback = connection_callback;
stream->connection_closed_callback = connection_closed_callback;
stream->packet_callback = NULL;
@@ -252,7 +256,6 @@ static bool do_connect_internal(struct nn_packet_stream *stream, str *addr, u16
s32 fd = nn_socket_get_fd(&stream->sock);
ev_io_set(&stream->revent, fd, EV_READ);
ev_io_set(&stream->wevent, fd, EV_WRITE);
- // Start non-blocking connection.
stream->connect = PACKET_STREAM_CONNECTING;
start_write_internal(stream);
return true;
@@ -285,7 +288,7 @@ bool nn_packet_stream_set_connected(struct nn_packet_stream *stream)
void nn_packet_stream_cork(struct nn_packet_stream *stream, bool cork)
{
- if (stream->direct) return;
+ if (stream->is_direct) return;
if (stream->connect == PACKET_STREAM_CONNECTED) {
if (cork && !stream->corked) {
ev_io_stop(stream->loop->ev, &stream->revent);
@@ -298,15 +301,16 @@ void nn_packet_stream_cork(struct nn_packet_stream *stream, bool cork)
bool nn_packet_stream_send_packet(struct nn_packet_stream *stream, struct nn_packet *packet)
{
+ if (stream->is_direct) {
+ stream->packet_dequeued_callback(stream->userdata, packet);
+ struct nn_packet_stream *direct = atomic_load(void)(&stream->direct, AL_ATOMIC_RELAXED);
+ direct->packet_callback(direct->userdata, direct, packet);
+ return true;
+ }
if (stream->connect == PACKET_STREAM_DISCONNECTING) {
return false;
}
al_assert(stream->connect == PACKET_STREAM_CONNECTED);
- if (stream->direct) {
- struct nn_packet_stream *direct = stream->direct;
- direct->packet_callback(direct->userdata, direct, packet);
- return true;
- }
al_array_push(stream->out.queue, packet);
if (!stream->out.running) {
start_write_internal(stream);
@@ -321,8 +325,8 @@ void nn_packet_stream_discard_queue(struct nn_packet_stream *stream)
void nn_packet_stream_return_packet(struct nn_packet_stream *stream, struct nn_packet *packet)
{
- if (stream->direct) {
- struct nn_packet_stream *direct = stream->direct;
+ if (stream->is_direct) {
+ struct nn_packet_stream *direct = atomic_load(void)(&stream->direct, AL_ATOMIC_RELAXED);
direct->packet_sent_callback(direct->userdata, packet);
} else {
nn_packet_free(packet);
@@ -331,44 +335,77 @@ void nn_packet_stream_return_packet(struct nn_packet_stream *stream, struct nn_p
void nn_packet_stream_return_packets(struct nn_packet_stream *stream, struct nn_packet **packets, u32 count)
{
- if (stream->direct) {
- struct nn_packet_stream *direct = stream->direct;
+ if (stream->is_direct) {
+ struct nn_packet_stream *direct = atomic_load(void)(&stream->direct, AL_ATOMIC_RELAXED);
if (direct->packets_sent_callback) {
direct->packets_sent_callback(direct->userdata, packets, count);
} else {
for (u32 i = 0; i < count; i++) {
- if (packets[i]) {
- direct->packet_sent_callback(direct->userdata, packets[i]);
- }
+ direct->packet_sent_callback(direct->userdata, packets[i]);
}
}
} else {
for (u32 i = 0; i < count; i++) {
- if (packets[i]) nn_packet_free(packets[i]);
+ nn_packet_free(packets[i]);
}
}
}
+static void bridge_packet_callback(void *userdata, struct nn_packet_stream *stream, struct nn_packet *packet)
+{
+ (void)userdata;
+ al_assert(stream->is_direct);
+ struct nn_packet_stream *direct = stream->direct;
+ direct->packet_sent_callback(direct->userdata, packet);
+}
+
+static inline void install_bridge(struct nn_packet_stream *stream, struct nn_packet_stream *direct, struct nn_packet_stream *bridge)
+{
+ bridge->is_direct = true;
+ bridge->direct = stream;
+ // Update all callbacks that could happen post-connection because
+ // direct->connection_closed_callback() could run the event loop after
+ // we update stream->direct to bridge.
+ bridge->packet_callback = bridge_packet_callback;
+ bridge->packet_dequeued_callback = direct->packet_dequeued_callback;
+ bridge->packet_sent_callback = direct->packet_sent_callback;
+ bridge->packets_sent_callback = direct->packets_sent_callback;
+ bridge->userdata = direct->userdata;
+ // nn_packet_stream_return_packet() needs to be thread-safe. Non-atomically updating
+ // the value of stream->direct here would break that.
+ atomic_store(void)(&stream->direct, bridge, AL_ATOMIC_RELEASE);
+}
+
void nn_packet_stream_disconnect(struct nn_packet_stream *stream)
{
al_assert(stream->connect != PACKET_STREAM_DISCONNECTED);
al_assert(stream->connect != PACKET_STREAM_DISCONNECTING);
- if (stream->direct) {
- struct nn_packet_stream *direct = stream->direct;
+ if (stream->is_direct) {
+ struct nn_packet_stream *direct = atomic_load(void)(&stream->direct, AL_ATOMIC_ACQUIRE);
+ // After direct->connection_closed_callback(), direct could be freed.
+ // So use the bridge to finish the disconnect() on this side of the stream.
+ struct nn_multiplex_bridge *bridge = NULL;
+ if (stream->bridge) {
+ bridge = stream->bridge;
+ stream->bridge = NULL;
+ } else if (direct->bridge) {
+ bridge = direct->bridge;
+ direct->bridge = NULL;
+ }
+ if (!bridge) {
+ return; // Disconnect already in progress.
+ }
direct->connect = PACKET_STREAM_DISCONNECTED;
stream->connect = PACKET_STREAM_DISCONNECTED;
direct->corked = true;
stream->corked = true;
- struct nn_packet_stream *bridge = nn_multiplex_direct_get_bridge();
- bridge->connection_callback = NULL;
- bridge->connection_closed_callback = NULL;
- bridge->packet_dequeued_callback = direct->packet_dequeued_callback;
- bridge->packet_sent_callback = direct->packet_sent_callback;
- bridge->packets_sent_callback = direct->packets_sent_callback;
- bridge->userdata = direct->userdata;
+ install_bridge(stream, direct, bridge->bridge);
direct->connection_closed_callback(direct->userdata, direct);
- stream->direct = bridge;
stream->connection_closed_callback(stream->userdata, stream);
+ bridge->broken = true; // See multiplex.c:direct_connect().
+ if (!bridge->queue.count) {
+ nn_multiplex_bridge_free(bridge);
+ }
return;
}
if (stream->connect == PACKET_STREAM_CONNECTING) {
diff --git a/src/packet_stream.h b/src/packet_stream.h
index 623f61f..aa9b1a7 100644
--- a/src/packet_stream.h
+++ b/src/packet_stream.h
@@ -12,7 +12,7 @@ struct nn_packet_stream {
struct nn_socket sock;
ev_io revent;
ev_io wevent;
- u8 id; // multiplex
+ u8 id;
u8 connect;
bool corked;
struct {
@@ -26,7 +26,9 @@ struct nn_packet_stream {
size_t index;
bool running;
} out;
+ bool is_direct;
struct nn_packet_stream *direct;
+ void *bridge;
bool (*connection_callback)(void *, struct nn_packet_stream *);
void (*connection_closed_callback)(void *, struct nn_packet_stream *);
void (*packet_callback)(void *, struct nn_packet_stream *, struct nn_packet *);
diff --git a/src/rpc.c b/src/rpc.c
index c48a0e3..19fdb9a 100644
--- a/src/rpc.c
+++ b/src/rpc.c
@@ -320,9 +320,9 @@ void nn_rpc_add_stream(struct nn_rpc *rpc, struct nn_packet_stream *stream)
struct nn_rpc_connection *conn = al_alloc_object(struct nn_rpc_connection);
init_rpc_connection(rpc, conn);
conn->stream = stream;
- conn->stream->connection_callback = stream_connection_callback;
- conn->stream->connection_closed_callback = stream_connection_closed_callback;
- conn->stream->userdata = conn;
+ stream->connection_callback = stream_connection_callback;
+ stream->connection_closed_callback = stream_connection_closed_callback;
+ stream->userdata = conn;
}
void nn_rpc_prepare_client(struct nn_rpc *rpc)
diff --git a/src/socket/socket.h b/src/socket/socket.h
index 31f23f3..b3f2d98 100644
--- a/src/socket/socket.h
+++ b/src/socket/socket.h
@@ -13,7 +13,8 @@
#endif
enum {
- NNWT_SOCKET_TCP = 0,
+ NNWT_SOCKET_INVALID = 0,
+ NNWT_SOCKET_TCP,
NNWT_SOCKET_UDP,
NNWT_SOCKET_UNIX
};
diff --git a/src/util/packet.h b/src/util/packet.h
index c8d9400..a649ff2 100644
--- a/src/util/packet.h
+++ b/src/util/packet.h
@@ -39,6 +39,13 @@ static inline u32 nn_packet_get_u32(struct nn_packet *packet, u32 index)
return value;
}
+static inline u8 nn_packet_get_u8(struct nn_packet *packet, u32 index)
+{
+ u8 value;
+ NNWT_BUFFER_READ_TYPE(&packet->buffer, index, u8, value);
+ return value;
+}
+
struct nn_packet *nn_packet_create(void);
struct nn_packet *nn_packet_clone(struct nn_packet *packet);
void nn_packet_reset(struct nn_packet *packet);
diff --git a/subprojects/libalabaster.wrap b/subprojects/libalabaster.wrap
index 7b8a7bf..432a813 100644
--- a/subprojects/libalabaster.wrap
+++ b/subprojects/libalabaster.wrap
@@ -1,5 +1,5 @@
[wrap-git]
-directory = libalabaster-81a7b4b
+directory = libalabaster-8386718
url = https://git.akon.city/libalabaster.git
-revision = 81a7b4ba322aeddf52207fdcd2213e5f5a493471
+revision = 8386718d2b7e5af4e74544922197df678a761c5f
depth = 1