mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-19 09:15:34 -04:00
Merge remote-tracking branch 'origin/patches-2.0'
This commit is contained in:
commit
128c8d6c0f
24
event.c
24
event.c
@ -250,8 +250,10 @@ HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
|
||||
dent->added = 1; \
|
||||
} else { \
|
||||
event_errx(_EVENT_ERR_ABORT, \
|
||||
"%s: noting an add on a non-setup event %p", \
|
||||
__func__, (ev)); \
|
||||
"%s: noting an add on a non-setup event %p" \
|
||||
" (events: 0x%x, fd: %d, flags: 0x%x)", \
|
||||
__func__, (ev), (ev)->ev_events, \
|
||||
(ev)->ev_fd, (ev)->ev_flags); \
|
||||
} \
|
||||
EVLOCK_UNLOCK(_event_debug_map_lock, 0); \
|
||||
} \
|
||||
@ -268,8 +270,10 @@ HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
|
||||
dent->added = 0; \
|
||||
} else { \
|
||||
event_errx(_EVENT_ERR_ABORT, \
|
||||
"%s: noting a del on a non-setup event %p", \
|
||||
__func__, (ev)); \
|
||||
"%s: noting a del on a non-setup event %p" \
|
||||
" (events: 0x%x, fd: %d, flags: 0x%x)", \
|
||||
__func__, (ev), (ev)->ev_events, \
|
||||
(ev)->ev_fd, (ev)->ev_flags); \
|
||||
} \
|
||||
EVLOCK_UNLOCK(_event_debug_map_lock, 0); \
|
||||
} \
|
||||
@ -284,8 +288,10 @@ HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
|
||||
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
|
||||
if (!dent) { \
|
||||
event_errx(_EVENT_ERR_ABORT, \
|
||||
"%s called on a non-initialized event %p", \
|
||||
__func__, (ev)); \
|
||||
"%s called on a non-initialized event %p" \
|
||||
" (events: 0x%x, fd: %d, flags: 0x%x)", \
|
||||
__func__, (ev), (ev)->ev_events, \
|
||||
(ev)->ev_fd, (ev)->ev_flags); \
|
||||
} \
|
||||
EVLOCK_UNLOCK(_event_debug_map_lock, 0); \
|
||||
} \
|
||||
@ -300,8 +306,10 @@ HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry,
|
||||
dent = HT_FIND(event_debug_map, &global_debug_map, &find); \
|
||||
if (dent && dent->added) { \
|
||||
event_errx(_EVENT_ERR_ABORT, \
|
||||
"%s called on an already added event %p", \
|
||||
__func__, (ev)); \
|
||||
"%s called on an already added event %p" \
|
||||
" (events: 0x%x, fd: %d, flags: 0x%x)", \
|
||||
__func__, (ev), (ev)->ev_events, \
|
||||
(ev)->ev_fd, (ev)->ev_flags); \
|
||||
} \
|
||||
EVLOCK_UNLOCK(_event_debug_map_lock, 0); \
|
||||
} \
|
||||
|
@ -1637,6 +1637,124 @@ gaic_launch(struct event_base *base, struct evdns_base *dns_base)
|
||||
++pending;
|
||||
}
|
||||
|
||||
/* FIXME: We should move this to regress_main.c if anything else needs it.*/
|
||||
|
||||
/* Trivial replacements for malloc/free/realloc to check for memory leaks.
|
||||
* Not threadsafe. */
|
||||
static int allocated_chunks = 0;
|
||||
|
||||
static void *
|
||||
cnt_malloc(size_t sz)
|
||||
{
|
||||
allocated_chunks += 1;
|
||||
return malloc(sz);
|
||||
}
|
||||
|
||||
static void *
|
||||
cnt_realloc(void *old, size_t sz)
|
||||
{
|
||||
if (!old)
|
||||
allocated_chunks += 1;
|
||||
if (!sz)
|
||||
allocated_chunks -= 1;
|
||||
return realloc(old, sz);
|
||||
}
|
||||
|
||||
static void
|
||||
cnt_free(void *ptr)
|
||||
{
|
||||
allocated_chunks -= 1;
|
||||
return free(ptr);
|
||||
}
|
||||
|
||||
struct testleak_env_t {
|
||||
struct event_base *base;
|
||||
struct evdns_base *dns_base;
|
||||
struct evdns_request *req;
|
||||
struct generic_dns_callback_result r;
|
||||
};
|
||||
|
||||
static void *
|
||||
testleak_setup(const struct testcase_t *testcase)
|
||||
{
|
||||
struct testleak_env_t *env;
|
||||
|
||||
allocated_chunks = 0;
|
||||
event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free);
|
||||
event_enable_debug_mode();
|
||||
|
||||
/* not mm_calloc: we don't want to mess with the count. */
|
||||
env = calloc(1, sizeof(struct testleak_env_t));
|
||||
env->base = event_base_new();
|
||||
env->dns_base = evdns_base_new(env->base, 0);
|
||||
env->req = evdns_base_resolve_ipv4(
|
||||
env->dns_base, "example.com", DNS_QUERY_NO_SEARCH,
|
||||
generic_dns_callback, &env->r);
|
||||
return env;
|
||||
}
|
||||
|
||||
static int
|
||||
testleak_cleanup(const struct testcase_t *testcase, void *env_)
|
||||
{
|
||||
int ok = 0;
|
||||
struct testleak_env_t *env = env_;
|
||||
/* FIXME: that's `1' because of event_debug_map_HT_GROW */
|
||||
tt_int_op(allocated_chunks, ==, 1);
|
||||
ok = 1;
|
||||
end:
|
||||
if (env->dns_base)
|
||||
evdns_base_free(env->dns_base, 0);
|
||||
if (env->base)
|
||||
event_base_free(env->base);
|
||||
if (env)
|
||||
free(env);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static struct testcase_setup_t testleak_funcs = {
|
||||
testleak_setup, testleak_cleanup
|
||||
};
|
||||
|
||||
static void
|
||||
test_dbg_leak_cancel(void *env_)
|
||||
{
|
||||
/* cancel, loop, free/dns, free/base */
|
||||
struct testleak_env_t *env = env_;
|
||||
int send_err_shutdown = 1;
|
||||
evdns_cancel_request(env->dns_base, env->req);
|
||||
env->req = 0;
|
||||
|
||||
/* `req` is freed in callback, that's why one loop is required. */
|
||||
event_base_loop(env->base, EVLOOP_NONBLOCK);
|
||||
|
||||
/* send_err_shutdown means nothing as soon as our request is
|
||||
* already canceled */
|
||||
evdns_base_free(env->dns_base, send_err_shutdown);
|
||||
env->dns_base = 0;
|
||||
event_base_free(env->base);
|
||||
env->base = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_dbg_leak_shutdown(void *env_)
|
||||
{
|
||||
/* free/dns, loop, free/base */
|
||||
struct testleak_env_t *env = env_;
|
||||
int send_err_shutdown = 1;
|
||||
|
||||
/* `req` is freed both with `send_err_shutdown` and without it,
|
||||
* the only difference is `evdns_callback` call */
|
||||
env->req = 0;
|
||||
|
||||
evdns_base_free(env->dns_base, send_err_shutdown);
|
||||
env->dns_base = 0;
|
||||
|
||||
/* `req` is freed in callback, that's why one loop is required */
|
||||
event_base_loop(env->base, EVLOOP_NONBLOCK);
|
||||
event_base_free(env->base);
|
||||
env->base = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_getaddrinfo_async_cancel_stress(void *ptr)
|
||||
{
|
||||
@ -1714,6 +1832,9 @@ struct testcase_t dns_testcases[] = {
|
||||
{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
|
||||
TT_FORK, NULL, NULL },
|
||||
|
||||
{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
|
||||
{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
|
||||
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user