From 08ee3cab641f367b642bc29f6540de6be85226bd Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Thu, 25 Aug 2022 10:47:06 +0200 Subject: net: rework API First, rename all API functions so that they start with net_. Second, abstract the basic TCP server functionality into tcp_server.c. This includes reworking net_accept so that it's a simple blocking operation, and putting the callback stuff to tcp_server.c. Also, the server now uses detached threads instead of fork(), since I want connection handlers to share memory. --- src/tcp_server.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/tcp_server.c (limited to 'src/tcp_server.c') diff --git a/src/tcp_server.c b/src/tcp_server.c new file mode 100644 index 0000000..dc7d47b --- /dev/null +++ b/src/tcp_server.c @@ -0,0 +1,92 @@ +#include "tcp_server.h" +#include "log.h" +#include "net.h" + +#include +#include +#include + +int tcp_server_create(struct tcp_server *server, const char *port) +{ + server->fd = net_bind(port); + if (server->fd < 0) + return server->fd; + + return 0; +} + +void tcp_server_destroy(const struct tcp_server *server) +{ + close(server->fd); +} + +struct child_context { + int fd; + tcp_server_conn_handler handler; + void *arg; +}; + +static void *connection_thread(void *_ctx) +{ + struct child_context *ctx = (struct child_context *)_ctx; + ctx->handler(ctx->fd, ctx->arg); + close(ctx->fd); + free(ctx); + return NULL; +} + +int tcp_server_accept(const struct tcp_server *server, tcp_server_conn_handler handler, void *arg) +{ + struct child_context *ctx; + pthread_attr_t child_attr; + pthread_t child; + int conn_fd, ret = 0; + + ret = net_accept(server->fd); + if (ret < 0) { + print_errno("accept"); + return ret; + } + conn_fd = ret; + + ctx = malloc(sizeof(*ctx)); + if (!ctx) { + print_errno("malloc"); + ret = -1; + goto close_conn; + } + *ctx = (struct child_context){conn_fd, handler, arg}; + + ret = pthread_attr_init(&child_attr); + if (ret < 0) { + print_errno("pthread_attr_init"); + goto free_ctx; + } + + ret = pthread_attr_setdetachstate(&child_attr, PTHREAD_CREATE_DETACHED); + if (ret < 0) { + print_errno("pthread_attr_setdetachstate"); + goto destroy_attr; + } + + ret = pthread_create(&child, &child_attr, connection_thread, ctx); + if (ret < 0) { + print_errno("pthread_create"); + goto destroy_attr; + } + + pthread_attr_destroy(&child_attr); + + return ret; + +destroy_attr: + pthread_attr_destroy(&child_attr); + +free_ctx: + free(ctx); + +close_conn: + close(conn_fd); + + return ret; +} -- cgit v1.3