libei: switch to a single ei_new() function

The main reason for having different functions to create the initial context
was so we can nest the ei struct inside the context-specific struct. That
shouldn't leak into the API though and our use-case is probably one where we
create one context, then iterate through possible backends until one succeds -
having different contexts here doesn't help then.

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 6a164dfb3a
commit 283cc87416
5 changed files with 45 additions and 39 deletions

View file

@ -29,8 +29,8 @@
#include "util-list.h"
#include "util-sources.h"
struct ei_backend {
void (*destroy)(struct ei *ei);
struct ei_backend_interface {
void (*destroy)(struct ei *ei, void *backend);
};
enum ei_state {
@ -46,7 +46,8 @@ struct ei {
struct logger *logger;
struct sink *sink;
struct source *source;
struct ei_backend backend;
struct ei_backend_interface backend_interface;
void *backend;
enum ei_state state;
struct list event_queue;
struct list devices;

View file

@ -35,51 +35,53 @@
#include "util-macros.h"
#include "util-sources.h"
#include "util-strings.h"
#include "util-object.h"
#include "libei.h"
#include "libei-private.h"
struct ei_socket {
struct ei base;
struct object object;
struct source *connection;
};
static inline struct ei_socket *
ei_socket(struct ei *ei)
{
return container_of(ei, struct ei_socket, base);
return ei->backend;
}
static inline void
ei_socket_destroy(struct ei_socket *socket)
{
socket->connection = source_unref(socket->connection);
}
OBJECT_IMPLEMENT_CREATE(ei_socket);
static
OBJECT_IMPLEMENT_UNREF(ei_socket);
static void
socket_destroy(struct ei *ei)
interface_socket_destroy(struct ei *ei, void *backend)
{
struct ei_socket *socket = backend;
ei_socket_unref(socket);
}
const struct ei_backend backend = {
.destroy = socket_destroy,
static const struct ei_backend_interface interface = {
.destroy = interface_socket_destroy,
};
_public_ struct ei *
ei_socket_new_context(void *user_data)
{
struct ei_socket *ctx = xalloc(sizeof *ctx);
ei_init_object(&ctx->base, NULL);
ctx->base.user_data = user_data;
ctx->base.backend = backend;
return &ctx->base;
}
_public_ int
ei_socket_init(struct ei *ei, const char *socketpath)
{
assert(ei);
assert(!ei->backend);
int rc = ei_init(ei);
if (rc)
return -rc;
struct ei_socket *ei_socket = ei_socket_create(&ei->object);
ei->backend = ei_socket;
ei->backend_interface = interface;
if (!socketpath)
socketpath = getenv("LIBEI_SOCKET");

View file

@ -114,13 +114,14 @@ static void
ei_destroy(struct ei *ei)
{
ei->logger = logger_unref(ei->logger);
if (ei->backend.destroy)
ei->backend.destroy(ei);
if (ei->backend_interface.destroy)
ei->backend_interface.destroy(ei, ei->backend);
ei->backend = NULL;
sink_unref(ei->sink);
free(ei->name);
}
OBJECT_IMPLEMENT_INIT(ei);
OBJECT_IMPLEMENT_CREATE(ei);
_public_
OBJECT_IMPLEMENT_REF(ei);
_public_
@ -130,10 +131,11 @@ _public_
OBJECT_IMPLEMENT_SETTER(ei, user_data, void *);
OBJECT_IMPLEMENT_GETTER(ei, user_data, void *);
int
ei_init(struct ei *ei)
_public_ struct ei *
ei_new(void *user_data)
{
ei_init_object(ei, NULL);
_cleanup_ei_ struct ei *ei = ei_create(NULL);
ei->state = EI_STATE_NEW;
list_init(&ei->event_queue);
list_init(&ei->devices);
@ -142,9 +144,12 @@ ei_init(struct ei *ei)
logger_set_priority(ei->logger, LOGGER_DEBUG);
ei->sink = sink_new();
if (!ei->sink)
return -EMFILE;
return NULL;
return 0;
ei->user_data = user_data;
ei->backend = NULL;
return steal(&ei);
}
_public_ int
@ -716,9 +721,7 @@ static MunitResult
test_init_unref(const MunitParameter params[], void *user_data)
{
/* need to alloc here so unref can free */
struct ei *ei = xalloc(sizeof(*ei));
ei_init(ei);
struct ei *ei = ei_new(NULL);
munit_assert_int(ei->state, ==, EI_STATE_NEW);
munit_assert(list_empty(&ei->event_queue));

View file

@ -108,9 +108,9 @@ ei_new(void *user_data);
void
ei_configure_name(struct ei * ei, const char *name);
struct ei *
ei_socket_new_context(void *user_data);
/**
* Initialize the ei context with a named socket as backend.
*/
int
ei_socket_init(struct ei *ei, const char *socketpath);

View file

@ -38,7 +38,7 @@
int main(int argc, char **argv)
{
const char SOCKETNAME[] = "eis.socket";
struct ei *ei = ei_socket_new_context(NULL);
struct ei *ei = ei_new(NULL);
assert(ei);
ei_configure_name(ei, "ei-socket-client-demo");