1c43e99fdSEd Maste /*
2c43e99fdSEd Maste  * Copyright (c) 2013 Niels Provos and Nick Mathewson
3c43e99fdSEd Maste  *
4c43e99fdSEd Maste  * Redistribution and use in source and binary forms, with or without
5c43e99fdSEd Maste  * modification, are permitted provided that the following conditions
6c43e99fdSEd Maste  * are met:
7c43e99fdSEd Maste  * 1. Redistributions of source code must retain the above copyright
8c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer.
9c43e99fdSEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
10c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer in the
11c43e99fdSEd Maste  *    documentation and/or other materials provided with the distribution.
12c43e99fdSEd Maste  * 3. The name of the author may not be used to endorse or promote products
13c43e99fdSEd Maste  *    derived from this software without specific prior written permission.
14c43e99fdSEd Maste  *
15c43e99fdSEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16c43e99fdSEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17c43e99fdSEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18c43e99fdSEd Maste  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19c43e99fdSEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20c43e99fdSEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21c43e99fdSEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22c43e99fdSEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23c43e99fdSEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24c43e99fdSEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25c43e99fdSEd Maste  */
26c43e99fdSEd Maste 
27c43e99fdSEd Maste #include "event2/event-config.h"
28c43e99fdSEd Maste #include "evconfig-private.h"
29c43e99fdSEd Maste #include "tinytest.h"
30c43e99fdSEd Maste #include "tinytest_macros.h"
31c43e99fdSEd Maste #include <stdlib.h>
32c43e99fdSEd Maste 
33c43e99fdSEd Maste #include "event2/event.h"
34c43e99fdSEd Maste #include "event2/util.h"
35c43e99fdSEd Maste #include "event-internal.h"
36c43e99fdSEd Maste #include "defer-internal.h"
37c43e99fdSEd Maste 
38c43e99fdSEd Maste #include "regress.h"
39c43e99fdSEd Maste #include "regress_thread.h"
40c43e99fdSEd Maste 
41c43e99fdSEd Maste static void
timer_callback(evutil_socket_t fd,short what,void * arg)42c43e99fdSEd Maste timer_callback(evutil_socket_t fd, short what, void *arg)
43c43e99fdSEd Maste {
44c43e99fdSEd Maste 	int *int_arg = arg;
45c43e99fdSEd Maste 	*int_arg += 1;
46c43e99fdSEd Maste 	(void)fd;
47c43e99fdSEd Maste 	(void)what;
48c43e99fdSEd Maste }
49c43e99fdSEd Maste static void
simple_callback(struct event_callback * evcb,void * arg)50c43e99fdSEd Maste simple_callback(struct event_callback *evcb, void *arg)
51c43e99fdSEd Maste {
52c43e99fdSEd Maste 	int *int_arg = arg;
53c43e99fdSEd Maste         *int_arg += 1;
54c43e99fdSEd Maste 	(void)evcb;
55c43e99fdSEd Maste }
56c43e99fdSEd Maste static void
event_finalize_callback_1(struct event * ev,void * arg)57c43e99fdSEd Maste event_finalize_callback_1(struct event *ev, void *arg)
58c43e99fdSEd Maste {
59c43e99fdSEd Maste 	int *int_arg = arg;
60c43e99fdSEd Maste         *int_arg += 100;
61c43e99fdSEd Maste 	(void)ev;
62c43e99fdSEd Maste }
63c43e99fdSEd Maste static void
callback_finalize_callback_1(struct event_callback * evcb,void * arg)64c43e99fdSEd Maste callback_finalize_callback_1(struct event_callback *evcb, void *arg)
65c43e99fdSEd Maste {
66c43e99fdSEd Maste 	int *int_arg = arg;
67c43e99fdSEd Maste         *int_arg += 100;
68c43e99fdSEd Maste 	(void)evcb;
69c43e99fdSEd Maste }
70c43e99fdSEd Maste 
71c43e99fdSEd Maste 
72c43e99fdSEd Maste static void
test_fin_cb_invoked(void * arg)73c43e99fdSEd Maste test_fin_cb_invoked(void *arg)
74c43e99fdSEd Maste {
75c43e99fdSEd Maste 	struct basic_test_data *data = arg;
76c43e99fdSEd Maste 	struct event_base *base = data->base;
77c43e99fdSEd Maste 
78c43e99fdSEd Maste 	struct event *ev;
79c43e99fdSEd Maste 	struct event ev2;
80c43e99fdSEd Maste 	struct event_callback evcb;
81c43e99fdSEd Maste 	int cb_called = 0;
82c43e99fdSEd Maste 	int ev_called = 0;
83c43e99fdSEd Maste 
84c43e99fdSEd Maste 	const struct timeval ten_sec = {10,0};
85c43e99fdSEd Maste 
86c43e99fdSEd Maste 	event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called);
87c43e99fdSEd Maste 	ev = evtimer_new(base, timer_callback, &ev_called);
88c43e99fdSEd Maste 	/* Just finalize them; don't bother adding. */
89c43e99fdSEd Maste 	event_free_finalize(0, ev, event_finalize_callback_1);
90c43e99fdSEd Maste 	event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1);
91c43e99fdSEd Maste 
92c43e99fdSEd Maste 	event_base_dispatch(base);
93c43e99fdSEd Maste 
94c43e99fdSEd Maste 	tt_int_op(cb_called, ==, 100);
95c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 100);
96c43e99fdSEd Maste 
97c43e99fdSEd Maste 	ev_called = cb_called = 0;
98c43e99fdSEd Maste 	event_base_assert_ok_(base);
99c43e99fdSEd Maste 
100c43e99fdSEd Maste 	/* Now try it when they're active. (actually, don't finalize: make
101c43e99fdSEd Maste 	 * sure activation can happen! */
102c43e99fdSEd Maste 	ev = evtimer_new(base, timer_callback, &ev_called);
103c43e99fdSEd Maste 	event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called);
104c43e99fdSEd Maste 
105c43e99fdSEd Maste 	event_active(ev, EV_TIMEOUT, 1);
106c43e99fdSEd Maste 	event_callback_activate_(base, &evcb);
107c43e99fdSEd Maste 
108c43e99fdSEd Maste 	event_base_dispatch(base);
109c43e99fdSEd Maste 	tt_int_op(cb_called, ==, 1);
110c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 1);
111c43e99fdSEd Maste 
112c43e99fdSEd Maste 	ev_called = cb_called = 0;
113c43e99fdSEd Maste 	event_base_assert_ok_(base);
114c43e99fdSEd Maste 
115c43e99fdSEd Maste 	/* Great, it worked. Now activate and finalize and make sure only
116c43e99fdSEd Maste 	 * finalizing happens. */
117c43e99fdSEd Maste 	event_active(ev, EV_TIMEOUT, 1);
118c43e99fdSEd Maste 	event_callback_activate_(base, &evcb);
119c43e99fdSEd Maste 	event_free_finalize(0, ev, event_finalize_callback_1);
120c43e99fdSEd Maste 	event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1);
121c43e99fdSEd Maste 
122c43e99fdSEd Maste 	event_base_dispatch(base);
123c43e99fdSEd Maste 	tt_int_op(cb_called, ==, 100);
124c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 100);
125c43e99fdSEd Maste 
126c43e99fdSEd Maste 	ev_called = 0;
127c43e99fdSEd Maste 
128c43e99fdSEd Maste 	event_base_assert_ok_(base);
129c43e99fdSEd Maste 
130c43e99fdSEd Maste 	/* Okay, now add but don't have it become active, and make sure *that*
131c43e99fdSEd Maste 	 * works. */
132c43e99fdSEd Maste 	ev = evtimer_new(base, timer_callback, &ev_called);
133c43e99fdSEd Maste 	event_add(ev, &ten_sec);
134c43e99fdSEd Maste 	event_free_finalize(0, ev, event_finalize_callback_1);
135c43e99fdSEd Maste 
136c43e99fdSEd Maste 	event_base_dispatch(base);
137c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 100);
138c43e99fdSEd Maste 
139c43e99fdSEd Maste 	ev_called = 0;
140c43e99fdSEd Maste 	event_base_assert_ok_(base);
141c43e99fdSEd Maste 
142c43e99fdSEd Maste 	/* Now try adding and deleting after finalizing. */
143c43e99fdSEd Maste 	ev = evtimer_new(base, timer_callback, &ev_called);
144c43e99fdSEd Maste 	evtimer_assign(&ev2, base, timer_callback, &ev_called);
145c43e99fdSEd Maste 	event_add(ev, &ten_sec);
146c43e99fdSEd Maste 	event_free_finalize(0, ev, event_finalize_callback_1);
147c43e99fdSEd Maste 	event_finalize(0, &ev2, event_finalize_callback_1);
148c43e99fdSEd Maste 
149c43e99fdSEd Maste 	event_add(&ev2, &ten_sec);
150c43e99fdSEd Maste 	event_del(ev);
151c43e99fdSEd Maste 	event_active(&ev2, EV_TIMEOUT, 1);
152c43e99fdSEd Maste 
153c43e99fdSEd Maste 	event_base_dispatch(base);
154c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 200);
155c43e99fdSEd Maste 
156c43e99fdSEd Maste 	event_base_assert_ok_(base);
157c43e99fdSEd Maste 
158c43e99fdSEd Maste end:
159c43e99fdSEd Maste 	;
160c43e99fdSEd Maste }
161c43e99fdSEd Maste 
162c43e99fdSEd Maste #ifndef EVENT__DISABLE_MM_REPLACEMENT
163c43e99fdSEd Maste static void *
tfff_malloc(size_t n)164c43e99fdSEd Maste tfff_malloc(size_t n)
165c43e99fdSEd Maste {
166c43e99fdSEd Maste 	return malloc(n);
167c43e99fdSEd Maste }
168c43e99fdSEd Maste static void *tfff_p1=NULL, *tfff_p2=NULL;
169c43e99fdSEd Maste static int tfff_p1_freed=0, tfff_p2_freed=0;
170c43e99fdSEd Maste static void
tfff_free(void * p)171c43e99fdSEd Maste tfff_free(void *p)
172c43e99fdSEd Maste {
173c43e99fdSEd Maste 	if (! p)
174c43e99fdSEd Maste 		return;
175c43e99fdSEd Maste 	if (p == tfff_p1)
176c43e99fdSEd Maste 		++tfff_p1_freed;
177c43e99fdSEd Maste 	if (p == tfff_p2)
178c43e99fdSEd Maste 		++tfff_p2_freed;
179c43e99fdSEd Maste 	free(p);
180c43e99fdSEd Maste }
181c43e99fdSEd Maste static void *
tfff_realloc(void * p,size_t sz)182c43e99fdSEd Maste tfff_realloc(void *p, size_t sz)
183c43e99fdSEd Maste {
184c43e99fdSEd Maste 	return realloc(p,sz);
185c43e99fdSEd Maste }
186c43e99fdSEd Maste #endif
187c43e99fdSEd Maste 
188c43e99fdSEd Maste static void
test_fin_free_finalize(void * arg)189c43e99fdSEd Maste test_fin_free_finalize(void *arg)
190c43e99fdSEd Maste {
191c43e99fdSEd Maste #ifdef EVENT__DISABLE_MM_REPLACEMENT
192c43e99fdSEd Maste 	tinytest_set_test_skipped_();
193c43e99fdSEd Maste #else
194c43e99fdSEd Maste 	struct event_base *base = NULL;
195c43e99fdSEd Maste 	struct event *ev, *ev2;
196c43e99fdSEd Maste 	int ev_called = 0;
197c43e99fdSEd Maste 	int ev2_called = 0;
198c43e99fdSEd Maste 
199c43e99fdSEd Maste 	(void)arg;
200c43e99fdSEd Maste 
201c43e99fdSEd Maste 	event_set_mem_functions(tfff_malloc, tfff_realloc, tfff_free);
202c43e99fdSEd Maste 
203c43e99fdSEd Maste 	base = event_base_new();
204c43e99fdSEd Maste 	tt_assert(base);
205c43e99fdSEd Maste 
206c43e99fdSEd Maste 	ev = evtimer_new(base, timer_callback, &ev_called);
207c43e99fdSEd Maste 	ev2 = evtimer_new(base, timer_callback, &ev2_called);
208c43e99fdSEd Maste 	tfff_p1 = ev;
209c43e99fdSEd Maste 	tfff_p2 = ev2;
210c43e99fdSEd Maste 	event_free_finalize(0, ev, event_finalize_callback_1);
211c43e99fdSEd Maste 	event_finalize(0, ev2, event_finalize_callback_1);
212c43e99fdSEd Maste 
213c43e99fdSEd Maste 	event_base_dispatch(base);
214c43e99fdSEd Maste 
215c43e99fdSEd Maste 	tt_int_op(ev_called, ==, 100);
216c43e99fdSEd Maste 	tt_int_op(ev2_called, ==, 100);
217c43e99fdSEd Maste 
218c43e99fdSEd Maste 	event_base_assert_ok_(base);
219c43e99fdSEd Maste 	tt_int_op(tfff_p1_freed, ==, 1);
220c43e99fdSEd Maste 	tt_int_op(tfff_p2_freed, ==, 0);
221c43e99fdSEd Maste 
222c43e99fdSEd Maste 	event_free(ev2);
223c43e99fdSEd Maste 
224c43e99fdSEd Maste end:
225c43e99fdSEd Maste 	if (base)
226c43e99fdSEd Maste 		event_base_free(base);
227c43e99fdSEd Maste #endif
228c43e99fdSEd Maste }
229c43e99fdSEd Maste 
230c43e99fdSEd Maste /* For test_fin_within_cb */
231c43e99fdSEd Maste struct event_and_count {
232c43e99fdSEd Maste 	struct event *ev;
233c43e99fdSEd Maste 	struct event *ev2;
234c43e99fdSEd Maste 	int count;
235c43e99fdSEd Maste };
236c43e99fdSEd Maste static void
event_finalize_callback_2(struct event * ev,void * arg)237c43e99fdSEd Maste event_finalize_callback_2(struct event *ev, void *arg)
238c43e99fdSEd Maste {
239c43e99fdSEd Maste 	struct event_and_count *evc = arg;
240c43e99fdSEd Maste 	evc->count += 100;
241c43e99fdSEd Maste 	event_free(ev);
242c43e99fdSEd Maste }
243c43e99fdSEd Maste static void
timer_callback_2(evutil_socket_t fd,short what,void * arg)244c43e99fdSEd Maste timer_callback_2(evutil_socket_t fd, short what, void *arg)
245c43e99fdSEd Maste {
246c43e99fdSEd Maste 	struct event_and_count *evc = arg;
247c43e99fdSEd Maste 	event_finalize(0, evc->ev, event_finalize_callback_2);
248c43e99fdSEd Maste 	event_finalize(0, evc->ev2, event_finalize_callback_2);
249c43e99fdSEd Maste 	++ evc->count;
250c43e99fdSEd Maste 	(void)fd;
251c43e99fdSEd Maste 	(void)what;
252c43e99fdSEd Maste }
253c43e99fdSEd Maste 
254c43e99fdSEd Maste static void
test_fin_within_cb(void * arg)255c43e99fdSEd Maste test_fin_within_cb(void *arg)
256c43e99fdSEd Maste {
257c43e99fdSEd Maste 	struct basic_test_data *data = arg;
258c43e99fdSEd Maste 	struct event_base *base = data->base;
259c43e99fdSEd Maste 
260c43e99fdSEd Maste 	struct event_and_count evc1, evc2;
261c43e99fdSEd Maste 	evc1.count = evc2.count = 0;
262c43e99fdSEd Maste 	evc2.ev2 = evc1.ev = evtimer_new(base, timer_callback_2, &evc1);
263c43e99fdSEd Maste 	evc1.ev2 = evc2.ev = evtimer_new(base, timer_callback_2, &evc2);
264c43e99fdSEd Maste 
265c43e99fdSEd Maste 	/* Activate both.  The first one will have its callback run, which
266c43e99fdSEd Maste 	 * will finalize both of them, preventing the second one's callback
267c43e99fdSEd Maste 	 * from running. */
268c43e99fdSEd Maste 	event_active(evc1.ev, EV_TIMEOUT, 1);
269c43e99fdSEd Maste 	event_active(evc2.ev, EV_TIMEOUT, 1);
270c43e99fdSEd Maste 
271c43e99fdSEd Maste 	event_base_dispatch(base);
272c43e99fdSEd Maste 	tt_int_op(evc1.count, ==, 101);
273c43e99fdSEd Maste 	tt_int_op(evc2.count, ==, 100);
274c43e99fdSEd Maste 
275c43e99fdSEd Maste 	event_base_assert_ok_(base);
276c43e99fdSEd Maste 	/* Now try with EV_PERSIST events. */
277c43e99fdSEd Maste 	evc1.count = evc2.count = 0;
278c43e99fdSEd Maste 	evc2.ev2 = evc1.ev = event_new(base, -1, EV_PERSIST, timer_callback_2, &evc1);
279c43e99fdSEd Maste 	evc1.ev2 = evc2.ev = event_new(base, -1, EV_PERSIST, timer_callback_2, &evc2);
280c43e99fdSEd Maste 
281c43e99fdSEd Maste 	event_active(evc1.ev, EV_TIMEOUT, 1);
282c43e99fdSEd Maste 	event_active(evc2.ev, EV_TIMEOUT, 1);
283c43e99fdSEd Maste 
284c43e99fdSEd Maste 	event_base_dispatch(base);
285c43e99fdSEd Maste 	tt_int_op(evc1.count, ==, 101);
286c43e99fdSEd Maste 	tt_int_op(evc2.count, ==, 100);
287c43e99fdSEd Maste 
288c43e99fdSEd Maste 	event_base_assert_ok_(base);
289c43e99fdSEd Maste end:
290c43e99fdSEd Maste 	;
291c43e99fdSEd Maste }
292c43e99fdSEd Maste 
293*b50261e2SCy Schubert static void
event_finalize_callback_free(struct event * ev,void * arg)294*b50261e2SCy Schubert event_finalize_callback_free(struct event *ev, void *arg)
295*b50261e2SCy Schubert {
296*b50261e2SCy Schubert 	struct event_base *base = arg;
297*b50261e2SCy Schubert 	int err;
298*b50261e2SCy Schubert 	if (base) {
299*b50261e2SCy Schubert 		err = event_assign(ev, base, -1, EV_TIMEOUT, NULL, NULL);
300*b50261e2SCy Schubert 		tt_int_op(err, ==, 0);
301*b50261e2SCy Schubert 		test_ok += 1;
302*b50261e2SCy Schubert 	} else {
303*b50261e2SCy Schubert 		free(ev);
304*b50261e2SCy Schubert 		test_ok += 1;
305*b50261e2SCy Schubert 	}
306*b50261e2SCy Schubert 
307*b50261e2SCy Schubert end:
308*b50261e2SCy Schubert 	;
309*b50261e2SCy Schubert }
310*b50261e2SCy Schubert static void
test_fin_debug_use_after_free(void * arg)311*b50261e2SCy Schubert test_fin_debug_use_after_free(void *arg)
312*b50261e2SCy Schubert {
313*b50261e2SCy Schubert 	struct basic_test_data *data = arg;
314*b50261e2SCy Schubert 	struct event_base *base = data->base;
315*b50261e2SCy Schubert 	struct event *ev;
316*b50261e2SCy Schubert 
317*b50261e2SCy Schubert 	tt_ptr_op(ev = event_new(base, -1, EV_TIMEOUT, NULL, base), !=, NULL);
318*b50261e2SCy Schubert 	tt_int_op(event_add(ev, NULL), ==, 0);
319*b50261e2SCy Schubert 	tt_int_op(event_finalize(0, ev, event_finalize_callback_free), ==, 0);
320*b50261e2SCy Schubert 
321*b50261e2SCy Schubert 	// Dispatch base to trigger callbacks
322*b50261e2SCy Schubert 	event_base_dispatch(base);
323*b50261e2SCy Schubert 	event_base_assert_ok_(base);
324*b50261e2SCy Schubert 	tt_int_op(test_ok, ==, 1);
325*b50261e2SCy Schubert 
326*b50261e2SCy Schubert 	// Now add again, since we did event_assign in event_finalize_callback_free
327*b50261e2SCy Schubert 	// This used to fail in event_debug_assert_is_setup_
328*b50261e2SCy Schubert 	tt_int_op(event_add(ev, NULL), ==, 0);
329*b50261e2SCy Schubert 
330*b50261e2SCy Schubert 	// Finalize and dispatch again
331*b50261e2SCy Schubert 	tt_int_op(event_finalize(0, ev, event_finalize_callback_free), ==, 0);
332*b50261e2SCy Schubert 	event_base_dispatch(base);
333*b50261e2SCy Schubert 	event_base_assert_ok_(base);
334*b50261e2SCy Schubert 	tt_int_op(test_ok, ==, 2);
335*b50261e2SCy Schubert 
336*b50261e2SCy Schubert end:
337*b50261e2SCy Schubert 	;
338*b50261e2SCy Schubert }
339*b50261e2SCy Schubert 
340c43e99fdSEd Maste #if 0
341c43e99fdSEd Maste static void
342c43e99fdSEd Maste timer_callback_3(evutil_socket_t *fd, short what, void *arg)
343c43e99fdSEd Maste {
344c43e99fdSEd Maste 	(void)fd;
345c43e99fdSEd Maste 	(void)what;
346c43e99fdSEd Maste 
347c43e99fdSEd Maste }
348c43e99fdSEd Maste static void
349c43e99fdSEd Maste test_fin_many(void *arg)
350c43e99fdSEd Maste {
351c43e99fdSEd Maste 	struct basic_test_data *data = arg;
352c43e99fdSEd Maste 	struct event_base *base = data->base;
353c43e99fdSEd Maste 
354c43e99fdSEd Maste 	struct event *ev1, *ev2;
355c43e99fdSEd Maste 	struct event_callback evcb1, evcb2;
356c43e99fdSEd Maste 	int ev1_count = 0, ev2_count = 0;
357c43e99fdSEd Maste 	int evcb1_count = 0, evcb2_count = 0;
358c43e99fdSEd Maste 	struct event_callback *array[4];
359c43e99fdSEd Maste 
360c43e99fdSEd Maste 	int n;
361c43e99fdSEd Maste 
362c43e99fdSEd Maste 	/* First attempt: call finalize_many with no events running */
363c43e99fdSEd Maste 	ev1 = evtimer_new(base, timer_callback, &ev1_count);
364c43e99fdSEd Maste 	ev1 = evtimer_new(base, timer_callback, &ev2_count);
365c43e99fdSEd Maste 	event_deferred_cb_init_(&evcb1, 0, simple_callback, &evcb1_called);
366c43e99fdSEd Maste 	event_deferred_cb_init_(&evcb2, 0, simple_callback, &evcb2_called);
367c43e99fdSEd Maste 	array[0] = &ev1->ev_evcallback;
368c43e99fdSEd Maste 	array[1] = &ev2->ev_evcallback;
369c43e99fdSEd Maste 	array[2] = &evcb1;
370c43e99fdSEd Maste 	array[3] = &evcb2;
371c43e99fdSEd Maste 
372c43e99fdSEd Maste 
373c43e99fdSEd Maste 
374c43e99fdSEd Maste 	n = event_callback_finalize_many(base, 4, array,
375c43e99fdSEd Maste 	    callback_finalize_callback_1);
376c43e99fdSEd Maste 
377c43e99fdSEd Maste }
378c43e99fdSEd Maste #endif
379c43e99fdSEd Maste 
380c43e99fdSEd Maste 
381c43e99fdSEd Maste #define TEST(name, flags)					\
382c43e99fdSEd Maste 	{ #name, test_fin_##name, (flags), &basic_setup, NULL }
383c43e99fdSEd Maste 
384c43e99fdSEd Maste struct testcase_t finalize_testcases[] = {
385c43e99fdSEd Maste 
386c43e99fdSEd Maste 	TEST(cb_invoked, TT_FORK|TT_NEED_BASE),
387c43e99fdSEd Maste 	TEST(free_finalize, TT_FORK),
388c43e99fdSEd Maste 	TEST(within_cb, TT_FORK|TT_NEED_BASE),
389*b50261e2SCy Schubert 	TEST(debug_use_after_free, TT_FORK|TT_NEED_BASE|TT_ENABLE_DEBUG_MODE),
390c43e99fdSEd Maste //	TEST(many, TT_FORK|TT_NEED_BASE),
391c43e99fdSEd Maste 
392c43e99fdSEd Maste 
393c43e99fdSEd Maste 	END_OF_TESTCASES
394c43e99fdSEd Maste };
395c43e99fdSEd Maste 
396