From ad5342417e9c6e5930932afc9cfd71c88220501c Mon Sep 17 00:00:00 2001 From: HimbeerserverDE Date: Fri, 8 Oct 2021 20:08:52 +0200 Subject: [PATCH] Bug fixes (mainly threading) --- addr.c | 7 +-- listen.c | 42 ++++++++++++++---- listen.h | 8 +++- peer.c | 23 ++++++---- peer.h | 8 +++- recv_thread.c | 13 ++++-- typegen/main.c | 116 +++++++++++++++++++++++++++++-------------------- 7 files changed, 144 insertions(+), 73 deletions(-) diff --git a/addr.c b/addr.c index d675674..29765dd 100644 --- a/addr.c +++ b/addr.c @@ -18,11 +18,12 @@ DragonnetAddr dragonnet_addr_parse_str(char *str) } } + size_t ip_addr_i = 0, port_i = 0; for (size_t i = 0; i < strlen(str); ++i) { - if (i < colon_i) - addr.ip[i] = str[i]; + if (i < colon_i && str[i] != '[' && str[i] != ']') + addr.ip[ip_addr_i++] = str[i]; else if (i > colon_i) - addr.port[i-colon_i-1] = str[i]; + addr.port[port_i++] = str[i]; } return addr; diff --git a/listen.c b/listen.c index 4a819a7..a4b19bf 100644 --- a/listen.c +++ b/listen.c @@ -17,9 +17,12 @@ static bool dragonnet_peer_init_accepted(DragonnetPeer *p, int sock, pthread_rwlock_init(&p->mu, NULL); pthread_rwlock_wrlock(&p->mu); + pthread_rwlock_rdlock(&l->mu); p->sock = sock; p->laddr = l->laddr; p->raddr = dragonnet_addr_parse_sock(addr); + p->on_recv_type = l->on_recv_type; + pthread_rwlock_unlock(&l->mu); pthread_rwlock_unlock(&p->mu); return true; @@ -42,7 +45,8 @@ static DragonnetPeer *dragonnet_peer_accept(int sock, struct sockaddr_in6 addr, // -------- DragonnetListener *dragonnet_listener_new(char *addr, - void (*on_connect)(DragonnetPeer *p)) + void (*on_connect)(DragonnetPeer *p), + void (*on_recv_type)(struct dragonnet_peer *, u16)) { DragonnetListener *l = malloc(sizeof *l); pthread_rwlock_init(&l->mu, NULL); @@ -50,6 +54,7 @@ DragonnetListener *dragonnet_listener_new(char *addr, l->sock = socket(AF_INET6, SOCK_STREAM, 0); l->on_connect = on_connect; + l->on_recv_type = on_recv_type; int so_reuseaddr = 1; if (setsockopt(l->sock, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, @@ -78,20 +83,24 @@ DragonnetListener *dragonnet_listener_new(char *addr, return l; } -void dragonnet_listener_run(DragonnetListener *l) +static void *listener_main(void *g_listener) { - pthread_rwlock_wrlock(&l->mu); + DragonnetListener *l = (DragonnetListener *) g_listener; + pthread_rwlock_wrlock(&l->mu); assert(l->state == DRAGONNET_LISTENER_CREATED); l->state++; - pthread_rwlock_unlock(&l->mu); while (l->state == DRAGONNET_LISTENER_ACTIVE) { struct sockaddr_in6 clt_addr; socklen_t clt_addrlen = sizeof clt_addr; - int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen); + pthread_rwlock_rdlock(&l->mu); + int sock = l->sock; + pthread_rwlock_unlock(&l->mu); + + int clt_sock = accept(sock, (struct sockaddr *) &clt_addr, &clt_addrlen); if (clt_sock < 0) { perror("accept"); continue; @@ -101,21 +110,38 @@ void dragonnet_listener_run(DragonnetListener *l) if (p == NULL) continue; - if (l->on_connect != NULL) - l->on_connect(p); + dragonnet_peer_run(p); + + pthread_rwlock_rdlock(&l->mu); + void (*on_connect)(DragonnetPeer *) = l->on_connect; + pthread_rwlock_unlock(&l->mu); + + if (on_connect != NULL) + on_connect(p); } + + return NULL; +} + +void dragonnet_listener_run(DragonnetListener *l) +{ + pthread_create(&l->accept_thread, NULL, &listener_main, l); } void dragonnet_listener_close(DragonnetListener *l) { pthread_rwlock_wrlock(&l->mu); + pthread_t accept_thread = l->accept_thread; assert(l->state == DRAGONNET_LISTENER_ACTIVE); close(l->sock); - l->sock = 0; + l->sock = -1; l->state++; pthread_rwlock_unlock(&l->mu); + + pthread_cancel(accept_thread); + pthread_join(accept_thread, NULL); } void dragonnet_listener_delete(DragonnetListener *l) diff --git a/listen.h b/listen.h index e1d96a3..28c4562 100644 --- a/listen.h +++ b/listen.h @@ -14,14 +14,18 @@ typedef enum { typedef struct { int sock; DragonnetAddr laddr; - void (*on_connect)(DragonnetPeer *p); DragonnetListenerState state; + pthread_t accept_thread; + + void (*on_connect)(DragonnetPeer *); + void (*on_recv_type)(struct dragonnet_peer *, u16); pthread_rwlock_t mu; } DragonnetListener; DragonnetListener *dragonnet_listener_new(char *addr, - void (*on_connect)(DragonnetPeer *p)); + void (*on_connect)(DragonnetPeer *p), + void (*on_recv_type)(struct dragonnet_peer *, u16)); void dragonnet_listener_run(DragonnetListener *l); void dragonnet_listener_close(DragonnetListener *l); void dragonnet_listener_delete(DragonnetListener *l); diff --git a/peer.c b/peer.c index d508f74..a1bb39d 100644 --- a/peer.c +++ b/peer.c @@ -6,13 +6,14 @@ #include "peer.h" #include "recv_thread.h" -static bool dragonnet_peer_init(DragonnetPeer *p, char *addr) +static bool dragonnet_peer_init(DragonnetPeer *p, char *addr, void (*on_recv_type)(struct dragonnet_peer *, u16)) { pthread_rwlock_init(&p->mu, NULL); pthread_rwlock_wrlock(&p->mu); p->sock = socket(AF_INET6, SOCK_STREAM, 0); p->raddr = dragonnet_addr_parse_str(addr); + p->on_recv_type = on_recv_type; struct sockaddr_in6 sock_addr = dragonnet_addr_sock(p->raddr); if (connect(p->sock, (const struct sockaddr *) &sock_addr, @@ -35,10 +36,10 @@ static bool dragonnet_peer_init(DragonnetPeer *p, char *addr) return true; } -DragonnetPeer *dragonnet_connect(char *addr) +DragonnetPeer *dragonnet_connect(char *addr, void (*on_recv_type)(struct dragonnet_peer *, u16)) { DragonnetPeer *p = malloc(sizeof *p); - if (!dragonnet_peer_init(p, addr)) { + if (!dragonnet_peer_init(p, addr, on_recv_type)) { dragonnet_peer_delete(p); return NULL; } @@ -48,21 +49,25 @@ DragonnetPeer *dragonnet_connect(char *addr) void dragonnet_peer_run(DragonnetPeer *p) { - pthread_t recv_thread; - pthread_create(&recv_thread, NULL, &dragonnet_peer_recv_thread, p); - pthread_join(recv_thread, NULL); + pthread_rwlock_wrlock(&p->mu); + pthread_create(&p->recv_thread, NULL, &dragonnet_peer_recv_thread, p); + pthread_rwlock_unlock(&p->mu); + + while (p->state < DRAGONNET_PEER_ACTIVE); } void dragonnet_peer_close(DragonnetPeer *p) { pthread_rwlock_wrlock(&p->mu); - if (p->state == DRAGONNET_PEER_ACTIVE) { + pthread_t recv_thread = p->recv_thread; + if (p->state == DRAGONNET_PEER_ACTIVE) shutdown(p->sock, SHUT_RDWR); - p->state++; - } pthread_rwlock_unlock(&p->mu); + + pthread_cancel(recv_thread); + pthread_join(recv_thread, NULL); } void dragonnet_peer_delete(DragonnetPeer *p) diff --git a/peer.h b/peer.h index 80e5a95..16c02f9 100644 --- a/peer.h +++ b/peer.h @@ -2,6 +2,7 @@ #define _DRAGONNET_PEER_H_ #include +#include #include "addr.h" @@ -11,15 +12,18 @@ typedef enum { DRAGONNET_PEER_CLOSED } DragonnetPeerState; -typedef struct { +typedef struct dragonnet_peer { int sock; DragonnetAddr laddr, raddr; DragonnetPeerState state; + pthread_t recv_thread; + + void (*on_recv_type)(struct dragonnet_peer *, u16); pthread_rwlock_t mu; } DragonnetPeer; -DragonnetPeer *dragonnet_connect(char *addr); +DragonnetPeer *dragonnet_connect(char *addr, void (*on_recv_type)(struct dragonnet_peer *, u16)); void dragonnet_peer_run(DragonnetPeer *p); void dragonnet_peer_close(DragonnetPeer *p); void dragonnet_peer_delete(DragonnetPeer *p); diff --git a/recv_thread.c b/recv_thread.c index b50c5a3..b4975fb 100644 --- a/recv_thread.c +++ b/recv_thread.c @@ -18,14 +18,14 @@ void *dragonnet_peer_recv_thread(void *g_peer) pthread_rwlock_unlock(&p->mu); while (true) { - u16 msg; + u16 type; // Copy socket fd so that shutdown doesn't block pthread_rwlock_rdlock(&p->mu); int sock = p->sock; pthread_rwlock_unlock(&p->mu); - ssize_t len = recv(sock, &msg, sizeof msg, MSG_WAITALL); + ssize_t len = recv(sock, &type, sizeof type, MSG_WAITALL); if (len < 0) { perror("recv"); dragonnet_peer_delete(p); @@ -44,6 +44,13 @@ void *dragonnet_peer_recv_thread(void *g_peer) return NULL; } - // Deserialization + type = be16toh(type); + + pthread_rwlock_rdlock(&p->mu); + void (*on_recv_type)(struct dragonnet_peer *, u16) = p->on_recv_type; + pthread_rwlock_unlock(&p->mu); + + if (on_recv_type != NULL) + on_recv_type(p, type); } } diff --git a/typegen/main.c b/typegen/main.c index e591a27..acf9f73 100644 --- a/typegen/main.c +++ b/typegen/main.c @@ -38,8 +38,8 @@ static void gen_serializers(FILE *c_fp, FILE *h_fp) fprintf(h_fp, "typedef struct {\n\tu32 siz;\n\tu8 *data;\n} Blob;\n\n"); for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static void dragonnet_send_u%d(DragonnetPeer *p, bool submit, u%d v)\n"; - char *fmt_s = "static void dragonnet_send_s%d(DragonnetPeer *p, bool submit, s%d v)\n"; + char *fmt_u = "__attribute__((unused)) static void send_u%d(DragonnetPeer *p, bool submit, u%d v)\n"; + char *fmt_s = "__attribute__((unused)) static void send_s%d(DragonnetPeer *p, bool submit, s%d v)\n"; fprintf(c_fp, fmt_u, bits, bits); fprintf(c_fp, "{\n"); @@ -53,41 +53,44 @@ static void gen_serializers(FILE *c_fp, FILE *h_fp) fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static void dragonnet_send_f%d(DragonnetPeer *p, bool submit, f%d v)\n"; + char *fmt_f = "static void send_f%d(DragonnetPeer *p, bool submit, f%d v)\n"; fprintf(c_fp, fmt_f, bits, bits); fprintf(c_fp, "{\n"); - fprintf(c_fp, "\tdragonnet_send_u%d(p, submit, (u%d) v);\n", bits, bits); + fprintf(c_fp, "\tsend_u%d(p, submit, (u%d) v);\n", bits, bits); fprintf(c_fp, "}\n\n"); } } for (u8 elems = 2; elems <= 4; ++elems) { for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static void dragonnet_send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)\n"; - char *fmt_s = "static void dragonnet_send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)\n"; + char *fmt_u = "__attribute__((unused)) static void send_v%du%d(DragonnetPeer *p, bool submit, v%du%d v)\n"; + char *fmt_s = "__attribute__((unused)) static void send_v%ds%d(DragonnetPeer *p, bool submit, v%ds%d v)\n"; fprintf(c_fp, fmt_u, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tu%d *ptr = &v.x;\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tdragonnet_send_u%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t\tsend_u%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); fprintf(c_fp, fmt_s, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\ts%d *ptr = &v.x;\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tdragonnet_send_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t\tsend_s%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static void dragonnet_send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)\n"; + char *fmt_f = "__attribute__((unused)) static void send_v%df%d(DragonnetPeer *p, bool submit, v%df%d v)\n"; fprintf(c_fp, fmt_f, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tf%d *ptr = &v.x;\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tdragonnet_send_s%d(p, (i == %d-1) ? submit : false, v[i]);\n", bits, elems); + fprintf(c_fp, "\t\tsend_f%d(p, (i == %d-1) ? submit : false, *ptr++);\n", bits, elems); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); } @@ -96,44 +99,47 @@ static void gen_serializers(FILE *c_fp, FILE *h_fp) for (u8 elems = 2; elems <= 4; ++elems) { for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static void dragonnet_send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n"; - char *fmt_s = "static void dragonnet_send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n"; + char *fmt_u = "__attribute__((unused)) static void send_aabb%du%d(DragonnetPeer *p, bool submit, aabb%du%d v)\n"; + char *fmt_s = "__attribute__((unused)) static void send_aabb%ds%d(DragonnetPeer *p, bool submit, aabb%ds%d v)\n"; fprintf(c_fp, fmt_u, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tdragonnet_send_v%du%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t\tsend_v%du%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); fprintf(c_fp, fmt_s, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tdragonnet_send_v%ds%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t\tsend_v%ds%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static void dragonnet_send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v);\n"; + char *fmt_f = "__attribute__((unused)) static void send_aabb%df%d(DragonnetPeer *p, bool submit, aabb%df%d v)\n"; fprintf(c_fp, fmt_f, elems, bits, elems, bits); fprintf(c_fp, "{\n"); + fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tdragonnet_send_v%df%d(p, (i == 1) ? submit : false, v[i]);\n", elems, bits); + fprintf(c_fp, "\t\tsend_v%df%d(p, (i == 1) ? submit : false, *ptr++);\n", elems, bits); fprintf(c_fp, "\t}\n"); fprintf(c_fp, "}\n\n"); } } } - fprintf(c_fp, "static void dragonnet_send_string(DragonnetPeer *p, bool submit, string v)\n"); + fprintf(c_fp, "__attribute__((unused)) static void send_string(DragonnetPeer *p, bool submit, string v)\n"); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v, strlen(v));\n"); fprintf(c_fp, "}\n\n"); - fprintf(c_fp, "static void dragonnet_send_Blob(DragonnetPeer *p, bool submit, Blob *v)\n\n"); + fprintf(c_fp, "__attribute__((unused)) static void send_Blob(DragonnetPeer *p, bool submit, Blob *v)\n\n"); fprintf(c_fp, "{\n"); - fprintf(c_fp, "\tdragonnet_send_u32(p, false, v->siz);\n"); + fprintf(c_fp, "\tsend_u32(p, false, v->siz);\n"); fprintf(c_fp, "\tdragonnet_send_raw(p, submit, v->data, v->siz);\n"); fprintf(c_fp, "}\n\n"); } @@ -141,40 +147,42 @@ static void gen_serializers(FILE *c_fp, FILE *h_fp) static void gen_deserializers(FILE *c_fp) { for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static u%d dragonnet_recv_u%d(DragonnetPeer *p)\n"; - char *fmt_s = "static s%d dragonnet_recv_s%d(DragonnetPeer *p)\n"; + char *fmt_u = "__attribute__((unused)) static u%d recv_u%d(DragonnetPeer *p)\n"; + char *fmt_s = "__attribute__((unused)) static s%d recv_s%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_u, bits, bits); fprintf(c_fp, "{\n"); - fprintf(c_fp, "\tu%d be = dragonnet_recv_raw(p, &be, sizeof be);\n", bits); + fprintf(c_fp, "\tu%d be;\n", bits); + fprintf(c_fp, "\tdragonnet_recv_raw(p, &be, sizeof be);\n"); fprintf(c_fp, "\treturn be%dtoh(be);\n", bits); fprintf(c_fp, "}\n\n"); fprintf(c_fp, fmt_s, bits, bits); fprintf(c_fp, "{\n"); - fprintf(c_fp, "\treturn (s%d) dragonnet_recv_u%d(p);\n", bits, bits); + fprintf(c_fp, "\treturn (s%d) recv_u%d(p);\n", bits, bits); fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static f%d dragonnet_recv_f%d(DragonnetPeer *p)\n"; + char *fmt_f = "__attribute__((unused)) static f%d recv_f%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_f, bits, bits); fprintf(c_fp, "{\n"); - fprintf(c_fp, "\treturn (f%d) dragonnet_recv_u%d(p);\n", bits, bits); + fprintf(c_fp, "\treturn (f%d) recv_u%d(p);\n", bits, bits); fprintf(c_fp, "}\n\n"); } } for (u8 elems = 2; elems <= 4; ++elems) { for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static v%du%d dragonnet_recv_v%du%d(DragonnetPeer *p)\n"; - char *fmt_s = "static v%ds%d dragonnet_recv_v%ds%d(DragonnetPeer *p)\n"; + char *fmt_u = "__attribute__((unused)) static v%du%d recv_v%du%d(DragonnetPeer *p)\n"; + char *fmt_s = "__attribute__((unused)) static v%ds%d recv_v%ds%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_u, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tv%du%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tu%d *ptr = &v.x;\n\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_u%d(p);\n", bits); + fprintf(c_fp, "\t\t*ptr++ = recv_u%d(p);\n", bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); @@ -182,20 +190,22 @@ static void gen_deserializers(FILE *c_fp) fprintf(c_fp, fmt_s, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tv%ds%d v = {0};\n", elems, bits); + fprintf(c_fp, "\ts%d *ptr = &v.x;\n\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_s%d(p);\n", bits); + fprintf(c_fp, "\t\t*ptr++ = recv_s%d(p);\n", bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static v%df%d dragonnet_recv_v%df%d(DragonnetPeer *p)\n"; + char *fmt_f = "__attribute__((unused)) static v%df%d recv_v%df%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_f, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tv%df%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tf%d *ptr = &v.x;\n\n", bits); fprintf(c_fp, "\tfor (u8 i = 0; i < %d; ++i) {\n", elems); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_f%d(p);\n", bits); + fprintf(c_fp, "\t\t*ptr++ = recv_f%d(p);\n", bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); @@ -205,14 +215,15 @@ static void gen_deserializers(FILE *c_fp) for (u8 elems = 2; elems <= 4; ++elems) { for (u8 bits = 8; bits <= 64; bits *= 2) { - char *fmt_u = "static aabb%du%d dragonnet_recv_aabb%du%d(DragonnetPeer *p)\n"; - char *fmt_s = "static aabb%ds%d dragonnet_recv_aabb%ds%d(DragonnetPeer *p)\n"; + char *fmt_u = "__attribute__((unused)) static aabb%du%d recv_aabb%du%d(DragonnetPeer *p)\n"; + char *fmt_s = "__attribute__((unused)) static aabb%ds%d recv_aabb%ds%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_u, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\taabb%du%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tv%du%d *ptr = &v.min;\n\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_v%du%d(p);\n", elems, bits); + fprintf(c_fp, "\t\t*ptr++ = recv_v%du%d(p);\n", elems, bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); @@ -220,20 +231,22 @@ static void gen_deserializers(FILE *c_fp) fprintf(c_fp, fmt_s, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\taabb%ds%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tv%ds%d *ptr = &v.min;\n\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_v%ds%d(p);\n", elems, bits); + fprintf(c_fp, "\t\t*ptr++ = recv_v%ds%d(p);\n", elems, bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); if (bits >= 32) { - char *fmt_f = "static aabb%df%d dragonnet_recv_aabb%df%d(DragonnetPeer *p)\n"; + char *fmt_f = "__attribute__((unused)) static aabb%df%d recv_aabb%df%d(DragonnetPeer *p)\n"; fprintf(c_fp, fmt_f, elems, bits, elems, bits); fprintf(c_fp, "{\n"); fprintf(c_fp, "\taabb%df%d v = {0};\n", elems, bits); + fprintf(c_fp, "\tv%df%d *ptr = &v.min;\n\n", elems, bits); fprintf(c_fp, "\tfor (u8 i = 0; i < 2; ++i) {\n"); - fprintf(c_fp, "\t\tv[i] = dragonnet_recv_v%ds%d(p);\n", elems, bits); + fprintf(c_fp, "\t\t*ptr++ = recv_v%df%d(p);\n", elems, bits); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); @@ -241,22 +254,22 @@ static void gen_deserializers(FILE *c_fp) } } - fprintf(c_fp, "static string dragonnet_recv_string(DragonnetPeer *p)\n"); + fprintf(c_fp, "__attribute__((unused)) static string recv_string(DragonnetPeer *p)\n"); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tstring v = malloc(sizeof(u16));\n\n"); fprintf(c_fp, "\tchar ch;\n"); fprintf(c_fp, "\tfor (u16 i = 0; ch != '\\0'; ++i) {\n"); - fprintf(c_fp, "\t\tch = dragonnet_recv_s8(p);\n"); + fprintf(c_fp, "\t\tch = recv_s8(p);\n"); fprintf(c_fp, "\t\tv[i] = ch;\n"); fprintf(c_fp, "\t}\n\n"); fprintf(c_fp, "\tv = realloc(v, strlen(v));\n"); fprintf(c_fp, "\treturn v;\n"); fprintf(c_fp, "}\n\n"); - fprintf(c_fp, "static Blob *dragonnet_recv_Blob(DragonnetPeer *p)\n\n"); + fprintf(c_fp, "__attribute__((unused)) static Blob *recv_Blob(DragonnetPeer *p)\n\n"); fprintf(c_fp, "{\n"); fprintf(c_fp, "\tBlob *v = malloc(sizeof *v);\n"); - fprintf(c_fp, "\tv->siz = dragonnet_recv_u32(p, false, v->siz);\n"); + fprintf(c_fp, "\tv->siz = recv_u32(p);\n"); fprintf(c_fp, "\tv->data = malloc(v->siz);\n"); fprintf(c_fp, "\tdragonnet_recv_raw(p, v->data, v->siz);\n\n"); fprintf(c_fp, "\treturn v;\n"); @@ -275,6 +288,8 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) fp = NULL; FILE *c_fp = fopen("dnet-types.c", "w"); + fprintf(c_fp, "#include \n"); + fprintf(c_fp, "#include \n"); fprintf(c_fp, "#include \n"); fprintf(c_fp, "#include \n\n"); fprintf(c_fp, "#include \"dnet-types.h\"\n\n"); @@ -319,12 +334,12 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) fprintf(c_fp, "}\n\n"); msg = msgs[i]; - fprintf(c_fp, "static void dragonnet_send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg); + fprintf(c_fp, "__attribute__((unused)) static void send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg); } else { char **tokens; size_t tokens_len = split(&tokens, msgs[i], " "); - fprintf(c_fp, "\tdragonnet_send_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]); + fprintf(c_fp, "\tsend_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]); free_split(tokens, tokens_len); tokens = NULL; @@ -342,14 +357,23 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) msg = msgs[i]; fprintf(h_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s type);\n", msg, msg); fprintf(c_fp, "void dragonnet_peer_send_%s(DragonnetPeer *p, %s type)\n{\n", msg, msg); + + char upper[1 + strlen(msgs[i])]; + char *ptr = upper; + strcpy(upper, msg); + + while ((*ptr = *ptr ? toupper(*ptr) : '\0')) + ++ptr; + + fprintf(c_fp, "\tsend_u16(p, false, DRAGONNET_TYPE_%s);\n", upper); } else { char **tokens; size_t tokens_len = split(&tokens, msgs[i], " "); if (i >= msgs_len-1 || msgs[1+i][0] != '\t') - fprintf(c_fp, "\tdragonnet_send_%s(p, true, type.%s);\n", &tokens[0][1], tokens[1]); + fprintf(c_fp, "\tsend_%s(p, true, type.%s);\n", &tokens[0][1], tokens[1]); else - fprintf(c_fp, "\tdragonnet_send_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]); + fprintf(c_fp, "\tsend_%s(p, false, type.%s);\n", &tokens[0][1], tokens[1]); free_split(tokens, tokens_len); tokens = NULL; @@ -374,7 +398,7 @@ int main(__attribute((unused)) int argc, __attribute((unused)) char **argv) char **tokens; size_t tokens_len = split(&tokens, msgs[i], " "); - fprintf(c_fp, "\ttype.%s = dragonnet_recv_%s(p);\n", tokens[1], &tokens[0][1]); + fprintf(c_fp, "\ttype.%s = recv_%s(p);\n", tokens[1], &tokens[0][1]); free_split(tokens, tokens_len); tokens = NULL; } -- 2.44.0