153a5a1b3Sopenharmony_ci/***
253a5a1b3Sopenharmony_ci  This file is part of PulseAudio.
353a5a1b3Sopenharmony_ci
453a5a1b3Sopenharmony_ci  PulseAudio is free software; you can redistribute it and/or modify
553a5a1b3Sopenharmony_ci  it under the terms of the GNU Lesser General Public License as published
653a5a1b3Sopenharmony_ci  by the Free Software Foundation; either version 2.1 of the License,
753a5a1b3Sopenharmony_ci  or (at your option) any later version.
853a5a1b3Sopenharmony_ci
953a5a1b3Sopenharmony_ci  PulseAudio is distributed in the hope that it will be useful, but
1053a5a1b3Sopenharmony_ci  WITHOUT ANY WARRANTY; without even the implied warranty of
1153a5a1b3Sopenharmony_ci  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1253a5a1b3Sopenharmony_ci  General Public License for more details.
1353a5a1b3Sopenharmony_ci
1453a5a1b3Sopenharmony_ci  You should have received a copy of the GNU Lesser General Public License
1553a5a1b3Sopenharmony_ci  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
1653a5a1b3Sopenharmony_ci***/
1753a5a1b3Sopenharmony_ci
1853a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H
1953a5a1b3Sopenharmony_ci#include <config.h>
2053a5a1b3Sopenharmony_ci#endif
2153a5a1b3Sopenharmony_ci
2253a5a1b3Sopenharmony_ci#include <stdio.h>
2353a5a1b3Sopenharmony_ci#include <unistd.h>
2453a5a1b3Sopenharmony_ci#include <sys/time.h>
2553a5a1b3Sopenharmony_ci#include <assert.h>
2653a5a1b3Sopenharmony_ci#include <check.h>
2753a5a1b3Sopenharmony_ci
2853a5a1b3Sopenharmony_ci#include <pulse/rtclock.h>
2953a5a1b3Sopenharmony_ci#include <pulse/timeval.h>
3053a5a1b3Sopenharmony_ci
3153a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h>
3253a5a1b3Sopenharmony_ci#include <pulsecore/core-rtclock.h>
3353a5a1b3Sopenharmony_ci
3453a5a1b3Sopenharmony_ci#ifdef GLIB_MAIN_LOOP
3553a5a1b3Sopenharmony_ci
3653a5a1b3Sopenharmony_ci#include <glib.h>
3753a5a1b3Sopenharmony_ci#include <pulse/glib-mainloop.h>
3853a5a1b3Sopenharmony_ci
3953a5a1b3Sopenharmony_cistatic GMainLoop* glib_main_loop = NULL;
4053a5a1b3Sopenharmony_ci
4153a5a1b3Sopenharmony_ci#else /* GLIB_MAIN_LOOP */
4253a5a1b3Sopenharmony_ci#include <pulse/mainloop.h>
4353a5a1b3Sopenharmony_ci#endif /* GLIB_MAIN_LOOP */
4453a5a1b3Sopenharmony_ci
4553a5a1b3Sopenharmony_citypedef struct mainloop_events {
4653a5a1b3Sopenharmony_ci    pa_defer_event *de;
4753a5a1b3Sopenharmony_ci    pa_io_event *ioe;
4853a5a1b3Sopenharmony_ci    pa_time_event *te;
4953a5a1b3Sopenharmony_ci} mainloop_events;
5053a5a1b3Sopenharmony_ci
5153a5a1b3Sopenharmony_cistatic void iocb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
5253a5a1b3Sopenharmony_ci    mainloop_events *me = userdata;
5353a5a1b3Sopenharmony_ci    unsigned char c;
5453a5a1b3Sopenharmony_ci    int r;
5553a5a1b3Sopenharmony_ci
5653a5a1b3Sopenharmony_ci    pa_assert_se(e == me->ioe);
5753a5a1b3Sopenharmony_ci
5853a5a1b3Sopenharmony_ci    r = read(fd, &c, sizeof(c));
5953a5a1b3Sopenharmony_ci    pa_assert_se(r >= 0);
6053a5a1b3Sopenharmony_ci
6153a5a1b3Sopenharmony_ci    if (!r) {
6253a5a1b3Sopenharmony_ci        fprintf(stderr, "IO EVENT: EOF\n");
6353a5a1b3Sopenharmony_ci        a->io_free(me->ioe);
6453a5a1b3Sopenharmony_ci        me->ioe = NULL;
6553a5a1b3Sopenharmony_ci        return;
6653a5a1b3Sopenharmony_ci    }
6753a5a1b3Sopenharmony_ci
6853a5a1b3Sopenharmony_ci    fprintf(stderr, "IO EVENT: %c\n", c < 32 ? '.' : c);
6953a5a1b3Sopenharmony_ci    a->defer_enable(me->de, 1);
7053a5a1b3Sopenharmony_ci}
7153a5a1b3Sopenharmony_ci
7253a5a1b3Sopenharmony_cistatic void dcb(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
7353a5a1b3Sopenharmony_ci    fprintf(stderr, "DEFER EVENT\n");
7453a5a1b3Sopenharmony_ci    a->defer_enable(e, 0);
7553a5a1b3Sopenharmony_ci}
7653a5a1b3Sopenharmony_ci
7753a5a1b3Sopenharmony_cistatic void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) {
7853a5a1b3Sopenharmony_ci    fprintf(stderr, "TIME EVENT\n");
7953a5a1b3Sopenharmony_ci
8053a5a1b3Sopenharmony_ci#if defined(GLIB_MAIN_LOOP)
8153a5a1b3Sopenharmony_ci    g_main_loop_quit(glib_main_loop);
8253a5a1b3Sopenharmony_ci#else
8353a5a1b3Sopenharmony_ci    a->quit(a, 0);
8453a5a1b3Sopenharmony_ci#endif
8553a5a1b3Sopenharmony_ci}
8653a5a1b3Sopenharmony_ci
8753a5a1b3Sopenharmony_ciSTART_TEST (mainloop_test) {
8853a5a1b3Sopenharmony_ci    pa_mainloop_api *a;
8953a5a1b3Sopenharmony_ci    mainloop_events me;
9053a5a1b3Sopenharmony_ci    struct timeval tv;
9153a5a1b3Sopenharmony_ci
9253a5a1b3Sopenharmony_ci#ifdef GLIB_MAIN_LOOP
9353a5a1b3Sopenharmony_ci    pa_glib_mainloop *g;
9453a5a1b3Sopenharmony_ci
9553a5a1b3Sopenharmony_ci    glib_main_loop = g_main_loop_new(NULL, FALSE);
9653a5a1b3Sopenharmony_ci    fail_if(!glib_main_loop);
9753a5a1b3Sopenharmony_ci
9853a5a1b3Sopenharmony_ci    g = pa_glib_mainloop_new(NULL);
9953a5a1b3Sopenharmony_ci    fail_if(!g);
10053a5a1b3Sopenharmony_ci
10153a5a1b3Sopenharmony_ci    a = pa_glib_mainloop_get_api(g);
10253a5a1b3Sopenharmony_ci    fail_if(!a);
10353a5a1b3Sopenharmony_ci#else /* GLIB_MAIN_LOOP */
10453a5a1b3Sopenharmony_ci    pa_mainloop *m;
10553a5a1b3Sopenharmony_ci
10653a5a1b3Sopenharmony_ci    m = pa_mainloop_new();
10753a5a1b3Sopenharmony_ci    fail_if(!m);
10853a5a1b3Sopenharmony_ci
10953a5a1b3Sopenharmony_ci    a = pa_mainloop_get_api(m);
11053a5a1b3Sopenharmony_ci    fail_if(!a);
11153a5a1b3Sopenharmony_ci#endif /* GLIB_MAIN_LOOP */
11253a5a1b3Sopenharmony_ci
11353a5a1b3Sopenharmony_ci    me.ioe = a->io_new(a, 0, PA_IO_EVENT_INPUT, iocb, &me);
11453a5a1b3Sopenharmony_ci    fail_if(!me.ioe);
11553a5a1b3Sopenharmony_ci
11653a5a1b3Sopenharmony_ci    me.de = a->defer_new(a, dcb, &me);
11753a5a1b3Sopenharmony_ci    fail_if(!me.de);
11853a5a1b3Sopenharmony_ci
11953a5a1b3Sopenharmony_ci    me.te = a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 2 * PA_USEC_PER_SEC, true), tcb, &me);
12053a5a1b3Sopenharmony_ci
12153a5a1b3Sopenharmony_ci#if defined(GLIB_MAIN_LOOP)
12253a5a1b3Sopenharmony_ci    g_main_loop_run(glib_main_loop);
12353a5a1b3Sopenharmony_ci#else
12453a5a1b3Sopenharmony_ci    pa_mainloop_run(m, NULL);
12553a5a1b3Sopenharmony_ci#endif
12653a5a1b3Sopenharmony_ci
12753a5a1b3Sopenharmony_ci    if (me.te)
12853a5a1b3Sopenharmony_ci        a->time_free(me.te);
12953a5a1b3Sopenharmony_ci    if (me.de)
13053a5a1b3Sopenharmony_ci        a->defer_free(me.de);
13153a5a1b3Sopenharmony_ci    if (me.ioe)
13253a5a1b3Sopenharmony_ci        a->io_free(me.ioe);
13353a5a1b3Sopenharmony_ci
13453a5a1b3Sopenharmony_ci#ifdef GLIB_MAIN_LOOP
13553a5a1b3Sopenharmony_ci    pa_glib_mainloop_free(g);
13653a5a1b3Sopenharmony_ci    g_main_loop_unref(glib_main_loop);
13753a5a1b3Sopenharmony_ci#else
13853a5a1b3Sopenharmony_ci    pa_mainloop_free(m);
13953a5a1b3Sopenharmony_ci#endif
14053a5a1b3Sopenharmony_ci}
14153a5a1b3Sopenharmony_ciEND_TEST
14253a5a1b3Sopenharmony_ci
14353a5a1b3Sopenharmony_ciint main(int argc, char *argv[]) {
14453a5a1b3Sopenharmony_ci    int failed = 0;
14553a5a1b3Sopenharmony_ci    Suite *s;
14653a5a1b3Sopenharmony_ci    TCase *tc;
14753a5a1b3Sopenharmony_ci    SRunner *sr;
14853a5a1b3Sopenharmony_ci
14953a5a1b3Sopenharmony_ci    s = suite_create("MainLoop");
15053a5a1b3Sopenharmony_ci    tc = tcase_create("mainloop");
15153a5a1b3Sopenharmony_ci    tcase_add_test(tc, mainloop_test);
15253a5a1b3Sopenharmony_ci    suite_add_tcase(s, tc);
15353a5a1b3Sopenharmony_ci
15453a5a1b3Sopenharmony_ci    sr = srunner_create(s);
15553a5a1b3Sopenharmony_ci    srunner_run_all(sr, CK_NORMAL);
15653a5a1b3Sopenharmony_ci    failed = srunner_ntests_failed(sr);
15753a5a1b3Sopenharmony_ci    srunner_free(sr);
15853a5a1b3Sopenharmony_ci
15953a5a1b3Sopenharmony_ci    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
16053a5a1b3Sopenharmony_ci}
161