Skip to content

Commit 9104d5f

Browse files
matyhtfcjavad
authored andcommitted
Save and restore serialized and deserialized global variables during coroutine switching
1 parent d5cd793 commit 9104d5f

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

ext-src/php_swoole_coroutine.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ struct PHPContext {
6868
/* for array_walk non-reentrancy */
6969
zend::Function *array_walk_fci;
7070
#endif
71+
/*
72+
* for var serialize/unserialize,
73+
* coroutine switching may occur in the __sleep/__wakeup magic method of the object
74+
*/
75+
unsigned serialize_lock;
76+
struct {
77+
struct php_serialize_data *data;
78+
unsigned level;
79+
} serialize;
80+
struct {
81+
struct php_unserialize_data *data;
82+
unsigned level;
83+
} unserialize;
7184
/* for error control `@` */
7285
bool in_silence;
7386
bool enable_scheduler;
@@ -279,6 +292,8 @@ class PHPCoroutine {
279292
static void restore_vm_stack(PHPContext *ctx);
280293
static void save_og(PHPContext *ctx);
281294
static void restore_og(PHPContext *ctx);
295+
static void save_bg(PHPContext *ctx);
296+
static void restore_bg(PHPContext *ctx);
282297
static void save_context(PHPContext *ctx);
283298
static void restore_context(PHPContext *ctx);
284299
static void destroy_context(PHPContext *ctx);

ext-src/swoole_coroutine.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swoole_signal.h"
2626

2727
#include "zend_builtin_functions.h"
28+
#include "ext/standard/basic_functions.h"
2829
#include "ext/spl/spl_array.h"
2930

3031
#ifdef SWOOLE_COROUTINE_MOCK_FIBER_CONTEXT
@@ -585,6 +586,30 @@ inline void PHPCoroutine::restore_og(PHPContext *ctx) {
585586
}
586587
}
587588

589+
void PHPCoroutine::save_bg(PHPContext *ctx) {
590+
if (BG(serialize_lock)) {
591+
ctx->serialize_lock = BG(serialize_lock);
592+
}
593+
if (BG(serialize).data) {
594+
memcpy(&ctx->serialize, &BG(serialize), sizeof(BG(serialize)));
595+
}
596+
if (BG(unserialize).data) {
597+
memcpy(&ctx->unserialize, &BG(unserialize), sizeof(BG(unserialize)));
598+
}
599+
}
600+
601+
void PHPCoroutine::restore_bg(PHPContext *ctx) {
602+
if (ctx->serialize_lock) {
603+
BG(serialize_lock) = ctx->serialize_lock;
604+
}
605+
if (ctx->serialize.data) {
606+
memcpy(&BG(serialize), &ctx->serialize, sizeof(BG(serialize)));
607+
}
608+
if (ctx->unserialize.data) {
609+
memcpy(&BG(unserialize), &ctx->unserialize, sizeof(BG(unserialize)));
610+
}
611+
}
612+
588613
void PHPCoroutine::set_hook_flags(uint32_t flags) {
589614
zval options;
590615
array_init(&options);
@@ -603,11 +628,13 @@ void PHPCoroutine::set_hook_flags(uint32_t flags) {
603628
void PHPCoroutine::save_context(PHPContext *ctx) {
604629
save_vm_stack(ctx);
605630
save_og(ctx);
631+
save_bg(ctx);
606632
}
607633

608634
void PHPCoroutine::restore_context(PHPContext *ctx) {
609635
restore_vm_stack(ctx);
610636
restore_og(ctx);
637+
restore_bg(ctx);
611638
}
612639

613640
void PHPCoroutine::on_yield(void *arg) {

0 commit comments

Comments
 (0)