summaryrefslogtreecommitdiff
path: root/lib/dns/dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/dispatch.c')
-rw-r--r--lib/dns/dispatch.c123
1 files changed, 58 insertions, 65 deletions
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index ad4f30c3..a999032e 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.101.2.10 2004/04/15 02:16:26 marka Exp $ */
+/* $Id: dispatch.c,v 1.101.2.11 2004/07/21 00:49:02 marka Exp $ */
#include <config.h>
@@ -160,7 +160,7 @@ static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len);
static void *allocate_udp_buffer(dns_dispatch_t *disp);
static inline void free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev);
static inline dns_dispatchevent_t *allocate_event(dns_dispatch_t *disp);
-static void do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp);
+static void do_cancel(dns_dispatch_t *disp);
static dns_dispentry_t *linear_first(dns_qid_t *disp);
static dns_dispentry_t *linear_next(dns_qid_t *disp,
dns_dispentry_t *resp);
@@ -625,26 +625,25 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) {
/* query */
free_buffer(disp, ev->region.base, ev->region.length);
goto restart;
- } else {
- /* response */
- bucket = dns_hash(qid, &ev->address, id);
- LOCK(&qid->lock);
- resp = bucket_search(qid, &ev->address, id, bucket);
- UNLOCK(&qid->lock);
- dispatch_log(disp, LVL(90),
- "search for response in bucket %d: %s",
- bucket, (resp == NULL ? "not found" : "found"));
-
- if (resp == NULL) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto restart;
- }
- queue_response = resp->item_out;
- rev = allocate_event(resp->disp);
- if (rev == NULL) {
- free_buffer(disp, ev->region.base, ev->region.length);
- goto restart;
- }
+ }
+
+ /* response */
+ bucket = dns_hash(qid, &ev->address, id);
+ LOCK(&qid->lock);
+ resp = bucket_search(qid, &ev->address, id, bucket);
+ dispatch_log(disp, LVL(90),
+ "search for response in bucket %d: %s",
+ bucket, (resp == NULL ? "not found" : "found"));
+
+ if (resp == NULL) {
+ free_buffer(disp, ev->region.base, ev->region.length);
+ goto unlock;
+ }
+ queue_response = resp->item_out;
+ rev = allocate_event(resp->disp);
+ if (rev == NULL) {
+ free_buffer(disp, ev->region.base, ev->region.length);
+ goto unlock;
}
/*
@@ -672,6 +671,8 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) {
resp->item_out = ISC_TRUE;
isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
}
+ unlock:
+ UNLOCK(&qid->lock);
/*
* Restart recv() to get the next packet.
@@ -742,7 +743,7 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
case ISC_R_EOF:
dispatch_log(disp, LVL(90), "shutting down on EOF");
- do_cancel(disp, NULL);
+ do_cancel(disp);
break;
default:
@@ -750,7 +751,7 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
"shutting down due to TCP "
"receive error: %s",
isc_result_totext(tcpmsg->result));
- do_cancel(disp, NULL);
+ do_cancel(disp);
break;
}
@@ -806,27 +807,26 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
* Query.
*/
goto restart;
- } else {
- /*
- * Response.
- */
- bucket = dns_hash(qid, &tcpmsg->address, id);
- LOCK(&qid->lock);
- resp = bucket_search(qid, &tcpmsg->address, id, bucket);
- UNLOCK(&qid->lock);
- dispatch_log(disp, LVL(90),
- "search for response in bucket %d: %s",
- bucket, (resp == NULL ? "not found" : "found"));
-
- if (resp == NULL)
- goto restart;
- queue_response = resp->item_out;
- rev = allocate_event(disp);
- if (rev == NULL)
- goto restart;
}
/*
+ * Response.
+ */
+ bucket = dns_hash(qid, &tcpmsg->address, id);
+ LOCK(&qid->lock);
+ resp = bucket_search(qid, &tcpmsg->address, id, bucket);
+ dispatch_log(disp, LVL(90),
+ "search for response in bucket %d: %s",
+ bucket, (resp == NULL ? "not found" : "found"));
+
+ if (resp == NULL)
+ goto unlock;
+ queue_response = resp->item_out;
+ rev = allocate_event(disp);
+ if (rev == NULL)
+ goto unlock;
+
+ /*
* At this point, rev contains the event we want to fill in, and
* resp contains the information on the place to send it to.
* Send the event off.
@@ -848,6 +848,8 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
resp->item_out = ISC_TRUE;
isc_task_send(resp->task, ISC_EVENT_PTR(&rev));
}
+ unlock:
+ UNLOCK(&qid->lock);
/*
* Restart recv() to get the next packet.
@@ -895,7 +897,7 @@ startrecv(dns_dispatch_t *disp) {
free_buffer(disp, region.base, region.length);
disp->shutdown_why = res;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
return;
}
disp->recv_pending = 1;
@@ -907,7 +909,7 @@ startrecv(dns_dispatch_t *disp) {
if (res != ISC_R_SUCCESS) {
disp->shutdown_why = res;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
return;
}
disp->recv_pending = 1;
@@ -1924,7 +1926,7 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
res->magic = 0;
isc_mempool_put(disp->mgr->rpool, res);
if (disp->shutting_down == 1)
- do_cancel(disp, NULL);
+ do_cancel(disp);
else
startrecv(disp);
@@ -1935,8 +1937,9 @@ dns_dispatch_removeresponse(dns_dispentry_t **resp,
}
static void
-do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp) {
+do_cancel(dns_dispatch_t *disp) {
dns_dispatchevent_t *ev;
+ dns_dispentry_t *resp;
dns_qid_t *qid;
if (disp->shutdown_out == 1)
@@ -1947,28 +1950,16 @@ do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp) {
/*
* Search for the first response handler without packets outstanding.
*/
- if (resp == NULL) {
- LOCK(&qid->lock);
- resp = linear_first(qid);
- if (resp == NULL) {
- /* no first item? */
- UNLOCK(&qid->lock);
- return;
- }
- do {
- if (resp->item_out == ISC_FALSE)
- break;
-
- resp = linear_next(qid, resp);
- } while (resp != NULL);
- UNLOCK(&qid->lock);
- }
-
+ LOCK(&qid->lock);
+ for (resp = linear_first(qid);
+ resp != NULL && resp->item_out != ISC_FALSE;
+ /* Empty. */)
+ resp = linear_next(qid, resp);
/*
* No one to send the cancel event to, so nothing to do.
*/
if (resp == NULL)
- return;
+ goto unlock;
/*
* Send the shutdown failsafe event to this resp.
@@ -1985,6 +1976,8 @@ do_cancel(dns_dispatch_t *disp, dns_dispentry_t *resp) {
ev, resp->task);
resp->item_out = ISC_TRUE;
isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
+ unlock:
+ UNLOCK(&qid->lock);
}
isc_socket_t *
@@ -2020,7 +2013,7 @@ dns_dispatch_cancel(dns_dispatch_t *disp) {
disp->shutdown_why = ISC_R_CANCELED;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
UNLOCK(&disp->lock);