Skip to content

Commit b97d337

Browse files
jpnurmiclaude
andcommitted
fix(sync): discard pending delayed tasks on shutdown
Move delayed task cleanup from the shutdown pre-prune pass into the worker thread itself. When the worker encounters a delayed task that is not yet ready and shutdown has been signaled, it discards all remaining tasks. This catches tasks submitted during execution that the one-time pre-prune in shutdown could not see. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a399d2a commit b97d337

2 files changed

Lines changed: 12 additions & 29 deletions

File tree

src/sentry_sync.c

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ worker_thread(void *data)
265265
{
266266
uint64_t now = sentry__monotonic_time();
267267
if (now < task->execute_after) {
268+
// discard delayed tasks submitted after shutdown pruning
269+
if (!sentry__atomic_fetch(&bgw->running)) {
270+
while (bgw->first_task) {
271+
sentry_bgworker_task_t *t = bgw->first_task;
272+
bgw->first_task = t->next_task;
273+
sentry__task_decref(t);
274+
}
275+
bgw->last_task = NULL;
276+
continue;
277+
}
268278
sentry__cond_wait_timeout(&bgw->submit_signal, &bgw->task_lock,
269279
(uint32_t)(task->execute_after - now));
270280
continue;
@@ -419,30 +429,6 @@ sentry__bgworker_shutdown(sentry_bgworker_t *bgw, uint64_t timeout)
419429

420430
uint64_t started = sentry__monotonic_time();
421431
sentry__mutex_lock(&bgw->task_lock);
422-
423-
// prune delayed tasks that exceed the shutdown timeout
424-
sentry_bgworker_task_t *prev = NULL;
425-
sentry_bgworker_task_t *cur = bgw->first_task;
426-
while (cur) {
427-
if (cur->execute_after > started + timeout) {
428-
if (prev) {
429-
prev->next_task = NULL;
430-
bgw->last_task = prev;
431-
} else {
432-
bgw->first_task = NULL;
433-
bgw->last_task = NULL;
434-
}
435-
while (cur) {
436-
sentry_bgworker_task_t *next = cur->next_task;
437-
sentry__task_decref(cur);
438-
cur = next;
439-
}
440-
break;
441-
}
442-
prev = cur;
443-
cur = cur->next_task;
444-
}
445-
446432
while (true) {
447433
if (sentry__bgworker_is_done(bgw)) {
448434
sentry__mutex_unlock(&bgw->task_lock);

tests/unit/test_sync.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,9 @@ SENTRY_TEST(bgworker_delayed_shutdown)
344344
sentry__bgworker_submit(bgw, record_order_task, NULL, (void *)2);
345345
sentry__bgworker_submit(bgw, record_order_task, NULL, (void *)3);
346346

347-
// short delay fits within shutdown deadline
347+
// delayed tasks are discarded on shutdown unless already ready
348348
sentry__bgworker_submit_delayed(
349349
bgw, record_order_task, NULL, (void *)4, 50);
350-
351-
// long delay exceeds shutdown deadline and should be pruned
352350
sentry__bgworker_submit_delayed(
353351
bgw, record_order_task, NULL, (void *)5, 5000);
354352
sentry__bgworker_submit_delayed(
@@ -357,11 +355,10 @@ SENTRY_TEST(bgworker_delayed_shutdown)
357355
sentry__bgworker_start(bgw);
358356
TEST_CHECK_INT_EQUAL(sentry__bgworker_shutdown(bgw, 1000), 0);
359357

360-
TEST_CHECK_INT_EQUAL(os.count, 4);
358+
TEST_CHECK_INT_EQUAL(os.count, 3);
361359
TEST_CHECK_INT_EQUAL(os.order[0], 1);
362360
TEST_CHECK_INT_EQUAL(os.order[1], 2);
363361
TEST_CHECK_INT_EQUAL(os.order[2], 3);
364-
TEST_CHECK_INT_EQUAL(os.order[3], 4);
365362

366363
sentry__bgworker_decref(bgw);
367364
}

0 commit comments

Comments
 (0)