libeis: switch to a single eis_new() function

The main reason for having different functions to create the initial context
was so we can nest the eis struct inside the context-specific struct. That
shouldn't leak into the API though.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-08-05 16:09:27 +10:00
parent bc5be06549
commit d2ecf43abd
5 changed files with 44 additions and 42 deletions

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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

View file

@ -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.

View file

@ -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;