mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 12:28:19 -04:00
Merge remote-tracking branch 'origin/pr/62'
This commit is contained in:
commit
0ac2ed655a
17
evdns.c
17
evdns.c
@ -742,23 +742,31 @@ request_reissue(struct request *req) {
|
|||||||
|
|
||||||
/* this function looks for space on the inflight queue and promotes */
|
/* this function looks for space on the inflight queue and promotes */
|
||||||
/* requests from the waiting queue if it can. */
|
/* requests from the waiting queue if it can. */
|
||||||
|
/* */
|
||||||
|
/* TODO: */
|
||||||
|
/* add return code, see at nameserver_pick() and other functions. */
|
||||||
static void
|
static void
|
||||||
evdns_requests_pump_waiting_queue(struct evdns_base *base) {
|
evdns_requests_pump_waiting_queue(struct evdns_base *base) {
|
||||||
ASSERT_LOCKED(base);
|
ASSERT_LOCKED(base);
|
||||||
while (base->global_requests_inflight < base->global_max_requests_inflight &&
|
while (base->global_requests_inflight < base->global_max_requests_inflight &&
|
||||||
base->global_requests_waiting) {
|
base->global_requests_waiting) {
|
||||||
struct request *req;
|
struct request *req;
|
||||||
/* move a request from the waiting queue to the inflight queue */
|
|
||||||
EVUTIL_ASSERT(base->req_waiting_head);
|
EVUTIL_ASSERT(base->req_waiting_head);
|
||||||
req = base->req_waiting_head;
|
req = base->req_waiting_head;
|
||||||
|
|
||||||
|
req->ns = nameserver_pick(base);
|
||||||
|
if (!req->ns)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* move a request from the waiting queue to the inflight queue */
|
||||||
|
req->ns->requests_inflight++;
|
||||||
|
|
||||||
evdns_request_remove(req, &base->req_waiting_head);
|
evdns_request_remove(req, &base->req_waiting_head);
|
||||||
|
|
||||||
base->global_requests_waiting--;
|
base->global_requests_waiting--;
|
||||||
base->global_requests_inflight++;
|
base->global_requests_inflight++;
|
||||||
|
|
||||||
req->ns = nameserver_pick(base);
|
|
||||||
req->ns->requests_inflight++;
|
|
||||||
|
|
||||||
request_trans_id_set(req, transaction_id_pick(base));
|
request_trans_id_set(req, transaction_id_pick(base));
|
||||||
|
|
||||||
evdns_request_insert(req, &REQ_HEAD(base, req->trans_id));
|
evdns_request_insert(req, &REQ_HEAD(base, req->trans_id));
|
||||||
@ -2468,6 +2476,7 @@ evdns_base_resume(struct evdns_base *base)
|
|||||||
EVDNS_LOCK(base);
|
EVDNS_LOCK(base);
|
||||||
evdns_requests_pump_waiting_queue(base);
|
evdns_requests_pump_waiting_queue(base);
|
||||||
EVDNS_UNLOCK(base);
|
EVDNS_UNLOCK(base);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1755,6 +1755,56 @@ test_dbg_leak_cancel(void *env_)
|
|||||||
env->base = 0;
|
env->base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dbg_leak_resume(void *env_, int cancel, int send_err_shutdown)
|
||||||
|
{
|
||||||
|
/* cancel, loop, free/dns, free/base */
|
||||||
|
struct testleak_env_t *env = env_;
|
||||||
|
if (cancel) {
|
||||||
|
evdns_cancel_request(env->dns_base, env->req);
|
||||||
|
tt_assert(!evdns_base_resume(env->dns_base));
|
||||||
|
} else {
|
||||||
|
/* TODO: No nameservers, request can't be processed, must be errored */
|
||||||
|
tt_assert(!evdns_base_resume(env->dns_base));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because we don't cancel request,
|
||||||
|
* and want our callback to recieve DNS_ERR_SHUTDOWN,
|
||||||
|
* we use deferred callback, and there was
|
||||||
|
* - one extra malloc(),
|
||||||
|
* @see reply_schedule_callback()
|
||||||
|
* - and one missing free
|
||||||
|
* @see request_finished() (req->handle->pending_cb = 1)
|
||||||
|
* than we don't need to count in testleak_cleanup()
|
||||||
|
*
|
||||||
|
* So just decrement allocated_chunks to 2,
|
||||||
|
* like we already take care about it.
|
||||||
|
*/
|
||||||
|
if (!cancel && send_err_shutdown) {
|
||||||
|
allocated_chunks -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_base_loop(env->base, EVLOOP_NONBLOCK);
|
||||||
|
|
||||||
|
end:
|
||||||
|
evdns_base_free(env->dns_base, send_err_shutdown);
|
||||||
|
env->dns_base = 0;
|
||||||
|
event_base_free(env->base);
|
||||||
|
env->base = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IMPL_DBG_LEAK_RESUME(name, cancel, send_err_shutdown) \
|
||||||
|
static void \
|
||||||
|
test_dbg_leak_##name##_(void *env_) \
|
||||||
|
{ \
|
||||||
|
dbg_leak_resume(env_, cancel, send_err_shutdown); \
|
||||||
|
}
|
||||||
|
IMPL_DBG_LEAK_RESUME(resume, 0, 0)
|
||||||
|
IMPL_DBG_LEAK_RESUME(cancel_and_resume, 1, 0)
|
||||||
|
IMPL_DBG_LEAK_RESUME(resume_send_err, 0, 1)
|
||||||
|
IMPL_DBG_LEAK_RESUME(cancel_and_resume_send_err, 1, 1)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dbg_leak_shutdown(void *env_)
|
test_dbg_leak_shutdown(void *env_)
|
||||||
{
|
{
|
||||||
@ -1856,6 +1906,14 @@ struct testcase_t dns_testcases[] = {
|
|||||||
#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
|
#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
|
||||||
{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
|
{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
|
||||||
{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
|
{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
|
||||||
|
|
||||||
|
{ "leak_resume", test_dbg_leak_resume_, TT_FORK, &testleak_funcs, NULL },
|
||||||
|
{ "leak_cancel_and_resume", test_dbg_leak_cancel_and_resume_,
|
||||||
|
TT_FORK, &testleak_funcs, NULL },
|
||||||
|
{ "leak_resume_send_err", test_dbg_leak_resume_send_err_,
|
||||||
|
TT_FORK, &testleak_funcs, NULL },
|
||||||
|
{ "leak_cancel_and_resume_send_err", test_dbg_leak_cancel_and_resume_send_err_,
|
||||||
|
TT_FORK, &testleak_funcs, NULL },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
|
Loading…
x
Reference in New Issue
Block a user