qt: playlist: use item title if available
[vlc.git] / src / test / interrupt.c
blob808335575b1c30afa57fab88d725a0f6bde1b689
1 /*****************************************************************************
2 * interrupt.c: Test for interrupt context API
3 *****************************************************************************
4 * Copyright (C) 2015 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #undef NDEBUG
26 #include <assert.h>
27 #include <errno.h>
28 #include <unistd.h>
30 #include <vlc_common.h>
31 #include <vlc_threads.h>
32 #include <vlc_interrupt.h>
33 #include <vlc_network.h>
35 const char vlc_module_name[] = "test_interrupt";
37 static vlc_sem_t sem;
38 static int fds[2];
40 static void interrupt_callback(void *data)
42 vlc_sem_post(data);
45 static void test_context_simple(vlc_interrupt_t *ctx)
47 vlc_interrupt_t *octx;
48 char c;
50 vlc_interrupt_set(ctx);
51 octx = vlc_interrupt_set(NULL);
52 assert(octx == ctx);
53 octx = vlc_interrupt_set(ctx);
54 assert(octx == NULL);
55 octx = vlc_interrupt_set(ctx);
56 assert(octx == ctx);
58 vlc_interrupt_register(interrupt_callback, &sem);
59 vlc_interrupt_raise(ctx);
60 vlc_sem_wait(&sem);
61 vlc_interrupt_unregister();
63 /* BIG FAT WARNING: This is only meant to test the vlc_cond_wait_i11e()
64 * function. This is NOT a good example of how to use the function in
65 * normal code. */
66 vlc_sem_post(&sem);
67 assert(vlc_sem_wait_i11e(&sem) == 0);
69 vlc_interrupt_raise(ctx);
70 assert(vlc_sem_wait_i11e(&sem) == EINTR);
72 vlc_sem_post(&sem);
73 vlc_interrupt_raise(ctx);
74 assert(vlc_sem_wait_i11e(&sem) == EINTR);
75 assert(vlc_sem_wait_i11e(&sem) == 0);
77 vlc_interrupt_raise(ctx);
78 vlc_sem_post(&sem);
79 assert(vlc_sem_wait_i11e(&sem) == EINTR);
80 assert(vlc_sem_wait_i11e(&sem) == 0);
82 assert(vlc_mwait_i11e(1) == 0);
83 vlc_interrupt_raise(ctx);
84 assert(vlc_mwait_i11e(CLOCK_FREQ * 10000000) == EINTR);
86 assert(vlc_poll_i11e(NULL, 0, 1) == 0);
87 vlc_interrupt_raise(ctx);
88 assert(vlc_poll_i11e(NULL, 0, 1000000000) == -1);
89 assert(errno == EINTR);
91 c = 12;
92 assert(vlc_write_i11e(fds[0], &c, 1) == 1);
93 c = 0;
94 assert(vlc_read_i11e(fds[1], &c, 1) == 1 && c == 12);
95 vlc_interrupt_raise(ctx);
96 assert(vlc_read_i11e(fds[1], &c, 1) == -1);
97 assert(errno == EINTR);
99 c = 42;
100 assert(vlc_sendto_i11e(fds[0], &c, 1, 0, NULL, 0) == 1);
101 c = 0;
102 assert(vlc_recvfrom_i11e(fds[1], &c, 1, 0, NULL, 0) == 1 && c == 42);
103 vlc_interrupt_raise(ctx);
104 assert(vlc_recvfrom_i11e(fds[1], &c, 1, 0, NULL, 0) == -1);
105 assert(errno == EINTR);
107 vlc_interrupt_raise(ctx);
108 assert(vlc_accept_i11e(fds[1], NULL, NULL, true) < 0);
110 octx = vlc_interrupt_set(NULL);
111 assert(octx == ctx);
112 octx = vlc_interrupt_set(NULL);
113 assert(octx == NULL);
116 static void *test_thread_simple(void *data)
118 vlc_interrupt_t *ctx = data;
120 vlc_interrupt_set(ctx);
121 assert(vlc_sem_wait_i11e(&sem) == EINTR);
122 assert(vlc_sem_wait_i11e(&sem) == 0);
123 vlc_sem_wait(&sem);
125 test_context_simple(ctx);
126 return NULL;
129 static void *test_thread_cleanup(void *data)
131 vlc_interrupt_t *ctx = data;
133 test_context_simple(ctx);
134 /* Test context clearing on exit */
135 vlc_interrupt_set(ctx);
136 return NULL;
139 static void *test_thread_cancel(void *data)
141 vlc_interrupt_t *ctx = data;
143 int canc = vlc_savecancel();
144 test_context_simple(ctx);
145 vlc_restorecancel(canc);
147 /* Test context clearing on cancellation */
148 vlc_interrupt_set(ctx);
149 for (;;)
150 pause();
152 vlc_assert_unreachable();
155 static void unreachable_callback(void *data)
157 (void) data;
158 abort();
161 int main (void)
163 vlc_interrupt_t *ctx;
164 vlc_thread_t th;
166 alarm(2);
168 ctx = vlc_interrupt_create();
169 assert(ctx != NULL);
170 vlc_interrupt_destroy(ctx);
172 vlc_sem_init(&sem, 0);
173 ctx = vlc_interrupt_create();
174 assert(ctx != NULL);
176 assert(vlc_socketpair(PF_LOCAL, SOCK_STREAM, 0, fds, false) == 0);
178 test_context_simple(ctx);
180 assert(!vlc_clone(&th, test_thread_simple, ctx, VLC_THREAD_PRIORITY_LOW));
181 vlc_interrupt_raise(ctx);
182 vlc_sem_post(&sem);
183 vlc_sem_post(&sem);
184 vlc_join(th, NULL);
186 assert(!vlc_clone(&th, test_thread_cleanup, ctx, VLC_THREAD_PRIORITY_LOW));
187 vlc_join(th, NULL);
189 assert(!vlc_clone(&th, test_thread_cancel, ctx, VLC_THREAD_PRIORITY_LOW));
190 vlc_cancel(th);
191 vlc_join(th, NULL);
193 vlc_interrupt_destroy(ctx);
195 /* Tests without interrupt context */
196 vlc_sem_post(&sem);
197 assert(vlc_sem_wait_i11e(&sem) == 0);
198 assert(vlc_mwait_i11e(1) == 0);
199 assert(vlc_poll_i11e(NULL, 0, 1) == 0);
201 vlc_interrupt_register(unreachable_callback, NULL);
202 vlc_interrupt_unregister();
204 void *data[2];
205 vlc_interrupt_forward_start(ctx, data);
206 assert(vlc_interrupt_forward_stop(data) == 0);
208 vlc_close(fds[1]);
209 vlc_close(fds[0]);
210 return 0;