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 <stdlib.h> 23#include <unistd.h> 24#include <stdio.h> 25 26#include <check.h> 27 28#include <pulse/rtclock.h> 29#include <pulse/timeval.h> 30#include <pulse/util.h> 31#include <pulse/thread-mainloop.h> 32 33#include <pulsecore/core-rtclock.h> 34#include <pulsecore/macro.h> 35#include <pulsecore/mutex.h> 36 37static void tcb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *tv, void *userdata) { 38 pa_assert_se(pa_threaded_mainloop_in_thread(userdata)); 39 fprintf(stderr, "TIME EVENT START\n"); 40 pa_threaded_mainloop_signal(userdata, 1); 41 fprintf(stderr, "TIME EVENT END\n"); 42} 43 44static void ocb(pa_threaded_mainloop *m, void *userdata) { 45 pa_threaded_mainloop_lock(m); 46 pa_threaded_mainloop_signal(m, 0); 47 pa_threaded_mainloop_unlock(m); 48} 49 50START_TEST (thread_mainloop_test) { 51 pa_mainloop_api *a; 52 pa_threaded_mainloop *m; 53 struct timeval tv; 54 55 m = pa_threaded_mainloop_new(); 56 fail_unless(m != NULL); 57 a = pa_threaded_mainloop_get_api(m); 58 fail_unless(m != NULL); 59 60 fail_unless(pa_threaded_mainloop_start(m) >= 0); 61 62 pa_threaded_mainloop_lock(m); 63 64 fail_unless(!pa_threaded_mainloop_in_thread(m)); 65 66 a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 5 * PA_USEC_PER_SEC, true), tcb, m); 67 68 fprintf(stderr, "waiting 5s (signal)\n"); 69 pa_threaded_mainloop_wait(m); 70 fprintf(stderr, "wait completed\n"); 71 pa_threaded_mainloop_accept(m); 72 fprintf(stderr, "signal accepted\n"); 73 74 pa_threaded_mainloop_unlock(m); 75 76 fprintf(stderr, "waiting 5s (sleep)\n"); 77 pa_msleep(5000); 78 79 /* Test pa_threaded_mainloop_once_unlocked() */ 80 pa_threaded_mainloop_lock(m); 81 82 fprintf(stderr, "scheduling unlocked callback\n"); 83 pa_threaded_mainloop_once_unlocked(m, ocb, NULL); 84 85 pa_threaded_mainloop_wait(m); 86 fprintf(stderr, "got unlocked callback\n"); 87 88 pa_threaded_mainloop_unlock(m); 89 90 pa_threaded_mainloop_stop(m); 91 92 pa_threaded_mainloop_free(m); 93} 94END_TEST 95 96int main(int argc, char *argv[]) { 97 int failed = 0; 98 Suite *s; 99 TCase *tc; 100 SRunner *sr; 101 102 s = suite_create("Thread MainLoop"); 103 tc = tcase_create("threadmainloop"); 104 tcase_add_test(tc, thread_mainloop_test); 105 /* the default timeout is too small, 106 * set it to a reasonable large one. 107 */ 108 tcase_set_timeout(tc, 60 * 60); 109 suite_add_tcase(s, tc); 110 111 sr = srunner_create(s); 112 srunner_run_all(sr, CK_NORMAL); 113 failed = srunner_ntests_failed(sr); 114 srunner_free(sr); 115 116 return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 117} 118