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 *****************************************************************************/
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";
40 static void interrupt_callback(void *data
)
45 static void test_context_simple(vlc_interrupt_t
*ctx
)
47 vlc_interrupt_t
*octx
;
50 vlc_interrupt_set(ctx
);
51 octx
= vlc_interrupt_set(NULL
);
53 octx
= vlc_interrupt_set(ctx
);
55 octx
= vlc_interrupt_set(ctx
);
58 vlc_interrupt_register(interrupt_callback
, &sem
);
59 vlc_interrupt_raise(ctx
);
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
67 assert(vlc_sem_wait_i11e(&sem
) == 0);
69 vlc_interrupt_raise(ctx
);
70 assert(vlc_sem_wait_i11e(&sem
) == EINTR
);
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
);
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
);
92 assert(vlc_write_i11e(fds
[0], &c
, 1) == 1);
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
);
100 assert(vlc_sendto_i11e(fds
[0], &c
, 1, 0, NULL
, 0) == 1);
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
);
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);
125 test_context_simple(ctx
);
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
);
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
);
152 vlc_assert_unreachable();
155 static void unreachable_callback(void *data
)
163 vlc_interrupt_t
*ctx
;
168 ctx
= vlc_interrupt_create();
170 vlc_interrupt_destroy(ctx
);
172 vlc_sem_init(&sem
, 0);
173 ctx
= vlc_interrupt_create();
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
);
186 assert(!vlc_clone(&th
, test_thread_cleanup
, ctx
, VLC_THREAD_PRIORITY_LOW
));
189 assert(!vlc_clone(&th
, test_thread_cancel
, ctx
, VLC_THREAD_PRIORITY_LOW
));
193 vlc_interrupt_destroy(ctx
);
195 /* Tests without interrupt context */
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();
205 vlc_interrupt_forward_start(ctx
, data
);
206 assert(vlc_interrupt_forward_stop(data
) == 0);