Skip to content

Commit

Permalink
fixup! gh-119333: Back up exception before calling PyContext_WatchCal…
Browse files Browse the repository at this point in the history
…lback

I changed my mind about where to back up and restore the exception.
Instead of backing up and restoring once outside the loop over the
registered callbacks, the exception is backed up and restored each
time a callback is called.

This avoids concerns about what happens if a callback raises an
exception but returns non-negative.

This is also expected to be more efficient, not less, because the
common case is no watchers at all, in which case there is no
backup/restore overhead.  The second most common case is one watcher,
which is no less efficient than before.  The only time this is more
expensive is when there are two or more watchers, in which case the
overhead of the watcher callbacks probably dwarfs the overhead of the
extra backups anyways.
  • Loading branch information
rhansen committed Sep 30, 2024
1 parent ffa8cc8 commit 212948c
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Python/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,23 @@ static void notify_context_watchers(PyContextEvent event, PyContext *ctx, PyThre
assert(interp->_initialized);
uint8_t bits = interp->active_context_watchers;
int i = 0;
PyObject *exc = _PyErr_GetRaisedException(ts);
while (bits) {
assert(i < CONTEXT_MAX_WATCHERS);
if (bits & 1) {
PyContext_WatchCallback cb = interp->context_watchers[i];
assert(cb != NULL);
PyObject *exc = _PyErr_GetRaisedException(ts);
cb(event, ctx);
if (_PyErr_Occurred(ts) != NULL) {
PyErr_FormatUnraisable(
"Exception ignored in %s watcher callback for %R",
context_event_name(event), ctx);
}
_PyErr_SetRaisedException(ts, exc);
}
i++;
bits >>= 1;
}
_PyErr_SetRaisedException(ts, exc);
}


Expand Down

0 comments on commit 212948c

Please sign in to comment.