Files
2026-08-24 10:03:24 +08:00

98 lines
2.3 KiB
C

/*
* service.c
* SPDX-FileCopyrightText: 2023-2026 BlueALSA developers
* SPDX-License-Identifier: MIT
*/
#include "service.h"
#include <gio/gio.h>
#include <glib-object.h>
#include <glib.h>
#include "shared/log.h"
/**
* Simple read callback which drains the input buffer. */
int channel_drain_callback(GIOChannel * ch, GIOCondition cond,
G_GNUC_UNUSED void * userdata) {
char buffer[1024];
switch (cond) {
case G_IO_HUP:
case G_IO_ERR:
return G_SOURCE_REMOVE;
case G_IO_IN:
/* Just drain the input buffer. */
g_io_channel_read_chars(ch, buffer, sizeof(buffer), NULL, NULL);
g_printerr("#");
/* fall-through */
default:
return G_SOURCE_CONTINUE;
}
}
static void name_acquired(G_GNUC_UNUSED GDBusConnection * conn,
G_GNUC_UNUSED const char * name, void * userdata) {
mock_service_ready(userdata);
}
static void * mock_loop_run(void * userdata) {
MockService * service = userdata;
debug("Starting service loop: %s", service->name);
g_autoptr(GMainContext) context = g_main_context_new();
service->_loop = g_main_loop_new(context, FALSE);
g_main_context_push_thread_default(context);
g_assert((service->_id = g_bus_own_name_on_connection(service->_conn,
service->name, G_BUS_NAME_OWNER_FLAGS_NONE,
service->name_acquired_cb, service->name_lost_cb,
userdata, NULL)) != 0);
g_main_loop_run(service->_loop);
g_main_context_pop_thread_default(context);
return NULL;
}
void mock_service_start(void * service, GDBusConnection * conn) {
MockService * srv = service;
if (srv->name_acquired_cb == NULL)
/* Set default name acquired callback if not provided. */
srv->name_acquired_cb = name_acquired;
srv->_conn = g_object_ref(conn);
srv->_ready = g_async_queue_new();
srv->_thread = g_thread_new(srv->name, mock_loop_run, service);
g_async_queue_pop(srv->_ready);
}
void mock_service_ready(void * service) {
MockService * srv = service;
g_async_queue_push(srv->_ready, GINT_TO_POINTER(1));
}
void mock_service_stop(void * service) {
MockService * srv = service;
g_bus_unown_name(srv->_id);
g_main_loop_quit(srv->_loop);
g_main_loop_unref(srv->_loop);
g_thread_join(srv->_thread);
g_async_queue_unref(srv->_ready);
g_object_unref(srv->_conn);
}
void mock_service_free(void * service) {
MockService * srv = service;
srv->free(service);
}