1 /***
2 This file is part of PulseAudio.
3
4 PulseAudio is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published
6 by the Free Software Foundation; either version 2.1 of the License,
7 or (at your option) any later version.
8
9 PulseAudio is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
16 ***/
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <assert.h>
26 #include <check.h>
27
28 #include <pulse/rtclock.h>
29 #include <pulse/timeval.h>
30
31 #include <pulsecore/core-util.h>
32 #include <pulsecore/core-rtclock.h>
33
34 #ifdef GLIB_MAIN_LOOP
35
36 #include <glib.h>
37 #include <pulse/glib-mainloop.h>
38
39 static GMainLoop* glib_main_loop = NULL;
40
41 #else /* GLIB_MAIN_LOOP */
42 #include <pulse/mainloop.h>
43 #endif /* GLIB_MAIN_LOOP */
44
45 typedef struct mainloop_events {
46 pa_defer_event *de;
47 pa_io_event *ioe;
48 pa_time_event *te;
49 } mainloop_events;
50
iocb(pa_mainloop_api * a,pa_io_event * e,int fd,pa_io_event_flags_t f,void * userdata)51 static void iocb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
52 mainloop_events *me = userdata;
53 unsigned char c;
54 int r;
55
56 pa_assert_se(e == me->ioe);
57
58 r = read(fd, &c, sizeof(c));
59 pa_assert_se(r >= 0);
60
61 if (!r) {
62 fprintf(stderr, "IO EVENT: EOF\n");
63 a->io_free(me->ioe);
64 me->ioe = NULL;
65 return;
66 }
67
68 fprintf(stderr, "IO EVENT: %c\n", c < 32 ? '.' : c);
69 a->defer_enable(me->de, 1);
70 }
71
dcb(pa_mainloop_api * a,pa_defer_event * e,void * userdata)72 static void dcb(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
73 fprintf(stderr, "DEFER EVENT\n");
74 a->defer_enable(e, 0);
75 }
76
tcb(pa_mainloop_api * a,pa_time_event * e,const struct timeval * tv,void * userdata)77 static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) {
78 fprintf(stderr, "TIME EVENT\n");
79
80 #if defined(GLIB_MAIN_LOOP)
81 g_main_loop_quit(glib_main_loop);
82 #else
83 a->quit(a, 0);
84 #endif
85 }
86
START_TEST(mainloop_test)87 START_TEST (mainloop_test) {
88 pa_mainloop_api *a;
89 mainloop_events me;
90 struct timeval tv;
91
92 #ifdef GLIB_MAIN_LOOP
93 pa_glib_mainloop *g;
94
95 glib_main_loop = g_main_loop_new(NULL, FALSE);
96 fail_if(!glib_main_loop);
97
98 g = pa_glib_mainloop_new(NULL);
99 fail_if(!g);
100
101 a = pa_glib_mainloop_get_api(g);
102 fail_if(!a);
103 #else /* GLIB_MAIN_LOOP */
104 pa_mainloop *m;
105
106 m = pa_mainloop_new();
107 fail_if(!m);
108
109 a = pa_mainloop_get_api(m);
110 fail_if(!a);
111 #endif /* GLIB_MAIN_LOOP */
112
113 me.ioe = a->io_new(a, 0, PA_IO_EVENT_INPUT, iocb, &me);
114 fail_if(!me.ioe);
115
116 me.de = a->defer_new(a, dcb, &me);
117 fail_if(!me.de);
118
119 me.te = a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 2 * PA_USEC_PER_SEC, true), tcb, &me);
120
121 #if defined(GLIB_MAIN_LOOP)
122 g_main_loop_run(glib_main_loop);
123 #else
124 pa_mainloop_run(m, NULL);
125 #endif
126
127 if (me.te)
128 a->time_free(me.te);
129 if (me.de)
130 a->defer_free(me.de);
131 if (me.ioe)
132 a->io_free(me.ioe);
133
134 #ifdef GLIB_MAIN_LOOP
135 pa_glib_mainloop_free(g);
136 g_main_loop_unref(glib_main_loop);
137 #else
138 pa_mainloop_free(m);
139 #endif
140 }
141 END_TEST
142
main(int argc,char * argv[])143 int main(int argc, char *argv[]) {
144 int failed = 0;
145 Suite *s;
146 TCase *tc;
147 SRunner *sr;
148
149 s = suite_create("MainLoop");
150 tc = tcase_create("mainloop");
151 tcase_add_test(tc, mainloop_test);
152 suite_add_tcase(s, tc);
153
154 sr = srunner_create(s);
155 srunner_run_all(sr, CK_NORMAL);
156 failed = srunner_ntests_failed(sr);
157 srunner_free(sr);
158
159 return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
160 }
161