1/*
2 * lws-minimal-http-server-eventlib-foreign
3 *
4 * Written in 2010-2020 by Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 *
9 * The glib specific code
10 */
11
12#include <libwebsockets.h>
13
14#include <string.h>
15#include <signal.h>
16
17#include <glib-2.0/glib.h>
18#include <glib-unix.h>
19
20#include "private.h"
21
22#if !defined(G_SOURCE_FUNC)
23#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
24#endif
25
26typedef struct lws_glib_tag {
27	GSource			*gs;
28	guint			tag;
29} lws_glib_tag_t;
30
31#define lws_gs_valid(t)		  (t.gs)
32#define lws_gs_destroy(t)	  if (lws_gs_valid(t)) { \
33					g_source_remove(t.tag); \
34					g_source_unref(t.gs); \
35					t.gs = NULL; t.tag = 0; }
36
37static GMainLoop *loop_glib;
38static lws_glib_tag_t timer_outer_glib, sighandler_glib;
39
40static int
41timer_cb_glib(void *p)
42{
43	foreign_timer_service(loop_glib);
44	return 1;
45}
46
47static void
48signal_cb_glib(void *p)
49{
50	signal_cb(SIGINT);
51}
52
53static void
54foreign_event_loop_init_and_run_glib(void)
55{
56	/* we create and start our "foreign loop" */
57
58	loop_glib = g_main_loop_new(NULL, 0);
59
60	sighandler_glib.gs = g_unix_signal_source_new(SIGINT);
61	g_source_set_callback(sighandler_glib.gs, G_SOURCE_FUNC(signal_cb_glib),
62			      NULL, NULL);
63	sighandler_glib.tag = g_source_attach(sighandler_glib.gs,
64					    g_main_loop_get_context(loop_glib));
65
66	timer_outer_glib.gs = g_timeout_source_new(1000);
67	g_source_set_callback(timer_outer_glib.gs, timer_cb_glib, NULL, NULL);
68	timer_outer_glib.tag = g_source_attach(timer_outer_glib.gs,
69					   g_main_loop_get_context(loop_glib));
70
71	g_main_loop_run(loop_glib);
72}
73
74static void
75foreign_event_loop_stop_glib(void)
76{
77	g_main_loop_quit(loop_glib);
78}
79
80static void
81foreign_event_loop_cleanup_glib(void)
82{
83	/* cleanup the foreign loop assets */
84
85	lws_gs_destroy(sighandler_glib);
86	lws_gs_destroy(timer_outer_glib);
87
88	g_main_loop_unref(loop_glib);
89	loop_glib = NULL;
90}
91
92const struct ops ops_glib = {
93	foreign_event_loop_init_and_run_glib,
94	foreign_event_loop_stop_glib,
95	foreign_event_loop_cleanup_glib
96};
97