diff --git a/lib/modules/Concurrent.pmod b/lib/modules/Concurrent.pmod index c8890522f0330751e2c99f73b225cf972f89c0a6..fc59be8116ba81fa78b05ae9981d588725fc538c 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;