diff --git a/bindings/guile/engine.scm b/bindings/guile/engine.scm
index 99074e8690b..c2bf762214b 100644
--- a/bindings/guile/engine.scm
+++ b/bindings/guile/engine.scm
@@ -29,3 +29,20 @@
(load-and-reexport (sw_engine)
(gnucash engine business-core)
(gnucash engine gnc-numeric))
+
+
+(export gnc:price-ref)
+
+(define price-guardian (make-guardian))
+
+(define (reclaim-prices)
+ (let ((price (price-guardian)))
+ (when price
+ (gnc-price-unref price)
+ (reclaim-prices))))
+
+(add-hook! after-gc-hook reclaim-prices)
+
+(define (gnc:price-ref price)
+ (gnc-price-ref price)
+ (price-guardian price))
diff --git a/gnucash/report/gnc-report.cpp b/gnucash/report/gnc-report.cpp
index e7b933675cb..5f057e51db9 100644
--- a/gnucash/report/gnc-report.cpp
+++ b/gnucash/report/gnc-report.cpp
@@ -221,6 +221,10 @@ gnc_run_report_with_error_handling (gint report_id, gchar ** data, gchar **errms
html = scm_car (res);
captured_error = scm_cadr (res);
+ /* Force a gc run after the report is finished to ensure that
+ guardians are called to unref objects */
+ scm_gc();
+
if (!scm_is_false (html))
{
*data = gnc_scm_to_utf8_string (html);
diff --git a/gnucash/report/reports/standard/advanced-portfolio.scm b/gnucash/report/reports/standard/advanced-portfolio.scm
index 4e259d12f0d..5e0c6c55696 100644
--- a/gnucash/report/reports/standard/advanced-portfolio.scm
+++ b/gnucash/report/reports/standard/advanced-portfolio.scm
@@ -331,7 +331,7 @@ by preventing negative stock balances.
")
(if (gnc-commodity-equiv currency (gnc-price-get-commodity p))
(set! price (gnc-price-invert p))))
price-list)
- (gnc-price-ref price)
+ (gnc:price-ref price)
(gnc-price-list-destroy price-list)
price)))
@@ -470,7 +470,6 @@ by preventing negative stock balances.
")
(if (not (gnc-numeric-zero-p (gnc:gnc-monetary-amount trans-price)))
;; We can exchange the price from this transaction into the report currency
(begin
- (if price (gnc-price-unref price))
(set! pricing-txn trans)
(set! price trans-price)
(gnc:debug "Transaction price is " (gnc:monetary->string price))
@@ -942,15 +941,9 @@ by preventing negative stock balances.
")
row-style
activecols)
- (if (and (not use-txn) price) (gnc-price-unref price))
(table-add-stock-rows-internal rest (not odd-row?))
)
- (begin
- (if (and (not use-txn) price) (gnc-price-unref price))
- (table-add-stock-rows-internal rest odd-row?)
- )
- )
- )))
+ (table-add-stock-rows-internal rest odd-row?)))))
(set! work-to-do (gnc:accounts-count-splits accounts))
(table-add-stock-rows-internal accounts #t)))
diff --git a/gnucash/report/reports/standard/portfolio.scm b/gnucash/report/reports/standard/portfolio.scm
index eb516b3a99c..8d9f2efaccb 100644
--- a/gnucash/report/reports/standard/portfolio.scm
+++ b/gnucash/report/reports/standard/portfolio.scm
@@ -143,10 +143,8 @@
"number-cell" value)))
;;(display (format #f "Shares: ~6d " (gnc-numeric-to-double units)))
;;(display units) (newline)
- (if price (gnc-price-unref price))
(table-add-stock-rows-internal rest (not odd-row?)))
- (begin (if price (gnc-price-unref price))
- (table-add-stock-rows-internal rest odd-row?))))))
+ (table-add-stock-rows-internal rest odd-row?)))))
(set! work-to-do (length accounts))
(table-add-stock-rows-internal accounts #t)))
@@ -211,7 +209,7 @@
(car price)
(gnc-price-invert (car price))))
(v (gnc-price-get-value the_price)))
- (gnc-price-ref (car price))
+ (gnc:price-ref (car price))
(cons (car price) v))
(cons #f (gnc-numeric-zero)))))
(if price (gnc-price-list-destroy price))
@@ -223,7 +221,7 @@
(cond
((null? price) (cons #f 0))
(else (let ((p (car price)))
- (gnc-price-ref p)
+ (gnc:price-ref p)
(gnc-price-list-destroy price)
(cons p (gnc-price-get-value p))))))))
((pricedb-nearest)
@@ -233,7 +231,7 @@
pricedb foreign (time64CanonicalDayTime date)))
(fn (if (and price (> (length price) 0))
(let* ((v (gnc-price-get-value (car price))))
- (gnc-price-ref (car price))
+ (gnc:price-ref (car price))
(cons (car price) v))
(cons #f (gnc-numeric-zero)))))
(if price (gnc-price-list-destroy price))