From b29c54505a93365441fa140b152a651c3b9324c2 Mon Sep 17 00:00:00 2001 From: Danack Date: Tue, 30 Jul 2019 15:20:15 +0100 Subject: [PATCH] Add ini settings to work around segfault. Added the 'imagick.shutdown_sleep_count' (default 10) and 'imagick.set_single_thread' (default Off) to work around a segfault in OpenMP. --- imagick.c | 22 ++++++++++++- package.xml | 5 +++ php_imagick_defs.h | 4 +++ tests/281_ini_settings_default.phpt | 29 ++++++++++++++++ tests/282_ini_settings_set_falsy_string.phpt | 33 +++++++++++++++++++ tests/283_ini_settings_set_falsy_zero.phpt | 33 +++++++++++++++++++ tests/284_ini_settings_set_truthy_number.phpt | 33 +++++++++++++++++++ tests/285_ini_settings_set_truthy_string.phpt | 33 +++++++++++++++++++ 8 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 tests/281_ini_settings_default.phpt create mode 100644 tests/282_ini_settings_set_falsy_string.phpt create mode 100644 tests/283_ini_settings_set_falsy_zero.phpt create mode 100644 tests/284_ini_settings_set_truthy_number.phpt create mode 100644 tests/285_ini_settings_set_truthy_string.phpt diff --git a/imagick.c b/imagick.c index 8e58afe..be6b303 100644 --- a/imagick.c +++ b/imagick.c @@ -3262,6 +3262,10 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("imagick.locale_fix", "0", PHP_INI_ALL, OnUpdateBool, locale_fix, zend_imagick_globals, imagick_globals) STD_PHP_INI_ENTRY("imagick.skip_version_check", "0", PHP_INI_ALL, OnUpdateBool, skip_version_check, zend_imagick_globals, imagick_globals) STD_PHP_INI_ENTRY("imagick.progress_monitor", "0", PHP_INI_SYSTEM, OnUpdateBool, progress_monitor, zend_imagick_globals, imagick_globals) + + STD_PHP_INI_ENTRY("imagick.set_single_thread", "0", PHP_INI_SYSTEM, OnUpdateBool, set_single_thread, zend_imagick_globals, imagick_globals) + STD_PHP_INI_ENTRY("imagick.shutdown_sleep_count", "10", PHP_INI_ALL, OnUpdateLong, shutdown_sleep_count, zend_imagick_globals, imagick_globals) + PHP_INI_END() static void php_imagick_init_globals(zend_imagick_globals *imagick_globals) @@ -3269,6 +3273,9 @@ static void php_imagick_init_globals(zend_imagick_globals *imagick_globals) imagick_globals->locale_fix = 0; imagick_globals->progress_monitor = 0; imagick_globals->skip_version_check = 0; + imagick_globals->set_single_thread = 0; + // 10 is magick number, that seems to be enough. + imagick_globals->shutdown_sleep_count = 10; } @@ -3748,6 +3755,10 @@ PHP_MINIT_FUNCTION(imagick) checkImagickVersion(); } + if (IMAGICK_G(set_single_thread)) { + MagickSetResourceLimit(ThreadResource, 1); + } + return SUCCESS; } @@ -3824,12 +3835,21 @@ PHP_MINFO_FUNCTION(imagick) PHP_MSHUTDOWN_FUNCTION(imagick) { + int i; + // This suppresses an 'unused parameter' warning. (void)type; - MagickWandTerminus(); + // Sleep for a bit to hopefully allow OpenMP to + // shut down the threads it created, and avoid a segfault + // This hack won't be needed once everyone is compiling ImageMagick + // against a version of OpenMP that has omp_pause_resource_all() + for (i = 0; i < 100 && i < IMAGICK_G(shutdown_sleep_count); i += 1) { + usleep(1000); + } + #if defined(ZTS) && defined(PHP_WIN32) tsrm_mutex_free(imagick_mutex); #endif diff --git a/php_imagick_defs.h b/php_imagick_defs.h index 5eb57e5..dbc9c52 100644 --- a/php_imagick_defs.h +++ b/php_imagick_defs.h @@ -83,6 +83,10 @@ ZEND_BEGIN_MODULE_GLOBALS(imagick) zend_bool locale_fix; zend_bool progress_monitor; zend_bool skip_version_check; + + zend_bool set_single_thread; + zend_long shutdown_sleep_count; + php_imagick_callback *progress_callback; #ifdef PHP_IMAGICK_ZEND_MM MagickWand *keep_alive; diff --git a/tests/281_ini_settings_default.phpt b/tests/281_ini_settings_default.phpt new file mode 100644 index 0000000..e397e98 --- /dev/null +++ b/tests/281_ini_settings_default.phpt @@ -0,0 +1,29 @@ +--TEST-- +OpenMP segfault hacks +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Complete diff --git a/tests/282_ini_settings_set_falsy_string.phpt b/tests/282_ini_settings_set_falsy_string.phpt new file mode 100644 index 0000000..c5f6bfd --- /dev/null +++ b/tests/282_ini_settings_set_falsy_string.phpt @@ -0,0 +1,33 @@ +--TEST-- +OpenMP segfault hacks + +--INI-- +imagick.shutdown_sleep_count=Off +imagick.set_single_thread=0 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Complete diff --git a/tests/283_ini_settings_set_falsy_zero.phpt b/tests/283_ini_settings_set_falsy_zero.phpt new file mode 100644 index 0000000..8e41a35 --- /dev/null +++ b/tests/283_ini_settings_set_falsy_zero.phpt @@ -0,0 +1,33 @@ +--TEST-- +OpenMP segfault hacks + +--INI-- +imagick.shutdown_sleep_count=0 +imagick.set_single_thread=0 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Complete diff --git a/tests/284_ini_settings_set_truthy_number.phpt b/tests/284_ini_settings_set_truthy_number.phpt new file mode 100644 index 0000000..fc0a0bb --- /dev/null +++ b/tests/284_ini_settings_set_truthy_number.phpt @@ -0,0 +1,33 @@ +--TEST-- +OpenMP segfault hacks + +--INI-- +imagick.shutdown_sleep_count=20 +imagick.set_single_thread=1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Complete diff --git a/tests/285_ini_settings_set_truthy_string.phpt b/tests/285_ini_settings_set_truthy_string.phpt new file mode 100644 index 0000000..c35a213 --- /dev/null +++ b/tests/285_ini_settings_set_truthy_string.phpt @@ -0,0 +1,33 @@ +--TEST-- +OpenMP segfault hacks + +--INI-- +imagick.shutdown_sleep_count=On +imagick.set_single_thread=On +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Complete