diff --git a/src/libeis-private.h b/src/libeis-private.h index 7f68547..19d06ff 100644 --- a/src/libeis-private.h +++ b/src/libeis-private.h @@ -29,8 +29,8 @@ #include "util-list.h" #include "util-sources.h" -struct eis_backend { - void (*destroy)(struct eis *eis); +struct eis_backend_interface { + void (*destroy)(struct eis *eis, void *backend); }; struct eis { @@ -40,7 +40,8 @@ struct eis { struct sink *sink; struct list clients; - struct eis_backend backend; + struct eis_backend_interface backend_interface; + void *backend; struct list event_queue; }; diff --git a/src/libeis-socket.c b/src/libeis-socket.c index 68ab7c8..6186077 100644 --- a/src/libeis-socket.c +++ b/src/libeis-socket.c @@ -37,7 +37,7 @@ #include "libeis-private.h" struct eis_socket { - struct eis base; + struct object object; struct source *listener; char *socketpath; }; @@ -45,60 +45,62 @@ struct eis_socket { static inline struct eis_socket * eis_socket(struct eis *eis) { - return container_of(eis, struct eis_socket, base); + return eis->backend; } -static void -socket_destroy(struct eis *eis) +static inline void +eis_socket_destroy(struct eis_socket *socket) { - struct eis_socket *socket = eis_socket(eis); - + socket->listener = source_unref(socket->listener); if (socket->socketpath) { unlink(socket->socketpath); free(socket->socketpath); } } -const struct eis_backend backend = { - .destroy = socket_destroy, -}; +OBJECT_IMPLEMENT_CREATE(eis_socket); +static +OBJECT_IMPLEMENT_UNREF(eis_socket); -_public_ struct eis * -eis_socket_new_context(void *userdata) +static +OBJECT_IMPLEMENT_PARENT(eis_socket, eis); + +static void +interface_socket_destroy(struct eis *eis, void *backend) { - struct eis_socket *ctx = xalloc(sizeof *ctx); + struct eis_socket *socket = backend; + eis_socket_unref(socket); - eis_init_object(&ctx->base, NULL); - - ctx->base.userdata = userdata; - ctx->base.backend = backend; - - return &ctx->base; } +const struct eis_backend_interface interface = { + .destroy = interface_socket_destroy, +}; + static void listener_dispatch(struct source *source, void *data) { struct eis_socket *socket = data; + struct eis *eis = eis_socket_parent(socket); - log_debug(&socket->base, "New client connection waiting\n"); + log_debug(eis, "New client connection waiting\n"); int fd = accept4(source_get_fd(source), NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); if (fd == -1) return; - eis_client_new(&socket->base, fd); + eis_client_new(eis, fd); } _public_ int eis_socket_init(struct eis *eis, const char *socketpath) { assert(eis); + assert(!eis->backend); assert(socketpath); assert(socketpath[0] != '\0'); - int rc = eis_init(eis); - if (rc) - return -rc; + _cleanup_(eis_socket_cleanup) struct eis_socket *eis_socket = + eis_socket_create(&eis->object); _cleanup_free_ char *path; if (socketpath[0] == '/') { @@ -127,9 +129,10 @@ eis_socket_init(struct eis *eis, const char *socketpath) if (listen(sockfd, 2) == -1) return -errno; - struct eis_socket *socket = eis_socket(eis); - source_add_autoclose(eis->sink, sockfd, listener_dispatch, socket); - socket->socketpath = steal(&path); + source_add_autoclose(eis->sink, sockfd, listener_dispatch, eis_socket); + eis_socket->socketpath = steal(&path); + eis->backend = steal(&eis_socket); + eis->backend_interface = interface; return 0; } diff --git a/src/libeis.c b/src/libeis.c index e79b4a6..d5c0c55 100644 --- a/src/libeis.c +++ b/src/libeis.c @@ -145,12 +145,12 @@ static void eis_destroy(struct eis *eis) { eis->logger = logger_unref(eis->logger); - if (eis->backend.destroy) - eis->backend.destroy(eis); + if (eis->backend_interface.destroy) + eis->backend_interface.destroy(eis, eis->backend); sink_unref(eis->sink); } -OBJECT_IMPLEMENT_INIT(eis); +OBJECT_IMPLEMENT_CREATE(eis); _public_ OBJECT_IMPLEMENT_REF(eis); _public_ @@ -160,9 +160,11 @@ _public_ OBJECT_IMPLEMENT_SETTER(eis, userdata, void *); OBJECT_IMPLEMENT_GETTER(eis, userdata, void *); -int -eis_init(struct eis *eis) +_public_ struct eis * +eis_new(void *user_data) { + _cleanup_eis_ struct eis *eis = eis_create(NULL); + list_init(&eis->clients); list_init(&eis->event_queue); @@ -170,9 +172,9 @@ eis_init(struct eis *eis) logger_set_priority(eis->logger, LOGGER_DEBUG); eis->sink = sink_new(); if (!eis->sink) - return -EMFILE; + return NULL; - return 0; + return steal(&eis); } _public_ int diff --git a/src/libeis.h b/src/libeis.h index 973a621..7635048 100644 --- a/src/libeis.h +++ b/src/libeis.h @@ -109,7 +109,7 @@ enum eis_event_type { * Create a new libeis context with a refcount of 1. */ struct eis * -eis_new(void *userdata); +eis_new(void *user_data); struct eis * eis_ref(struct eis *eis); @@ -136,10 +136,6 @@ eis_portal_init(struct eis *ctx); int eis_dbus_init(struct eis *ctx); - -struct eis * -eis_socket_new_context(void *userdata); - /** * Initialize the context with a UNIX socket name. * If the path does not start with / it is relative to $XDG_RUNTIME_DIR. diff --git a/tools/eis-socket-server.c b/tools/eis-socket-server.c index 9c2785b..ab365a4 100644 --- a/tools/eis-socket-server.c +++ b/tools/eis-socket-server.c @@ -43,7 +43,7 @@ static void sighandler(int signal) { int main(int argc, char **argv) { - struct eis *eis = eis_socket_new_context(NULL); + struct eis *eis = eis_new(NULL); assert(eis); _cleanup_free_ char *socketpath = NULL;