98 lines
2.3 KiB
C
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);
|
|
}
|