From b22c04c6e8efc646592940ef4e06d54b730c8672 Mon Sep 17 00:00:00 2001
From: "Stephen R. van den Berg" <srb@cuci.nl>
Date: Sat, 16 May 2020 18:33:26 +0200
Subject: [PATCH] Concurrent: Add CONCURRENT_DEBUG to get more meaningful
 broken-promises.

---
 lib/modules/Concurrent.pmod | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/lib/modules/Concurrent.pmod b/lib/modules/Concurrent.pmod
index c8890522f0..fc59be8116 100644
--- a/lib/modules/Concurrent.pmod
+++ b/lib/modules/Concurrent.pmod
@@ -1,5 +1,9 @@
 #pike __REAL_VERSION__
 
+// Enable CONCURRENT_DEBUG to get more meaningful broken-promise messages
+
+#define CONCURRENT_DEBUG 0
+
 //! Module for handling multiple concurrent events.
 //!
 //! The @[Future] and @[Promise] API was inspired by
@@ -834,6 +838,9 @@ class Promise
 
   final int _materialised;
   final AggregateState _astate;
+#if CONCURRENT_DEBUG
+  array(Pike.BacktraceFrame) createdat;
+#endif
 
   //! Creates a new promise, optionally initialised from a traditional callback
   //! driven method via @expr{executor(success, failure, @@extra)@}.
@@ -844,6 +851,9 @@ class Promise
    function(function(mixed:void),
             function(mixed:void), mixed ...:void) executor, mixed ... extra)
   {
+#if CONCURRENT_DEBUG
+    createdat = backtrace()[..<1];
+#endif
     state = STATE_NO_FUTURE;
     if (executor)
       executor(success, failure, @extra);
@@ -1149,7 +1159,11 @@ class Promise
   {
     // NB: Don't complain about dropping STATE_NO_FUTURE on the floor.
     if (state == STATE_PENDING)
-      try_failure(({ sprintf("%O: Promise broken.\n", this), backtrace() }));
+      try_failure(({ sprintf("%O: Promise broken.\n", this),
+#if CONCURRENT_DEBUG
+                     this->createdat ||
+#endif
+                     backtrace() }));
     if ((state == STATE_REJECTED) && global_on_failure)
       call_callback(global_on_failure, result);
     result = UNDEFINED;
-- 
GitLab