Skip to content

Commit 9f4d0e4

Browse files
Merge pull request NoiseByNorthwest#278 from NoiseByNorthwest/fix_258
Make Zend MM custom handler state thread-local
2 parents dedb474 + f36d431 commit 9f4d0e4

File tree

1 file changed

+46
-40
lines changed

1 file changed

+46
-40
lines changed

src/spx_php.c

Lines changed: 46 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,17 @@ static struct {
135125
NULL
136126
};
137127

128+
#if ZEND_MODULE_API_NO >= 20151012
129+
static SPX_THREAD_TLS struct {
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+
} ze_tls_hooked_func = {
135+
NULL, NULL, NULL, NULL
136+
};
137+
#endif
138+
138139
static SPX_THREAD_TLS struct {
139140
struct {
140141
struct {
@@ -664,24 +665,28 @@ void spx_php_execution_init(void)
664665
#if ZEND_MODULE_API_NO >= 20151012
665666
zend_mm_heap * ze_mm_heap = zend_mm_get_heap();
666667

668+
/*
669+
* FIXME document why we need ze_mm_custom_block_size instead of ze_mm_block_size
670+
* when there is no previous MM custom handler.
671+
*/
672+
ze_tls_hooked_func.block_size = ze_mm_custom_block_size;
673+
667674
zend_mm_get_custom_handlers(
668675
ze_mm_heap,
669-
&ze_hooked_func.malloc,
670-
&ze_hooked_func.free,
671-
&ze_hooked_func.realloc
676+
&ze_tls_hooked_func.malloc,
677+
&ze_tls_hooked_func.free,
678+
&ze_tls_hooked_func.realloc
672679
);
673680

674-
ze_hooked_func.block_size = ze_mm_custom_block_size;
675-
676681
if (
677-
!ze_hooked_func.malloc
678-
|| !ze_hooked_func.free
679-
|| !ze_hooked_func.realloc
682+
!ze_tls_hooked_func.malloc
683+
|| !ze_tls_hooked_func.free
684+
|| !ze_tls_hooked_func.realloc
680685
) {
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;
686+
ze_tls_hooked_func.malloc = ze_mm_malloc;
687+
ze_tls_hooked_func.free = ze_mm_free;
688+
ze_tls_hooked_func.realloc = ze_mm_realloc;
689+
ze_tls_hooked_func.block_size = ze_mm_block_size;
685690
}
686691

687692
zend_mm_set_custom_handlers(
@@ -697,24 +702,24 @@ void spx_php_execution_shutdown(void)
697702
{
698703
#if ZEND_MODULE_API_NO >= 20151012
699704
if (
700-
ze_hooked_func.malloc
701-
&& ze_hooked_func.free
702-
&& ze_hooked_func.realloc
705+
ze_tls_hooked_func.malloc
706+
&& ze_tls_hooked_func.free
707+
&& ze_tls_hooked_func.realloc
703708
) {
704709
zend_mm_heap * ze_mm_heap = zend_mm_get_heap();
705710

706711
if (
707712
/*
708-
* ze_hooked_func.malloc was defaulted to ze_mm_malloc only if there were no
713+
* ze_tls_hooked_func.malloc was defaulted to ze_mm_malloc only if there were no
709714
* previous custom handlers.
710715
*/
711-
ze_hooked_func.malloc != ze_mm_malloc
716+
ze_tls_hooked_func.malloc != ze_mm_malloc
712717
) {
713718
zend_mm_set_custom_handlers(
714719
ze_mm_heap,
715-
ze_hooked_func.malloc,
716-
ze_hooked_func.free,
717-
ze_hooked_func.realloc
720+
ze_tls_hooked_func.malloc,
721+
ze_tls_hooked_func.free,
722+
ze_tls_hooked_func.realloc
718723
);
719724
} else {
720725
/*
@@ -733,9 +738,10 @@ void spx_php_execution_shutdown(void)
733738
}
734739
}
735740

736-
ze_hooked_func.malloc = NULL;
737-
ze_hooked_func.free = NULL;
738-
ze_hooked_func.realloc = NULL;
741+
ze_tls_hooked_func.malloc = NULL;
742+
ze_tls_hooked_func.free = NULL;
743+
ze_tls_hooked_func.realloc = NULL;
744+
ze_tls_hooked_func.block_size = NULL;
739745
}
740746
#endif
741747

@@ -1013,11 +1019,11 @@ static void * ze_mm_realloc(void * ptr, size_t size)
10131019

10141020
static void * tls_hook_malloc(size_t size)
10151021
{
1016-
void * ptr = ze_hooked_func.malloc(size);
1022+
void * ptr = ze_tls_hooked_func.malloc(size);
10171023

10181024
if (ptr) {
10191025
context.alloc_count++;
1020-
context.alloc_bytes += ze_hooked_func.block_size(ptr);
1026+
context.alloc_bytes += ze_tls_hooked_func.block_size(ptr);
10211027
}
10221028

10231029
return ptr;
@@ -1027,17 +1033,17 @@ static void tls_hook_free(void * ptr)
10271033
{
10281034
if (ptr) {
10291035
context.free_count++;
1030-
context.free_bytes += ze_hooked_func.block_size(ptr);
1036+
context.free_bytes += ze_tls_hooked_func.block_size(ptr);
10311037
}
10321038

1033-
ze_hooked_func.free(ptr);
1039+
ze_tls_hooked_func.free(ptr);
10341040
}
10351041

10361042
static void * tls_hook_realloc(void * ptr, size_t size)
10371043
{
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;
1044+
const size_t old_size = ptr ? ze_tls_hooked_func.block_size(ptr) : 0;
1045+
void * new = ze_tls_hooked_func.realloc(ptr, size);
1046+
const size_t new_size = new ? ze_tls_hooked_func.block_size(new) : 0;
10411047

10421048
if (ptr && new) {
10431049
if (ptr != new) {

0 commit comments

Comments
 (0)