diff --git a/src/FFI.php b/src/FFI.php index 70a399b..a48aeed 100644 --- a/src/FFI.php +++ b/src/FFI.php @@ -243,10 +243,6 @@ private static function init(): void if (!ini_get('ffi.enable')) { throw new Exception("ffi.enable not set to 'true'"); } - if (version_compare(PHP_VERSION, '8.3', '>=') && - ini_get('zend.max_allowed_stack_size') != '-1') { - throw new Exception("zend.max_allowed_stack_size not set to '-1'"); - } $vips_libname = self::libraryName("libvips", 42); if (PHP_OS_FAMILY === "Windows") { diff --git a/src/GObject.php b/src/GObject.php index 2959e25..50ae8d1 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -60,6 +60,14 @@ abstract class GObject */ private CData $pointer; + /** + * libvips executes FFI callbacks off the main thread and this confuses + * the stack limit checks available since PHP 8.3.0. We need to check + * if `zend.max_allowed_stack_size` is set to `-1`. + * See: https://github.com/libvips/php-vips/pull/237. + */ + private static bool $check_max_stack_size = true; + /** * Wrap a GObject around an underlying vips resource. The GObject takes * ownership of the pointer and will unref it on finalize. @@ -104,6 +112,16 @@ public function unref(): void */ public function signalConnect(string $name, callable $callback): void { + if (self::$check_max_stack_size) { + $max_allowed_stack_size = ini_get('zend.max_allowed_stack_size'); + if ($max_allowed_stack_size !== false && + $max_allowed_stack_size !== '-1') { + throw new Exception("signalConnect() requires zend.max_allowed_stack_size set to '-1'"); + } + + self::$check_max_stack_size = false; + } + $marshaler = self::getMarshaler($name, $callback); if ($marshaler === null) { throw new Exception("unsupported signal $name");