* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.117 2004/04/15 01:58:24 marka Exp $ */
+/* $Id: dispatch.c,v 1.118 2004/07/21 00:48:19 marka Exp $ */
#include <config.h>
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);
/* 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;
}
/*
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.
case ISC_R_EOF:
dispatch_log(disp, LVL(90), "shutting down on EOF");
- do_cancel(disp, NULL);
+ do_cancel(disp);
break;
case ISC_R_CONNECTIONRESET:
dispatch_log(disp, level, "shutting down due to TCP "
"receive error: %s: %s", buf,
isc_result_totext(tcpmsg->result));
- do_cancel(disp, NULL);
+ do_cancel(disp);
break;
}
* 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.
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.
free_buffer(disp, region.base, region.length);
disp->shutdown_why = res;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
return;
}
INSIST(disp->recv_pending == 0);
if (res != ISC_R_SUCCESS) {
disp->shutdown_why = res;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
return;
}
INSIST(disp->recv_pending == 0);
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);
}
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)
/*
* 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.
ev, resp->task);
resp->item_out = ISC_TRUE;
isc_task_send(resp->task, ISC_EVENT_PTR(&ev));
+ unlock:
+ UNLOCK(&qid->lock);
}
isc_socket_t *
disp->shutdown_why = ISC_R_CANCELED;
disp->shutting_down = 1;
- do_cancel(disp, NULL);
+ do_cancel(disp);
UNLOCK(&disp->lock);