mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-31 20:30:09 +01:00
brei: add a brei context object
Having debugging in the brei code is useful, the only way we can do this is by passing the log handler down.
This commit is contained in:
parent
6721802059
commit
da51bc095f
6 changed files with 159 additions and 21 deletions
|
|
@ -31,6 +31,73 @@
|
|||
|
||||
#include "brei-shared.h"
|
||||
|
||||
struct brei_context {
|
||||
struct object object;
|
||||
void *parent_context;
|
||||
|
||||
brei_logfunc_t log_func;
|
||||
void *log_context;
|
||||
};
|
||||
|
||||
static void
|
||||
brei_context_destroy(struct brei_context *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
OBJECT_IMPLEMENT_CREATE(brei_context);
|
||||
OBJECT_IMPLEMENT_REF(brei_context);
|
||||
OBJECT_IMPLEMENT_UNREF_CLEANUP(brei_context);
|
||||
OBJECT_IMPLEMENT_SETTER(brei_context, log_func, brei_logfunc_t);
|
||||
OBJECT_IMPLEMENT_SETTER(brei_context, log_context, void *);
|
||||
|
||||
struct brei_context *
|
||||
brei_context_new(void *parent_context)
|
||||
{
|
||||
struct brei_context *brei = brei_context_create(NULL);
|
||||
|
||||
brei->parent_context = parent_context;
|
||||
|
||||
return brei;
|
||||
}
|
||||
|
||||
#define log_debug(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_info(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_warn(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_error(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__)
|
||||
#define log_bug(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_ERROR, __FILE__, __LINE__, __func__, "🪳 brei bug: " __VA_ARGS__)
|
||||
#define log_bug_client(T_, ...) \
|
||||
brei_log_msg((T_), BREI_LOG_PRIORITY_ERROR, __FILE__, __LINE__, __func__, "🪲 Bug: " __VA_ARGS__)
|
||||
|
||||
_printf_(6, 0) static void
|
||||
brei_log_msg_va(struct brei_context *brei,
|
||||
enum brei_log_priority priority,
|
||||
const char *file, int lineno, const char *func,
|
||||
const char *format,
|
||||
va_list ap)
|
||||
{
|
||||
if (brei->log_func && brei->log_context)
|
||||
brei->log_func(brei->log_context, priority, file, lineno, func, format, ap);
|
||||
}
|
||||
|
||||
|
||||
_printf_(6, 7) static void
|
||||
brei_log_msg(struct brei_context *brei,
|
||||
enum brei_log_priority priority,
|
||||
const char *file, int lineno, const char *func,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
brei_log_msg_va(brei, priority, file, lineno, func, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of int32s required to store count bytes.
|
||||
*/
|
||||
|
|
@ -41,11 +108,13 @@ bytes_to_int32(uint32_t count)
|
|||
}
|
||||
|
||||
static int
|
||||
brei_demarshal(struct iobuf *buf, const char *signature, union brei_arg **args_out)
|
||||
brei_demarshal(struct brei_context *brei, struct iobuf *buf, const char *signature, union brei_arg **args_out)
|
||||
{
|
||||
size_t nargs = strlen(signature);
|
||||
if (nargs > 256)
|
||||
if (nargs > 256) {
|
||||
log_bug(brei, "Too many arguments in signature (%zu)", nargs);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
/* This over-allocates if we have more than one char per type but meh */
|
||||
_cleanup_free_ union brei_arg *args = xalloc(nargs * sizeof(*args));
|
||||
|
|
@ -77,19 +146,25 @@ brei_demarshal(struct iobuf *buf, const char *signature, union brei_arg **args_o
|
|||
|
||||
uint32_t slen32 = bytes_to_int32(slen);
|
||||
if (end - p < slen32) {
|
||||
log_bug_client(brei, "Invalid string length %zu, only %li bytes remaining", slen, (end - p) * 4);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
const char *str = (char*)p;
|
||||
|
||||
/* strings must be null-terminated */
|
||||
if (slen && str[slen - 1] != '\0')
|
||||
if (slen && str[slen - 1] != '\0') {
|
||||
log_bug_client(brei, "Message string not zero-terminated");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
arg->str = str;
|
||||
p += slen32;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_bug(brei, "Invalid signature '%c'", *s);
|
||||
return -EBADMSG;
|
||||
}
|
||||
arg++;
|
||||
s++;
|
||||
|
|
@ -102,7 +177,7 @@ brei_demarshal(struct iobuf *buf, const char *signature, union brei_arg **args_o
|
|||
}
|
||||
|
||||
static int
|
||||
brei_marshal(struct iobuf *buf, const char *signature, size_t nargs, va_list args)
|
||||
brei_marshal(struct brei_context *brei, struct iobuf *buf, const char *signature, size_t nargs, va_list args)
|
||||
{
|
||||
const char *s = signature;
|
||||
int32_t i;
|
||||
|
|
@ -144,6 +219,9 @@ brei_marshal(struct iobuf *buf, const char *signature, size_t nargs, va_list arg
|
|||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_bug(brei, "Invalid signature '%c'", *s);
|
||||
return -EBADMSG;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
|
@ -152,7 +230,8 @@ brei_marshal(struct iobuf *buf, const char *signature, size_t nargs, va_list arg
|
|||
}
|
||||
|
||||
int
|
||||
brei_send_message(int fd,
|
||||
brei_send_message(struct brei_context *brei,
|
||||
int fd,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
|
|
@ -166,7 +245,7 @@ brei_send_message(int fd,
|
|||
iobuf_append(buf, (const char *)&id, 4);
|
||||
iobuf_append(buf, (const char *)&opcode, 4);
|
||||
|
||||
int rc = brei_marshal(buf, signature, nargs, args);
|
||||
int rc = brei_marshal(brei, buf, signature, nargs, args);
|
||||
|
||||
if (rc == 0) {
|
||||
/* now write the actual message length, including header */
|
||||
|
|
@ -178,7 +257,8 @@ brei_send_message(int fd,
|
|||
}
|
||||
|
||||
int
|
||||
brei_dispatch(int fd,
|
||||
brei_dispatch(struct brei_context *brei,
|
||||
int fd,
|
||||
int (*lookup_object)(uint32_t object_id, struct brei_object **object, void *user_data),
|
||||
void *user_data)
|
||||
{
|
||||
|
|
@ -222,6 +302,8 @@ brei_dispatch(int fd,
|
|||
assert(interface);
|
||||
|
||||
if (opcode >= interface->nincoming) {
|
||||
log_bug_client(brei, "opcode %u exceeds interface %s method count %u",
|
||||
opcode, interface->name, interface->nincoming);
|
||||
rc = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -231,17 +313,21 @@ brei_dispatch(int fd,
|
|||
/* Demarshal the protocol into a set of arguments */
|
||||
_cleanup_free_ union brei_arg * args = NULL;
|
||||
const char *signature = interface->incoming[opcode].signature;
|
||||
int nargs = brei_demarshal(buf, signature, &args);
|
||||
int nargs = brei_demarshal(brei, buf, signature, &args);
|
||||
if (nargs < 0) {
|
||||
rc = nargs;
|
||||
goto error;
|
||||
}
|
||||
|
||||
log_debug(brei, "dispatching %s.%s() on object %#x", interface->name, interface->incoming[opcode].name, object_id);
|
||||
|
||||
/* Success! Let's pass this on to the
|
||||
* context to process */
|
||||
rc = interface->dispatcher(object->implementation, opcode, nargs, args);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
log_error(brei, "dispatch failed with %d (%s)", -rc, strerror(-rc));
|
||||
goto error;
|
||||
}
|
||||
|
||||
iobuf_pop(buf, msglen - headersize);
|
||||
}
|
||||
|
|
@ -266,26 +352,27 @@ brei_drain_fd(int fd)
|
|||
#include "util-munit.h"
|
||||
|
||||
static int
|
||||
brei_marshal_va(struct iobuf *buf, const char *signature, size_t nargs, ...)
|
||||
brei_marshal_va(struct brei_context *brei, struct iobuf *buf, const char *signature, size_t nargs, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, nargs);
|
||||
int rc = brei_marshal(buf, signature, nargs, args);
|
||||
int rc = brei_marshal(brei, buf, signature, nargs, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_brei_marshal)
|
||||
{
|
||||
_unref_(brei_context) *brei = brei_context_new(NULL);
|
||||
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(64);
|
||||
const char *str = "eierspeise";
|
||||
|
||||
int rc = brei_marshal_va(buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
int rc = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
|
||||
_cleanup_free_ union brei_arg *args;
|
||||
rc = brei_demarshal(buf, "noiusf", &args);
|
||||
_cleanup_free_ union brei_arg *args = NULL;
|
||||
rc = brei_demarshal(brei, buf, "noiusf", &args);
|
||||
munit_assert_int(rc, ==, 6);
|
||||
|
||||
munit_assert_int(args[0].obj, ==, 0xab);
|
||||
|
|
@ -298,13 +385,30 @@ MUNIT_TEST(test_brei_marshal)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_brei_marshal_bad_sig)
|
||||
{
|
||||
_unref_(brei_context) *brei = brei_context_new(NULL);
|
||||
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(64);
|
||||
const char *str = "eierspeise";
|
||||
|
||||
int rc = brei_marshal_va(brei, buf, "noiusf", 5, 0xab, 0xcd, -13, 0xfffd, str, 1.45);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
|
||||
_cleanup_free_ union brei_arg *args = NULL;
|
||||
rc = brei_demarshal(brei, buf, "nxoiusf", &args);
|
||||
munit_assert_int(rc, ==, -EBADMSG);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
brei_send_message_va(int fd, uint32_t id, uint32_t opcode,
|
||||
const char *signature, size_t nargs, ...)
|
||||
{
|
||||
_unref_(brei_context) *brei = brei_context_new(NULL);
|
||||
va_list args;
|
||||
va_start(args, nargs);
|
||||
int rc = brei_send_message(fd, id, opcode, signature, nargs, args);
|
||||
int rc = brei_send_message(brei, fd, id, opcode, signature, nargs, args);
|
||||
va_end(args);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,11 +31,32 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#include "util-list.h"
|
||||
#include "util-object.h"
|
||||
|
||||
struct brei_interface;
|
||||
struct brei_message;
|
||||
struct brei_object;
|
||||
|
||||
struct brei_context;
|
||||
|
||||
enum brei_log_priority {
|
||||
BREI_LOG_PRIORITY_DEBUG = 10,
|
||||
BREI_LOG_PRIORITY_INFO = 20,
|
||||
BREI_LOG_PRIORITY_WARNING = 30,
|
||||
BREI_LOG_PRIORITY_ERROR = 40,
|
||||
};
|
||||
|
||||
typedef void (*brei_logfunc_t)(void *context, enum brei_log_priority priority,
|
||||
const char *file, int lineno, const char *func,
|
||||
const char *format, va_list args);
|
||||
|
||||
struct brei_context *brei_context_new(void *user_data);
|
||||
|
||||
OBJECT_DECLARE_SETTER(brei_context, log_func, brei_logfunc_t);
|
||||
OBJECT_DECLARE_SETTER(brei_context, log_context, void *);
|
||||
OBJECT_DECLARE_REF(brei_context);
|
||||
OBJECT_DECLARE_UNREF(brei_context);
|
||||
|
||||
union brei_arg {
|
||||
uint32_t u32;
|
||||
int32_t i32;
|
||||
|
|
@ -77,7 +98,8 @@ struct brei_object {
|
|||
};
|
||||
|
||||
int
|
||||
brei_send_message(int fd,
|
||||
brei_send_message(struct brei_context *brei,
|
||||
int fd,
|
||||
uint32_t id,
|
||||
uint32_t opcode,
|
||||
const char *signature,
|
||||
|
|
@ -95,7 +117,8 @@ brei_send_message(int fd,
|
|||
* @return zero on success or a negative errno otherwise
|
||||
*/
|
||||
int
|
||||
brei_dispatch(int fd,
|
||||
brei_dispatch(struct brei_context *brei,
|
||||
int fd,
|
||||
int (*lookup_object)(uint32_t object_id, struct brei_object **object, void *user_data),
|
||||
void *user_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct ei {
|
|||
uint32_t next_object_id;
|
||||
|
||||
void *user_data;
|
||||
struct brei_context *brei;
|
||||
struct sink *sink;
|
||||
struct source *source;
|
||||
struct ei_backend_interface backend_interface;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ ei_destroy(struct ei *ei)
|
|||
ei->backend = NULL;
|
||||
ei_connection_setup_unref(ei->connection_setup);
|
||||
ei_connection_unref(ei->connection);
|
||||
brei_context_unref(ei->brei);
|
||||
sink_unref(ei->sink);
|
||||
free(ei->name);
|
||||
}
|
||||
|
|
@ -101,6 +102,9 @@ ei_create_context(bool is_sender, void *user_data)
|
|||
|
||||
ei->connection_setup = ei_connection_setup_new(ei, VERSION_V(1));
|
||||
ei->next_object_id = 1;
|
||||
ei->brei = brei_context_new(ei);
|
||||
brei_context_set_log_context(ei->brei, ei);
|
||||
brei_context_set_log_func(ei->brei, (brei_logfunc_t)ei_log_msg_va);
|
||||
|
||||
ei_log_set_handler(ei, NULL);
|
||||
ei_log_set_priority(ei, EI_LOG_PRIORITY_INFO);
|
||||
|
|
@ -697,7 +701,7 @@ connection_dispatch(struct source *source, void *userdata)
|
|||
struct ei *ei = userdata;
|
||||
enum ei_state old_state = ei->state;
|
||||
|
||||
int rc = brei_dispatch(source_get_fd(source), lookup_object, ei);
|
||||
int rc = brei_dispatch(ei->brei, source_get_fd(source), lookup_object, ei);
|
||||
if (rc < 0) {
|
||||
brei_drain_fd(source_get_fd(source));
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -738,7 +742,7 @@ ei_send_message(struct ei *ei, const struct brei_object *object,
|
|||
|
||||
va_list args;
|
||||
va_start(args, nargs);
|
||||
int rc = brei_send_message(fd, object->id, opcode, signature, nargs, args);
|
||||
int rc = brei_send_message(ei->brei, fd, object->id, opcode, signature, nargs, args);
|
||||
va_end(args);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ eis_client_destroy(struct eis_client *client)
|
|||
eis_connection_setup_unref(client->setup);
|
||||
eis_connection_unref(client->connection);
|
||||
free(client->name);
|
||||
brei_context_unref(client->brei);
|
||||
source_remove(client->source);
|
||||
source_unref(client->source);
|
||||
list_remove(&client->link);
|
||||
|
|
@ -158,7 +159,7 @@ eis_client_send_message(struct eis_client *client, const struct brei_object *obj
|
|||
|
||||
va_list args;
|
||||
va_start(args, nargs);
|
||||
int rc = brei_send_message(fd, object->id, opcode, signature, nargs, args);
|
||||
int rc = brei_send_message(client->brei, fd, object->id, opcode, signature, nargs, args);
|
||||
va_end(args);
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
|
@ -325,7 +326,7 @@ client_dispatch(struct source *source, void *userdata)
|
|||
_unref_(eis_client) *client = eis_client_ref(userdata);
|
||||
enum eis_client_state old_state = client->state;
|
||||
|
||||
int rc = brei_dispatch(source_get_fd(source), lookup_object, client);
|
||||
int rc = brei_dispatch(client->brei, source_get_fd(source), lookup_object, client);
|
||||
if (rc < 0) {
|
||||
brei_drain_fd(source_get_fd(source));
|
||||
client_disconnect(client, strerror(-rc));
|
||||
|
|
@ -358,6 +359,10 @@ eis_client_new(struct eis *eis, int fd)
|
|||
static uint32_t client_id;
|
||||
struct eis_client *client = eis_client_create(&eis->object);
|
||||
|
||||
client->brei = brei_context_new(client);
|
||||
brei_context_set_log_context(client->brei, eis);
|
||||
brei_context_set_log_func(client->brei, (brei_logfunc_t)eis_log_msg_va);
|
||||
|
||||
client->is_sender = true;
|
||||
client->id = ++client_id;
|
||||
list_init(&client->seats);
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct eis_client_interface_versions {
|
|||
|
||||
struct eis_client {
|
||||
struct object object;
|
||||
struct brei_context *brei;
|
||||
struct eis_connection *connection;
|
||||
|
||||
struct list proto_objects; /* struct brei_objects list */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue