Skip to content

Commit b8dc02a

Browse files
Make Zend MM custom handler state thread-local
1 parent dedb474 commit b8dc02a

File tree

1 file changed

+52
-40
lines changed

1 file changed

+52
-40
lines changed

src/spx_php.c

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,6 @@ typedef void (*execute_internal_func_t) (
7474
);
7575

7676
static struct {
77-
#if ZEND_MODULE_API_NO >= 20151012
78-
void * (*malloc) (size_t size);
79-
void (*free) (void * ptr);
80-
void * (*realloc) (void * ptr, size_t size);
81-
size_t (*block_size) (void * ptr);
82-
#endif
83-
8477
#if ZEND_MODULE_API_NO < 20121212
8578
void (*execute) (zend_op_array * op_array TSRMLS_DC);
8679
#else
@@ -124,9 +117,6 @@ static struct {
124117
#endif
125118
);
126119
} ze_hooked_func = {
127-
#if ZEND_MODULE_API_NO >= 20151012
128-
NULL, NULL, NULL, NULL,
129-
#endif
130120
NULL, NULL, NULL,
131121
NULL, NULL,
132122
#if ZEND_MODULE_API_NO >= 20151012
@@ -135,6 +125,23 @@ static struct {
135125
NULL
136126
};
137127

128+
static SPX_THREAD_TLS struct {
129+
#if ZEND_MODULE_API_NO >= 20151012
130+
void * (*malloc) (size_t size);
131+
void (*free) (void * ptr);
132+
void * (*realloc) (void * ptr, size_t size);
133+
size_t (*block_size) (void * ptr);
134+
#else
135+
int unused;
136+
#endif
137+
} ze_tls_hooked_func = {
138+
#if ZEND_MODULE_API_NO >= 20151012
139+
NULL, NULL, NULL, NULL
140+
#else
141+
0
142+
#endif
143+
};
144+
138145
static SPX_THREAD_TLS struct {
139146
struct {
140147
struct {
@@ -664,24 +671,28 @@ void spx_php_execution_init(void)
664671
#if ZEND_MODULE_API_NO >= 20151012
665672
zend_mm_heap * ze_mm_heap = zend_mm_get_heap();
666673

674+
/*
675+
* FIXME document why we need ze_mm_custom_block_size instead of ze_mm_block_size
676+
* when there is no previous MM custom handler.
677+
*/
678+
ze_tls_hooked_func.block_size = ze_mm_custom_block_size;
679+
667680
zend_mm_get_custom_handlers(
668681
ze_mm_heap,
669-
&ze_hooked_func.malloc,
670-
&ze_hooked_func.free,
671-
&ze_hooked_func.realloc
682+
&ze_tls_hooked_func.malloc,
683+
&ze_tls_hooked_func.free,
684+
&ze_tls_hooked_func.realloc
672685
);
673686

674-
ze_hooked_func.block_size = ze_mm_custom_block_size;
675-
676687
if (
677-
!ze_hooked_func.malloc
678-
|| !ze_hooked_func.free
679-
|| !ze_hooked_func.realloc
688+
!ze_tls_hooked_func.malloc
689+
|| !ze_tls_hooked_func.free
690+
|| !ze_tls_hooked_func.realloc
680691
) {
681-
ze_hooked_func.malloc = ze_mm_malloc;
682-
ze_hooked_func.free = ze_mm_free;
683-
ze_hooked_func.realloc = ze_mm_realloc;
684-
ze_hooked_func.block_size = ze_mm_block_size;
692+
ze_tls_hooked_func.malloc = ze_mm_malloc;
693+
ze_tls_hooked_func.free = ze_mm_free;
694+
ze_tls_hooked_func.realloc = ze_mm_realloc;
695+
ze_tls_hooked_func.block_size = ze_mm_block_size;
685696
}
686697

687698
zend_mm_set_custom_handlers(
@@ -697,24 +708,24 @@ void spx_php_execution_shutdown(void)
697708
{
698709
#if ZEND_MODULE_API_NO >= 20151012
699710
if (
700-
ze_hooked_func.malloc
701-
&& ze_hooked_func.free
702-
&& ze_hooked_func.realloc
711+
ze_tls_hooked_func.malloc
712+
&& ze_tls_hooked_func.free
713+
&& ze_tls_hooked_func.realloc
703714
) {
704715
zend_mm_heap * ze_mm_heap = zend_mm_get_heap();
705716

706717
if (
707718
/*
708-
* ze_hooked_func.malloc was defaulted to ze_mm_malloc only if there were no
719+
* ze_tls_hooked_func.malloc was defaulted to ze_mm_malloc only if there were no
709720
* previous custom handlers.
710721
*/
711-
ze_hooked_func.malloc != ze_mm_malloc
722+
ze_tls_hooked_func.malloc != ze_mm_malloc
712723
) {
713724
zend_mm_set_custom_handlers(
714725
ze_mm_heap,
715-
ze_hooked_func.malloc,
716-
ze_hooked_func.free,
717-
ze_hooked_func.realloc
726+
ze_tls_hooked_func.malloc,
727+
ze_tls_hooked_func.free,
728+
ze_tls_hooked_func.realloc
718729
);
719730
} else {
720731
/*
@@ -733,9 +744,10 @@ void spx_php_execution_shutdown(void)
733744
}
734745
}
735746

736-
ze_hooked_func.malloc = NULL;
737-
ze_hooked_func.free = NULL;
738-
ze_hooked_func.realloc = NULL;
747+
ze_tls_hooked_func.malloc = NULL;
748+
ze_tls_hooked_func.free = NULL;
749+
ze_tls_hooked_func.realloc = NULL;
750+
ze_tls_hooked_func.block_size = NULL;
739751
}
740752
#endif
741753

@@ -1013,11 +1025,11 @@ static void * ze_mm_realloc(void * ptr, size_t size)
10131025

10141026
static void * tls_hook_malloc(size_t size)
10151027
{
1016-
void * ptr = ze_hooked_func.malloc(size);
1028+
void * ptr = ze_tls_hooked_func.malloc(size);
10171029

10181030
if (ptr) {
10191031
context.alloc_count++;
1020-
context.alloc_bytes += ze_hooked_func.block_size(ptr);
1032+
context.alloc_bytes += ze_tls_hooked_func.block_size(ptr);
10211033
}
10221034

10231035
return ptr;
@@ -1027,17 +1039,17 @@ static void tls_hook_free(void * ptr)
10271039
{
10281040
if (ptr) {
10291041
context.free_count++;
1030-
context.free_bytes += ze_hooked_func.block_size(ptr);
1042+
context.free_bytes += ze_tls_hooked_func.block_size(ptr);
10311043
}
10321044

1033-
ze_hooked_func.free(ptr);
1045+
ze_tls_hooked_func.free(ptr);
10341046
}
10351047

10361048
static void * tls_hook_realloc(void * ptr, size_t size)
10371049
{
1038-
const size_t old_size = ptr ? ze_hooked_func.block_size(ptr) : 0;
1039-
void * new = ze_hooked_func.realloc(ptr, size);
1040-
const size_t new_size = new ? ze_hooked_func.block_size(new) : 0;
1050+
const size_t old_size = ptr ? ze_tls_hooked_func.block_size(ptr) : 0;
1051+
void * new = ze_tls_hooked_func.realloc(ptr, size);
1052+
const size_t new_size = new ? ze_tls_hooked_func.block_size(new) : 0;
10411053

10421054
if (ptr && new) {
10431055
if (ptr != new) {

0 commit comments

Comments
 (0)