Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libuv_reactor.c
Original file line number Diff line number Diff line change
Expand Up @@ -7161,4 +7161,8 @@ void async_libuv_reactor_register(void)
async_thread_transfer_zval, async_thread_load_zval,
async_thread_release_transferred_zval,
async_thread_xlat_put_ctx, async_thread_defer_release_ctx);

/* Batched multi-root release (one visited set). Additive; set directly rather
* than widening zend_async_thread_pool_register's signature. */
zend_async_thread_release_transferred_zvals_fn = async_thread_release_transferred_zvals;
}
14 changes: 14 additions & 0 deletions thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,20 @@ void async_thread_release_transferred_zval(zval *z)
ZVAL_UNDEF(z);
}

/* One release ctx (one visited set) across all roots — unlike the single-zval call,
* which builds a fresh set each time — so an object xlat-deduped into more than one
* root is freed once. Contract and rationale: the typedef in zend_async_API.h. */
void async_thread_release_transferred_zvals(zval **roots, size_t count)
{
thread_release_ctx_t ctx;
thread_release_ctx_init(&ctx);
for (size_t i = 0; i < count; i++) {
thread_release_transferred_zval(&ctx, roots[i]);
ZVAL_UNDEF(roots[i]);
}
thread_release_ctx_destroy(&ctx);
}

/* Partial-release for build-error paths: refcount-based so xlat-shared
* sub-pieces still owned by the half-built snapshot survive; the snapshot's
* full release frees them shortly afterwards. */
Expand Down
1 change: 1 addition & 0 deletions thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ void async_thread_load_zval(zval *dst, const zval *src);
* Free a persistent zval created by async_thread_transfer_zval().
*/
void async_thread_release_transferred_zval(zval *z);
void async_thread_release_transferred_zvals(zval **roots, size_t count);

/* Recursion helpers passed to zend_async_thread_pool_register() — expose
* thread_transfer_zval_inner / thread_load_zval_inner / xlat_put / a lazy
Expand Down
Loading