daemon->env->worker = NULL;
daemon->env->send_packet = &worker_send_packet;
daemon->env->send_query = &worker_send_query;
+ daemon->env->remove_subqueries = &worker_slumber_subqueries;
for(i=0; i<daemon->num_modules; i++) {
log_info("init module %d: %s", i, daemon->modfunc[i]->name);
if(!(*daemon->modfunc[i]->init)(daemon->env, i)) {
{
if(!qstate)
return;
- if(qstate->subquery_first) {
- while(qstate->subquery_first) {
- /* put subqueries on slumber list */
- struct module_qstate* s = qstate->subquery_first;
- module_subreq_remove(&qstate->subquery_first, s);
- s->parent = NULL;
- s->work_info = NULL;
- module_subreq_insert(&worker->slumber_list, s);
- }
- verbose(VERB_ALGO, "worker: slumber list has %d entries",
- module_subreq_num(worker->slumber_list));
- }
+ worker_slumber_subqueries(qstate);
qstate_cleanup(worker, qstate);
}
}
return e;
}
+
+void
+worker_slumber_subqueries(struct module_qstate* qstate)
+{
+ struct worker* worker = qstate->env->worker;
+ if(qstate->subquery_first) {
+ while(qstate->subquery_first) {
+ /* put subqueries on slumber list */
+ struct module_qstate* s = qstate->subquery_first;
+ module_subreq_remove(&qstate->subquery_first, s);
+ s->parent = NULL;
+ s->work_info = NULL;
+ module_subreq_insert(&worker->slumber_list, s);
+ }
+ verbose(VERB_ALGO, "worker: slumber list has %d entries",
+ module_subreq_num(worker->slumber_list));
+ }
+}
struct sockaddr_storage* addr, socklen_t addrlen,
struct module_qstate* q);
+/**
+ * Remove subqueries, by moving them to the slumber list.
+ * @param qstate: this state has subqueries removed.
+ */
+void worker_slumber_subqueries(struct module_qstate* qstate);
+
#endif /* DAEMON_WORKER_H */
multiple times, this will succeed. Only one callback will happen;
multiple outbound-list entries result (but the double cleanup of it
will not matter).
+ - when iterator moves on due to CNAME or referral, it will remove
+ the subqueries (for other targets). These are put on the slumber
+ list.
14 June 2007: Wouter
- num query targets was > 0 , not >= 0 compared, so that fetch
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
+ (*qstate->env->remove_subqueries)(qstate);
return final_state(iq);
} else if(type == RESPONSE_TYPE_REFERRAL) {
/* REFERRAL type responses get a reset of the
* handled? Say by a subquery that inherits the outbound_entry.
*/
outbound_list_clear(&iq->outlist);
+ (*qstate->env->remove_subqueries)(qstate);
verbose(VERB_ALGO, "cleared outbound list for next round");
return next_state(iq, QUERYTARGETS_STATE);
} else if(type == RESPONSE_TYPE_CNAME) {
* handled? Say by a subquery that inherits the outbound_entry.
*/
outbound_list_clear(&iq->outlist);
+ (*qstate->env->remove_subqueries)(qstate);
verbose(VERB_ALGO, "cleared outbound list for query restart");
/* go to INIT_REQUEST_STATE for new qname. */
return next_state(iq, INIT_REQUEST_STATE);
struct sockaddr_storage* addr, socklen_t addrlen,
struct module_qstate* q);
+ /**
+ * Cleanup subqueries from this query state. Either delete or
+ * move them somewhere else. This query state no longer needs the
+ * results from those subqueries.
+ * @param qstate: query state.
+ * subqueries are (re)moved so that no subq_done events from
+ * them will reach this qstate.
+ */
+ void (*remove_subqueries)(struct module_qstate* qstate);
+
/** internal data for daemon - worker thread. */
struct worker* worker;
/** allocation service */