*
*/
typedef struct {
+ fr_dlist_head_t *log_head; //!< To allow the log entry to remove itself on free.
fr_dlist_t entry; //!< Entry in the linked list.
fr_trunk_request_state_t from; //!< What state we transitioned from.
fr_trunk_request_state_t to; //!< What state we transitioned to.
char const *function; //!< State change occurred in.
int line; //!< Line change occurred on.
-
} fr_trunk_request_state_log_t;
#endif
#ifndef NDEBUG
void trunk_request_state_log_entry_add(char const *function, int line,
- fr_trunk_request_t *treq, fr_trunk_request_state_t new);
+ fr_trunk_request_t *treq, fr_trunk_request_state_t new) CC_HINT(nonnull);
/** Record a request state transition and log appropriate output
*
*/
if (trunk->conf.req_cleanup_delay == 0) {
treq->pub.state = FR_TRUNK_REQUEST_STATE_INIT;
+
+#ifndef NDEBUG
+ /*
+ * Ensure anything parented off the treq
+ * is freed. We do this to trigger
+ * the destructors for the log entries.
+ */
+ talloc_free_children(treq);
+
+ /*
+ * State log should now be empty as entries
+ * remove themselves from the dlist
+ * on free.
+ */
+ fr_assert_msg(fr_dlist_num_elements(&treq->log) == 0,
+ "Should have 0 remaining log entries, have %zu", fr_dlist_num_elements(&treq->log));
+#endif
+
talloc_free(treq);
return;
}
treq->cancel_reason = FR_TRUNK_CANCEL_REASON_NONE;
treq->last_freed = fr_time();
-#ifndef NDEBUG
- /*
- * Clear the state change log
- */
- fr_dlist_talloc_free(&treq->log);
-#endif
-
/*
* Ensure anything parented off the treq
* is freed.
*/
talloc_free_children(treq);
+#ifndef NDEBUG
+ /*
+ * State log should now be empty as entries
+ * remove themselves from the dlist
+ * on free.
+ */
+ fr_assert_msg(fr_dlist_num_elements(&treq->log) == 0,
+ "Should have 0 remaining log entries, have %zu", fr_dlist_num_elements(&treq->log));
+#endif
+
/*
* Insert at the head, so that we can free
* requests that have been unused for N
}
#ifndef NDEBUG
+/** Used for sanity checks to ensure all log entries have been freed
+ *
+ */
+static int _state_log_entry_free(fr_trunk_request_state_log_t *slog)
+{
+ fr_dlist_remove(slog->log_head, slog);
+
+ return 0;
+}
+
void trunk_request_state_log_entry_add(char const *function, int line,
fr_trunk_request_t *treq, fr_trunk_request_state_t new)
{
fr_trunk_request_state_log_t *slog = NULL;
MEM(slog = talloc_zero(treq, fr_trunk_request_state_log_t));
+ slog->log_head = &treq->log;
slog->from = treq->pub.state;
slog->to = new;
slog->function = function;
slog->tconn_state = treq->pub.tconn->pub.state;
}
fr_dlist_insert_tail(&treq->log, slog);
+ talloc_set_destructor(slog, _state_log_entry_free);
}
void fr_trunk_request_state_log(fr_log_t const *log, fr_log_type_t log_type, char const *file, int line,