1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-03-09 23:38:56 +00:00

miracle-wfdctl: integrate sd_event with GMainLoop for running gstreamer

in process instead of fork n exec gst-launch
This commit is contained in:
Derek Dai 2017-03-03 15:40:43 +08:00
parent 0e1f3243bc
commit c458b273b1
No known key found for this signature in database
GPG key ID: E109CC97553EF009
2 changed files with 125 additions and 24 deletions

View file

@ -2,9 +2,9 @@ find_package(Readline)
########### next target ############### ########### next target ###############
set(miracle-wifictl_SRCS ctl.h set(miracle-wifictl_SRCS ctl.h
ctl-cli.c ctl-cli.c
ctl-wifi.c ctl-wifi.c
wifictl.c) wifictl.c)
add_executable(miracle-wifictl ${miracle-wifictl_SRCS}) add_executable(miracle-wifictl ${miracle-wifictl_SRCS})
@ -22,12 +22,12 @@ target_link_libraries(miracle-wifictl miracle-shared)
########### next target ############### ########### next target ###############
set(miracle-sinkctl_SRCS ctl.h set(miracle-sinkctl_SRCS ctl.h
ctl-cli.c ctl-cli.c
ctl-sink.h ctl-sink.h
ctl-sink.c ctl-sink.c
ctl-wifi.c ctl-wifi.c
sinkctl.c sinkctl.c
wfd.c) wfd.c)
add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS}) add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS})
@ -57,7 +57,8 @@ set(miracle-wfdctl_SRCS ctl-cli.c
wfd-arg.c) wfd-arg.c)
include_directories(${CMAKE_BINARY_DIR} include_directories(${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src ${GLIB2_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/shared) ${CMAKE_SOURCE_DIR}/src/shared)
add_executable(miracle-wfdctl ${miracle-wfdctl_SRCS}) add_executable(miracle-wfdctl ${miracle-wfdctl_SRCS})
@ -72,7 +73,7 @@ if(READLINE_FOUND)
target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY}) target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY})
endif(READLINE_FOUND) endif(READLINE_FOUND)
target_link_libraries(miracle-wfdctl miracle-shared) target_link_libraries(miracle-wfdctl miracle-shared ${GLIB2_LIBRARIES})
########### install files ############### ########### install files ###############

View file

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <systemd/sd-event.h> #include <systemd/sd-event.h>
#include <glib.h>
#include "ctl.h" #include "ctl.h"
#include "wfd.h" #include "wfd.h"
#include "wfd-dbus.h" #include "wfd-dbus.h"
@ -416,11 +417,91 @@ void cli_fn_help()
{ {
} }
/*
* see: https://lists.freedesktop.org/archives/systemd-devel/2014-August/022329.html
**/
#define SD_SOURCE(p) ((SDSource *) (p))
typedef struct _SDSource SDSource;
struct _SDSource
{
GSource source;
sd_event *event;
GPollFD pollfd;
};
static gboolean sd_source_prepare(GSource *source, gint *timeout)
{
return sd_event_prepare(SD_SOURCE(source)->event) > 0 ? TRUE : FALSE;
}
static gboolean sd_source_check(GSource *source)
{
return sd_event_wait(SD_SOURCE(source)->event, 0) > 0 ? TRUE : FALSE;
}
static gboolean sd_source_dispatch(GSource *source,
GSourceFunc callback,
gpointer userdata)
{
return sd_event_dispatch(SD_SOURCE(source)->event) >= 0
? G_SOURCE_CONTINUE
: G_SOURCE_REMOVE;
}
static void sd_source_finalize(GSource *source)
{
sd_event_unref(SD_SOURCE(source)->event);
}
static int sd_source_on_exit(sd_event_source *source, void *userdata)
{
g_main_loop_quit(userdata);
sd_event_source_set_enabled(source, false);
sd_event_source_unref(source);
return 0;
}
static int sd_source_attach(GSource *source, GMainLoop *loop)
{
g_source_set_name(source, "sd-event");
g_source_add_poll(source, &SD_SOURCE(source)->pollfd);
g_source_attach(source, g_main_loop_get_context(loop));
return sd_event_add_exit(SD_SOURCE(source)->event,
NULL,
sd_source_on_exit,
loop);
}
GSource * sd_source_new(sd_event *event)
{
static GSourceFuncs funcs = {
sd_source_prepare,
sd_source_check,
sd_source_dispatch,
sd_source_finalize,
};
GSource *s = g_source_new(&funcs, sizeof(SDSource));
if(s) {
SD_SOURCE(s)->event = sd_event_ref(event);
SD_SOURCE(s)->pollfd.fd = sd_event_get_fd(event);
SD_SOURCE(s)->pollfd.events = G_IO_IN | G_IO_HUP;
}
return s;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int r; int r;
sd_event *loop; GMainLoop *loop;
GSource *source;
sd_event *event;
sd_bus *bus; sd_bus *bus;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
@ -429,30 +510,47 @@ int main(int argc, char **argv)
log_max_sev = log_parse_arg(getenv("LOG_LEVEL")); log_max_sev = log_parse_arg(getenv("LOG_LEVEL"));
} }
r = sd_event_default(&loop); loop = g_main_loop_new(NULL, FALSE);
if(0 > r) { if(!loop) {
r = -ENOMEM;
goto end; goto end;
} }
r = sd_event_default(&event);
if(0 > r) {
goto unref_loop;
}
source = sd_source_new(event);
if(!source) {
r = -ENOMEM;
goto unref_event;
}
r = sd_source_attach(source, loop);
if(0 > r) {
goto unref_source;
}
r = sd_bus_default_system(&bus); r = sd_bus_default_system(&bus);
if(0 > r) { if(0 > r) {
log_warning("unabled to connect to system DBus: %s", strerror(errno)); log_warning("unabled to connect to system DBus: %s", strerror(errno));
goto unref_loop; goto unref_source;
} }
r = sd_bus_attach_event(bus, loop, 0); r = sd_bus_attach_event(bus, event, 0);
if(0 > r) { if(0 > r) {
log_warning("unabled to attache DBus event source to loop: %s", log_warning("unabled to attache DBus event source to loop: %s",
strerror(errno)); strerror(errno));
goto unref_bus; goto unref_bus;
} }
r = ctl_wfd_new(&wfd, loop, bus); r = ctl_wfd_new(&wfd, event, bus);
if(0 > r) { if(0 > r) {
goto bus_detach_event;; goto bus_detach_event;;
} }
r = wfd_dbus_new(&wfd_dbus, loop, bus); r = wfd_dbus_new(&wfd_dbus, event, bus);
if(0 > r) { if(0 > r) {
goto free_ctl_wfd; goto free_ctl_wfd;
} }
@ -463,10 +561,7 @@ int main(int argc, char **argv)
goto free_wfd_dbus; goto free_wfd_dbus;
} }
r = sd_event_loop(loop); g_main_loop_run(loop);
if(0 > r) {
log_warning("unabled to keep WFD service running: %s", strerror(errno));
}
free_wfd_dbus: free_wfd_dbus:
wfd_dbus_free(wfd_dbus); wfd_dbus_free(wfd_dbus);
@ -478,9 +573,14 @@ bus_detach_event:
sd_bus_detach_event(bus); sd_bus_detach_event(bus);
unref_bus: unref_bus:
sd_bus_flush_close_unref(bus); sd_bus_flush_close_unref(bus);
unref_source:
g_source_ref(source);
g_source_destroy(source);
unref_event:
sd_event_run(event, 0);
sd_event_unref(event);
unref_loop: unref_loop:
sd_event_run(loop, 0); g_main_loop_unref(loop);
sd_event_unref(loop);
end: end:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
} }