Skip to content

Commit 28530c8

Browse files
committed
Merge branch 'true-async-api' into true-async-api-stable
2 parents 6e955d2 + 9d59043 commit 28530c8

File tree

5 files changed

+57
-14
lines changed

5 files changed

+57
-14
lines changed

Zend/zend_async_API.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,13 @@ void zend_async_globals_dtor(void)
197197
#endif
198198
}
199199

200-
void zend_async_shutdown(void)
200+
void zend_async_api_shutdown(void)
201201
{
202-
zend_async_globals_dtor();
203202
zend_async_internal_context_api_shutdown();
204203
zend_async_main_handlers_shutdown();
204+
#ifndef ZTS
205+
zend_async_globals_dtor();
206+
#endif
205207
}
206208

207209
ZEND_API int zend_async_get_api_version_number(void)

Zend/zend_async_API.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,30 @@ struct _zend_async_event_callback_s {
363363
zend_async_event_callback_dispose_fn dispose;
364364
};
365365

366+
#define ZEND_ASYNC_EVENT_CALLBACK_ADD_REF(callback) \
367+
if (callback != NULL) { \
368+
callback->ref_count++; \
369+
}
370+
371+
//
372+
// For a callback,
373+
// it’s crucial that the reference count is always greater than zero,
374+
// because a value of zero is a special case triggered from a destructor.
375+
// If you need to “retain” ownership of the object,
376+
// you **MUST** use either this macro or ZEND_ASYNC_EVENT_CALLBACK_RELEASE.
377+
//
378+
#define ZEND_ASYNC_EVENT_CALLBACK_DEC_REF(callback) \
379+
if(callback != NULL && callback->ref_count > 1) { \
380+
callback->ref_count--; \
381+
}
382+
383+
#define ZEND_ASYNC_EVENT_CALLBACK_RELEASE(callback) \
384+
if (callback != NULL && callback->ref_count > 1) { \
385+
callback->ref_count--; \
386+
} else { \
387+
coroutine_event_callback_dispose(callback, NULL); \
388+
}
389+
366390
struct _zend_coroutine_event_callback_s {
367391
zend_async_event_callback_t base;
368392
zend_coroutine_t *coroutine;
@@ -1111,7 +1135,7 @@ ZEND_API bool zend_async_is_enabled(void);
11111135
ZEND_API bool zend_scheduler_is_enabled(void);
11121136

11131137
void zend_async_init(void);
1114-
void zend_async_shutdown(void);
1138+
void zend_async_api_shutdown(void);
11151139
void zend_async_globals_ctor(void);
11161140
void zend_async_globals_dtor(void);
11171141

@@ -1352,6 +1376,9 @@ END_EXTERN_C()
13521376
* @param priority Priority level for the exception-throwing coroutine
13531377
*/
13541378
#define ZEND_ASYNC_SPAWN_AND_THROW(exception, scope, priority) zend_async_spawn_and_throw_fn(exception, scope, priority)
1379+
/**
1380+
* The API method initiates graceful shutdown mode.
1381+
*/
13551382
#define ZEND_ASYNC_SHUTDOWN() zend_async_shutdown_fn()
13561383
#define ZEND_ASYNC_ENGINE_SHUTDOWN() zend_async_engine_shutdown_fn()
13571384
#define ZEND_ASYNC_GET_COROUTINES() zend_async_get_coroutines_fn()

Zend/zend_fibers.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,11 +461,14 @@ ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
461461
{
462462
zend_observer_fiber_destroy_notify(context);
463463

464+
// This code allows freeing the memory of the context independently of the stack memory.
465+
zend_fiber_stack *stack = context->stack;
466+
464467
if (context->cleanup) {
465468
context->cleanup(context);
466469
}
467470

468-
zend_fiber_stack_free(context->stack);
471+
zend_fiber_stack_free(stack);
469472
}
470473

471474
ZEND_API void zend_fiber_switch_context(zend_fiber_transfer *transfer)

Zend/zend_gc.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,8 +2034,10 @@ static void zend_gc_collect_cycles_coroutine(void)
20342034
}
20352035

20362036
if (GC_G(microtask) != NULL) {
2037-
GC_G(microtask)->is_cancelled = true;
2038-
ZEND_ASYNC_MICROTASK_RELEASE(GC_G(microtask));
2037+
zend_async_microtask_t *microtask = GC_G(microtask);
2038+
GC_G(microtask) = NULL;
2039+
microtask->is_cancelled = true;
2040+
ZEND_ASYNC_MICROTASK_RELEASE(microtask);
20392041
}
20402042
}
20412043

@@ -2066,8 +2068,10 @@ static void coroutine_dispose(zend_coroutine_t *coroutine)
20662068
GC_G(dtor_scope) = NULL;
20672069

20682070
if (GC_G(microtask) != NULL) {
2069-
GC_G(microtask)->is_cancelled = true;
2070-
zend_gc_collect_cycles_microtask_dtor(GC_G(microtask));
2071+
zend_async_microtask_t *microtask = GC_G(microtask);
2072+
GC_G(microtask) = NULL;
2073+
microtask->is_cancelled = true;
2074+
ZEND_ASYNC_MICROTASK_RELEASE(microtask);
20712075
}
20722076

20732077
if (GC_G(gc_stack) != NULL) {
@@ -2150,6 +2154,8 @@ ZEND_API int zend_gc_collect_cycles(void)
21502154

21512155
#endif
21522156

2157+
zend_hrtime_t dtor_start_time = 0;
2158+
21532159
#ifdef PHP_ASYNC_API
21542160
#define GC_COLLECT_TOTAL_COUNT (context->total_count)
21552161
#define GC_COLLECT_COUNT (context->count)
@@ -2181,6 +2187,7 @@ ZEND_API int zend_gc_collect_cycles(void)
21812187
// so we continue the process from the next element.
21822188
GC_G(async_context).state = GC_ASYNC_STATE_RUNNING;
21832189
GC_G(dtor_idx)++;
2190+
dtor_start_time = zend_hrtime();
21842191
goto continue_calling_destructors;
21852192
} else {
21862193
context->state = GC_ASYNC_STATE_INIT;
@@ -2231,7 +2238,10 @@ ZEND_API int zend_gc_collect_cycles(void)
22312238
zend_refcounted *p;
22322239
uint32_t gc_flags = 0;
22332240
uint32_t idx, end;
2234-
#ifndef PHP_ASYNC_API
2241+
#ifdef PHP_ASYNC_API
2242+
stack->next = NULL;
2243+
stack->prev = NULL;
2244+
#else
22352245
int count;
22362246
gc_stack stack;
22372247
stack.prev = NULL;
@@ -2314,7 +2324,7 @@ ZEND_API int zend_gc_collect_cycles(void)
23142324
}
23152325

23162326
/* Actually call destructors. */
2317-
zend_hrtime_t dtor_start_time = zend_hrtime();
2327+
dtor_start_time = zend_hrtime();
23182328
if (EXPECTED(!EG(active_fiber))) {
23192329
#ifdef PHP_ASYNC_API
23202330
continue_calling_destructors:
@@ -2344,7 +2354,7 @@ ZEND_API int zend_gc_collect_cycles(void)
23442354
}
23452355
}
23462356

2347-
GC_COLLECT_FREE_STACK;
2357+
gc_stack_free(GC_COLLECT_STACK);
23482358

23492359
#ifdef PHP_ASYNC_API
23502360
end = GC_G(first_unused);

main/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,12 +2515,13 @@ void php_module_shutdown(void)
25152515

25162516
module_initialized = false;
25172517

2518+
#ifdef PHP_ASYNC_API
2519+
zend_async_api_shutdown();
2520+
#endif
2521+
25182522
#ifndef ZTS
25192523
core_globals_dtor(&core_globals);
25202524
gc_globals_dtor();
2521-
#ifdef PHP_ASYNC_API
2522-
zend_async_globals_dtor();
2523-
#endif
25242525
#else
25252526
ts_free_id(core_globals_id);
25262527
#endif

0 commit comments

Comments
 (0)