Skip to content

Commit a72dee6

Browse files
committed
Avoid recursive use of signal blocking macros in ZendAccelerator.c
1 parent 9f6d44e commit a72dee6

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

Zend/zend.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,15 @@ ZEND_API void zend_debug_mask_signals()
7878
}
7979
ZEND_API void zend_debug_unmask_signals()
8080
{
81-
if (--_signals_masked)
82-
zend_error_noreturn(E_ERROR, "Cannot nest ZEND_SIGNAL_BLOCK_INTERRUPTIONS; it is not re-entrant");
81+
if (--_signals_masked) {
82+
zend_error_noreturn(E_ERROR, "Cannot nest HANDLE_BLOCK_INTERRUPTIONS; it is not re-entrant");
83+
}
84+
}
85+
ZEND_API void zend_debug_ensure_signals_masked()
86+
{
87+
if (!_signals_masked) {
88+
zend_error_noreturn(E_ERROR, "Must block signals using HANDLE_BLOCK_INTERRUPTIONS");
89+
}
8390
}
8491
# endif
8592
#endif

Zend/zend_signal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ extern sigset_t mask_all_signals;
2626
# if ZEND_DEBUG
2727
ZEND_API void zend_debug_mask_signals();
2828
ZEND_API void zend_debug_unmask_signals();
29+
ZEND_API void zend_debug_ensure_signals_masked();
2930
# else
3031
# define zend_debug_mask_signals() do {} while (0)
3132
# define zend_debug_unmask_signals() do {} while (0)
33+
# define zend_debug_ensure_signals_masked() do {} while (0)
3234
# endif
3335

3436
# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() \
@@ -55,6 +57,7 @@ ZEND_API void zend_debug_unmask_signals();
5557

5658
# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() do {} while(0)
5759
# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() do {} while(0)
60+
# define zend_debug_ensure_signals_masked() do {} while(0)
5861

5962
#endif /* HAVE_SIGPROCMASK */
6063
#endif /* ZEND_SIGNAL_H */

ext/opcache/ZendAccelerator.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,7 +2131,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21312131
if (ZSMMG(memory_exhausted)) {
21322132
zend_accel_restart_reason reason =
21332133
zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
2134+
HANDLE_BLOCK_INTERRUPTIONS();
21342135
zend_accel_schedule_restart_if_necessary(reason);
2136+
HANDLE_UNBLOCK_INTERRUPTIONS();
21352137
}
21362138
}
21372139
zend_shared_alloc_unlock();
@@ -2156,7 +2158,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21562158
if (ZSMMG(memory_exhausted)) {
21572159
zend_accel_restart_reason reason =
21582160
zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
2161+
HANDLE_BLOCK_INTERRUPTIONS();
21592162
zend_accel_schedule_restart_if_necessary(reason);
2163+
HANDLE_UNBLOCK_INTERRUPTIONS();
21602164
}
21612165
}
21622166
zend_shared_alloc_unlock();
@@ -3227,7 +3231,9 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason)
32273231
zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled! Reason: %s",
32283232
zend_accel_restart_reason_text[reason]);
32293233

3230-
HANDLE_BLOCK_INTERRUPTIONS();
3234+
/* This function must be called with signals blocked */
3235+
zend_debug_ensure_signals_masked();
3236+
32313237
SHM_UNPROTECT();
32323238
ZCSG(restart_pending) = 1;
32333239
ZCSG(restart_reason) = reason;
@@ -3240,7 +3246,6 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason)
32403246
ZCSG(force_restart_time) = 0;
32413247
}
32423248
SHM_PROTECT();
3243-
HANDLE_UNBLOCK_INTERRUPTIONS();
32443249
}
32453250

32463251
/* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */

0 commit comments

Comments
 (0)