* SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.68.2.3 2000/08/22 19:59:44 gson Exp $ */
+/* $Id: xfrout.c,v 1.68.2.4 2000/12/04 18:59:40 bwelling Exp $ */
#include <config.h>
return (it->result);
}
+static void
+db_rr_iterator_pause(db_rr_iterator_t *it) {
+ dns_dbiterator_pause(it->dbit);
+}
+
static void
db_rr_iterator_destroy(db_rr_iterator_t *it) {
if (dns_rdataset_isassociated(&it->rdataset))
dns_name_t **,
isc_uint32_t *,
dns_rdata_t **);
+ void (*pause)(rrstream_t *);
void (*destroy)(rrstream_t **);
};
+static void
+rrstream_noop_pause(rrstream_t *rs) {
+ UNUSED(rs);
+}
+
/**************************************************************************/
/*
* An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
static rrstream_methods_t ixfr_rrstream_methods = {
ixfr_rrstream_first,
ixfr_rrstream_next,
- ixfr_rrstream_current,
+ ixfr_rrstream_current,
+ rrstream_noop_pause,
ixfr_rrstream_destroy
};
/**************************************************************************/
/*
- * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns
+ * An 'axfr_rrstream_t' is an 'rrstream_t' that returns
* an AXFR-like RR stream from a database.
*
* The SOAs at the beginning and end of the transfer are
typedef struct axfr_rrstream {
rrstream_t common;
int state;
- db_rr_iterator_t it;
+ db_rr_iterator_t it;
isc_boolean_t it_valid;
} axfr_rrstream_t;
db_rr_iterator_current(&s->it, name, ttl, rdata);
}
+static void
+axfr_rrstream_pause(rrstream_t *rs) {
+ axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
+ db_rr_iterator_pause(&s->it);
+}
+
static void
axfr_rrstream_destroy(rrstream_t **rsp) {
axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
static rrstream_methods_t axfr_rrstream_methods = {
axfr_rrstream_first,
axfr_rrstream_next,
- axfr_rrstream_current,
+ axfr_rrstream_current,
+ axfr_rrstream_pause,
axfr_rrstream_destroy
};
static rrstream_methods_t soa_rrstream_methods = {
soa_rrstream_first,
soa_rrstream_next,
- soa_rrstream_current,
+ soa_rrstream_current,
+ rrstream_noop_pause,
soa_rrstream_destroy
};
rrstream_t *curstream = s->components[s->state];
s->result = curstream->methods->next(curstream);
while (s->result == ISC_R_NOMORE) {
+ /*
+ * Make sure locks held by the current stream
+ * are released before we switch streams.
+ */
+ curstream->methods->pause(curstream);
if (s->state == 2)
return (ISC_R_NOMORE);
s->state++;
curstream->methods->current(curstream, name, ttl, rdata);
}
+static void
+compound_rrstream_pause(rrstream_t *rs)
+{
+ compound_rrstream_t *s = (compound_rrstream_t *) rs;
+ rrstream_t *curstream;
+ INSIST(0 <= s->state && s->state < 3);
+ curstream = s->components[s->state];
+ curstream->methods->pause(curstream);
+}
+
static void
compound_rrstream_destroy(rrstream_t **rsp) {
compound_rrstream_t *s = (compound_rrstream_t *) *rsp;
static rrstream_methods_t compound_rrstream_methods = {
compound_rrstream_first,
compound_rrstream_next,
- compound_rrstream_current,
+ compound_rrstream_current,
+ compound_rrstream_pause,
compound_rrstream_destroy
};
msg = NULL;
ns_client_send(xfr->client);
xfrout_ctx_destroy(&xfr);
- return;
+ result = ISC_R_SUCCESS;
+ goto done;
}
/* Advance lasttsig to be the last TSIG generated */
if (msg != NULL) {
dns_message_destroy(&msg);
}
+
+ done:
+ /*
+ * Make sure to release any locks held by database
+ * iterators before returning from the event handler.
+ */
+ xfr->stream->methods->pause(xfr->stream);
+
if (result == ISC_R_SUCCESS)
return;