diff --git a/bin/dig/dig.c b/bin/dig/dig.c index ecd80de2b7..52036f92a3 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: dig.c,v 1.66 2000/07/14 16:35:25 mws Exp $ */ +/* $Id: dig.c,v 1.67 2000/07/14 17:57:23 mws Exp $ */ #include #include @@ -66,6 +66,7 @@ extern dns_tsigkey_t *key; extern isc_boolean_t validated; extern isc_taskmgr_t *taskmgr; extern isc_task_t *global_task; +extern isc_boolean_t free_now; extern isc_boolean_t debugging; extern isc_boolean_t isc_mem_debugging; @@ -539,7 +540,7 @@ reorder_args(int argc, char *argv[]) { static void parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { isc_boolean_t have_host = ISC_FALSE; - dig_server_t *srv = NULL; + dig_server_t *srv = NULL, *s, *s2; dig_lookup_t *lookup = NULL; static dig_lookup_t *default_lookup = NULL; char *batchname = NULL; @@ -926,8 +927,20 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { strcpy(lookup->rttext, "NS"); ISC_LIST_APPEND(lookup_list, lookup, link); } - if (!is_batchfile) + if (!is_batchfile) { printgreeting(argc, argv); + s = ISC_LIST_HEAD(default_lookup->my_server_list); + while (s != NULL) { + debug("freeing server %p belonging to %p", + s, default_lookup); + s2 = s; + s = ISC_LIST_NEXT(s, link); + ISC_LIST_DEQUEUE(default_lookup->my_server_list, + (dig_server_t *)s2, link); + isc_mem_free(mctx, s2); + } + isc_mem_free(mctx, default_lookup); + } } int @@ -946,22 +959,9 @@ main(int argc, char **argv) { result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); check_result(result, "isc_app_onrun"); isc_app_run(); - /* - * XXXMWS This code should really NOT be bypassed. However, - * until the proper code can be added to handle SIGTERM/INT - * correctly, just exit out "hard" and deal as best we can. - */ -#if 0 - if (taskmgr != NULL) { - debug("Freeing taskmgr"); - isc_taskmgr_destroy(&taskmgr); - } - if (isc_mem_debugging) - isc_mem_stats(mctx, stderr); - if (mctx != NULL) - isc_mem_destroy(&mctx); + cancel_all(); + destroy_libs(); isc_app_finish(); -#endif return (exitcode); } diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 535b6268a2..9331cf8ac6 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: dighost.c,v 1.86 2000/07/14 16:35:26 mws Exp $ */ +/* $Id: dighost.c,v 1.87 2000/07/14 17:57:25 mws Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -71,6 +71,7 @@ isc_boolean_t have_ipv6 = ISC_FALSE, specified_source = ISC_FALSE, free_now = ISC_FALSE, + cancel_now = ISC_FALSE, show_details = ISC_FALSE, usesearch = ISC_FALSE, qr = ISC_FALSE, @@ -107,6 +108,21 @@ isc_mempool_t *commctx = NULL; extern isc_boolean_t isc_mem_debugging; isc_boolean_t debugging = ISC_FALSE; char *progname = NULL; +isc_mutex_t lookup_lock; + +/* + * Apply and clear locks at the event level in global task. + */ +#define LOCK_LOOKUP {\ + debug("lock_lookup %s:%d", __FILE__, __LINE__);\ + check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\ + debug("success");\ +} +#define UNLOCK_LOOKUP {\ + debug("unlock_lookup %s:%d", __FILE__, __LINE__);\ + check_result(isc_mutex_unlock((&lookup_lock)),\ + "isc_mutex_unlock");\ +} static void cancel_lookup(dig_lookup_t *lookup); @@ -624,6 +640,9 @@ setup_libs(void) { */ isc_mempool_setfreemax(commctx, 6); isc_mempool_setfillcount(commctx, 2); + + result = isc_mutex_init(&lookup_lock); + check_result(result, "isc_mutex_init"); } static void @@ -701,6 +720,7 @@ clear_query(dig_query_t *query) { debug("clear_query(%p)",query); lookup = query->lookup; + ISC_LIST_UNLINK(lookup->q, query, link); if (ISC_LINK_LINKED(&query->recvbuf, link)) ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf, @@ -784,6 +804,8 @@ begin_next_lookup(void) { dig_lookup_t *next; debug("begin_next_lookup()"); + if (cancel_now) + return; next = ISC_LIST_HEAD(lookup_list); if (next != NULL) { setup_lookup(next); @@ -838,6 +860,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, debug("followup_lookup()"); result = dns_message_firstname(msg,section); + if (result != ISC_R_SUCCESS) { debug("firstname returned %s", isc_result_totext(result)); @@ -1277,6 +1300,7 @@ send_done(isc_task_t *task, isc_event_t *event) { UNUSED(task); + LOCK_LOOKUP; sevent = (isc_socketevent_t *)event; query = event->ev_arg; @@ -1294,9 +1318,8 @@ send_done(isc_task_t *task, isc_event_t *event) { l = query->lookup; clear_query(query); check_next_lookup(l); - return; } - + UNLOCK_LOOKUP; } void @@ -1392,8 +1415,9 @@ connect_timeout(isc_task_t *task, isc_event_t *event) { REQUIRE(event->ev_type == ISC_TIMEREVENT_IDLE); debug("connect_timeout()"); - lookup = event->ev_arg; + LOCK_LOOKUP; + lookup = event->ev_arg; isc_event_free(&event); debug("buffer allocate connect_timeout"); @@ -1434,6 +1458,7 @@ connect_timeout(isc_task_t *task, isc_event_t *event) { isc_timer_detach(&lookup->timer); isc_buffer_free(&b); debug("done with connect_timeout()"); + UNLOCK_LOOKUP; } static void @@ -1453,8 +1478,8 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { debug("tcp_length_done()"); + LOCK_LOOKUP; sevent = (isc_socketevent_t *)event; - query = event->ev_arg; recvcount--; @@ -1512,6 +1537,7 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) { debug("resubmitted recv request with length %d, recvcount=%d", length, recvcount); isc_event_free(&event); + UNLOCK_LOOKUP; } static void @@ -1583,10 +1609,11 @@ connect_done(isc_task_t *task, isc_event_t *event) { debug("connect_done()"); + LOCK_LOOKUP; sevent = (isc_socketevent_t *)event; query = sevent->ev_arg; - REQUIRE(query->waiting_connect); + INSIST(query->waiting_connect); query->waiting_connect = ISC_FALSE; @@ -1616,10 +1643,12 @@ connect_done(isc_task_t *task, isc_event_t *event) { l = query->lookup; clear_query(query); check_next_lookup(l); + UNLOCK_LOOKUP; return; } launch_next_query(query, ISC_TRUE); isc_event_free(&event); + UNLOCK_LOOKUP; } @@ -1821,6 +1850,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { debug("recv_done()"); + LOCK_LOOKUP; recvcount--; debug("recvcount=%d", recvcount); INSIST(recvcount >= 0); @@ -1835,7 +1865,8 @@ recv_done(isc_task_t *task, isc_event_t *event) { if ((l->tcp_mode) && (l->timer != NULL)) isc_timer_touch(l->timer); - if (!l->pending && !l->ns_search_only) { + if ((!l->pending && !l->ns_search_only) + || cancel_now) { debug("no longer pending. Got %s", isc_result_totext(sevent->result)); @@ -1845,6 +1876,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); clear_query(query); check_next_lookup(l); + UNLOCK_LOOKUP; return; } @@ -1892,6 +1924,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { clear_query(query); cancel_lookup(l); check_next_lookup(l); + UNLOCK_LOOKUP; return; } if (key != NULL) { @@ -1999,6 +2032,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { isc_event_free (&event); query->working = ISC_FALSE; query->waiting_connect = ISC_FALSE; + UNLOCK_LOOKUP; return; } docancel = check_for_more_data(query, msg, sevent); @@ -2041,6 +2075,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { clear_query(query); check_next_lookup(l); } + UNLOCK_LOOKUP; return; } /* @@ -2054,6 +2089,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); clear_query(query); check_next_lookup(l); + UNLOCK_LOOKUP; return; } fatal("recv_done got result %s", @@ -2224,20 +2260,27 @@ void onrun_callback(isc_task_t *task, isc_event_t *event) { UNUSED(task); isc_event_free(&event); + LOCK_LOOKUP; start_lookup(); + UNLOCK_LOOKUP; } -#if 0 /* * This will be used in the SIGINT handler, and perhaps other places. */ -static void +void cancel_all(void) { dig_lookup_t *l; dig_query_t *q; debug("cancel_all()"); - + + LOCK_LOOKUP; + if (free_now) { + UNLOCK_LOOKUP; + return; + } + cancel_now = ISC_TRUE; l = ISC_LIST_HEAD(lookup_list); while (l != NULL) { if (l->timer != NULL) @@ -2249,22 +2292,16 @@ cancel_all(void) { if (q->sock != NULL) { isc_socket_cancel(q->sock, NULL, ISC_SOCKCANCEL_ALL); - isc_socket_detach(&q->sock); - sockcount--; - debug("sockcount=%d",sockcount); - INSIST(sockcount >= 0); - check_if_done(); } q = ISC_LIST_NEXT(q, link); } l = ISC_LIST_NEXT(l, link); } - check_if_done(); + UNLOCK_LOOKUP; } -#endif -void -free_lists(void) { +static void +xfree_lists(void) { void *ptr; dig_server_t *s; dig_searchlist_t *o; @@ -2307,10 +2344,6 @@ free_lists(void) { debug("freeing timermgr"); isc_timermgr_destroy(&timermgr); } - if (global_task != NULL) { - debug("freeing task"); - isc_task_detach(&global_task); - } if (key != NULL) { debug("freeing key %p", key); dns_tsigkey_setdeleted(key); @@ -2333,3 +2366,30 @@ free_lists(void) { isc_entropy_detach(&entp); } } + +void +destroy_libs(void) { + debug("destroy_libs()"); + if (global_task != NULL) { + debug("freeing task"); + isc_task_detach(&global_task); + } + if (taskmgr != NULL) { + debug("Freeing taskmgr"); + isc_taskmgr_destroy(&taskmgr); + } + LOCK_LOOKUP; + xfree_lists(); + isc_mutex_destroy(&lookup_lock); + if (isc_mem_debugging) + isc_mem_stats(mctx, stderr); + if (mctx != NULL) + isc_mem_destroy(&mctx); +} + +/* + * Dummy function, soon to go away + */ +void +free_lists(void) { +} diff --git a/bin/dig/host.c b/bin/dig/host.c index 27a2d99b02..0364fcfe3e 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: host.c,v 1.40 2000/07/14 16:35:27 mws Exp $ */ +/* $Id: host.c,v 1.41 2000/07/14 17:57:26 mws Exp $ */ #include #include @@ -677,22 +677,9 @@ main(int argc, char **argv) { result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); check_result(result, "isc_app_onrun"); isc_app_run(); - /* - * XXXMWS This code should really NOT be bypassed. However, - * until the proper code can be added to handle SIGTERM/INT - * correctly, just exit out "hard" and deal as best we can. - */ -#if 0 - if (taskmgr != NULL) { - debug("freeing taskmgr"); - isc_taskmgr_destroy(&taskmgr); - } - if (isc_mem_debugging) - isc_mem_stats(mctx, stderr); + cancel_all(); + destroy_libs(); isc_app_finish(); - if (mctx != NULL) - isc_mem_destroy(&mctx); -#endif return (0); } diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 289e2a26aa..d3d37c0598 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: dig.h,v 1.34 2000/07/14 16:35:30 mws Exp $ */ +/* $Id: dig.h,v 1.35 2000/07/14 17:57:27 mws Exp $ */ #ifndef DIG_H #define DIG_H @@ -222,6 +222,12 @@ void clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest); +void +cancel_all(void); + +void +destroy_libs(void); + /* * Routines needed in dig.c and host.c. */