diff options
author | David Hankins <dhankins@isc.org> | 2008-03-18 18:28:14 +0000 |
---|---|---|
committer | David Hankins <dhankins@isc.org> | 2008-03-18 18:28:14 +0000 |
commit | 4619c0a2fb805a27baaa48728a564f9870300b29 (patch) | |
tree | 7366084f7686797f0360bcca7c5336237ebc950d /omapip | |
parent | 507fe25f11f51eed58fffc49bf252784ba851074 (diff) | |
download | isc-dhcp-4619c0a2fb805a27baaa48728a564f9870300b29.tar.gz |
- A memory leak when using omapi has been fixed. [ISC-Bugs #17560]
Diffstat (limited to 'omapip')
-rw-r--r-- | omapip/connection.c | 22 | ||||
-rw-r--r-- | omapip/dispatch.c | 103 | ||||
-rw-r--r-- | omapip/protocol.c | 9 |
3 files changed, 94 insertions, 40 deletions
diff --git a/omapip/connection.c b/omapip/connection.c index 93509696..e0cb9177 100644 --- a/omapip/connection.c +++ b/omapip/connection.c @@ -498,6 +498,28 @@ isc_result_t omapi_disconnect (omapi_object_t *h, /* If whatever created us registered a signal handler, send it a disconnect signal. */ omapi_signal (h, "disconnect", h); + + /* Disconnect from protocol object, if any. */ + if (h->inner != NULL) { + if (h->inner->outer != NULL) { + omapi_object_dereference(&h->inner->outer, MDL); + } + omapi_object_dereference(&h->inner, MDL); + } + + /* XXX: the code to free buffers should be in the dereference + function, but there is no special-purpose function to + dereference connections, so these just get leaked */ + /* Free any buffers */ + if (c->inbufs != NULL) { + omapi_buffer_dereference(&c->inbufs, MDL); + } + c->in_bytes = 0; + if (c->outbufs != NULL) { + omapi_buffer_dereference(&c->outbufs, MDL); + } + c->out_bytes = 0; + return ISC_R_SUCCESS; } diff --git a/omapip/dispatch.c b/omapip/dispatch.c index b017e5bd..dda8ce77 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -162,6 +162,8 @@ isc_result_t omapi_register_io_object (omapi_object_t *h, obj -> reader = reader; obj -> writer = writer; obj -> reaper = reaper; + + omapi_io_dereference(&obj, MDL); return ISC_R_SUCCESS; } @@ -273,7 +275,7 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, int count; int desc; struct timeval now, to; - omapi_io_object_t *io, *prev; + omapi_io_object_t *io, *prev, *next; omapi_waiter_object_t *waiter; omapi_object_t *tmp = (omapi_object_t *)0; @@ -483,44 +485,71 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, /* Now check for I/O handles that are no longer valid, and remove them from the list. */ - prev = (omapi_io_object_t *)0; - for (io = omapi_io_states.next; io; io = io -> next) { - if (io -> reaper) { - if (!io -> inner || - ((*(io -> reaper)) (io -> inner) != - ISC_R_SUCCESS)) { - omapi_io_object_t *tmp = - (omapi_io_object_t *)0; - /* Save a reference to the next - pointer, if there is one. */ - if (io -> next) - omapi_io_reference (&tmp, - io -> next, MDL); - if (prev) { - omapi_io_dereference (&prev -> next, - MDL); - if (tmp) - omapi_io_reference - (&prev -> next, - tmp, MDL); - } else { - omapi_io_dereference - (&omapi_io_states.next, MDL); - if (tmp) - omapi_io_reference - (&omapi_io_states.next, - tmp, MDL); - else - omapi_signal_in - ((omapi_object_t *) - &omapi_io_states, - "ready"); - } - if (tmp) - omapi_io_dereference (&tmp, MDL); + prev = NULL; + io = NULL; + if (omapi_io_states.next != NULL) { + omapi_io_reference(&io, omapi_io_states.next, MDL); + } + while (io != NULL) { + if ((io->inner == NULL) || + ((io->reaper != NULL) && + ((io->reaper)(io->inner) != ISC_R_SUCCESS))) + { + + omapi_io_object_t *tmp = NULL; + /* Save a reference to the next + pointer, if there is one. */ + if (io->next != NULL) { + omapi_io_reference(&tmp, io->next, MDL); + omapi_io_dereference(&io->next, MDL); } + if (prev != NULL) { + omapi_io_dereference(&prev->next, MDL); + if (tmp != NULL) + omapi_io_reference(&prev->next, + tmp, MDL); + } else { + omapi_io_dereference(&omapi_io_states.next, + MDL); + if (tmp != NULL) + omapi_io_reference + (&omapi_io_states.next, + tmp, MDL); + else + omapi_signal_in( + (omapi_object_t *) + &omapi_io_states, + "ready"); + } + if (tmp != NULL) + omapi_io_dereference(&tmp, MDL); + + } else { + + if (prev != NULL) { + omapi_io_dereference(&prev, MDL); + } + omapi_io_reference(&prev, io, MDL); + } - prev = io; + + /* + * Equivalent to: + * io = io->next + * But using our reference counting voodoo. + */ + next = NULL; + if (io->next != NULL) { + omapi_io_reference(&next, io->next, MDL); + } + omapi_io_dereference(&io, MDL); + if (next != NULL) { + omapi_io_reference(&io, next, MDL); + omapi_io_dereference(&next, MDL); + } + } + if (prev != NULL) { + omapi_io_dereference(&prev, MDL); } return ISC_R_SUCCESS; diff --git a/omapip/protocol.c b/omapip/protocol.c index 38966cdd..a29bea99 100644 --- a/omapip/protocol.c +++ b/omapip/protocol.c @@ -410,7 +410,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) - dump_rc_history (); + dump_rc_history (h); #endif for (m = omapi_registered_messages; m; m = m -> next) { if (m -> protocol_object == p) { @@ -418,6 +418,9 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, omapi_signal (m -> object, "disconnect"); } } + + /* XXX */ + return ISC_R_SUCCESS; } /* Not a signal we recognize? */ @@ -492,7 +495,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) - dump_rc_history (); + dump_rc_history (h); #endif #if defined (DEBUG_MEMORY_LEAKAGE) } @@ -750,7 +753,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) - dump_rc_history (); + dump_rc_history (h); #endif #if defined (DEBUG_MEMORY_LEAKAGE) previous_outstanding = 0xDEADBEEF; |