[prev in list] [next in list] [prev in thread] [next in thread] 

List:       php-cvs
Subject:    [PHP-CVS] [php-src] master: Fix exception thrown during fiber destruction
From:       Aaron Piotrowski <noreply () php ! net>
Date:       2021-04-30 5:27:31
Message-ID: xstigo1Sb6vizcykVO4Al1D23VrBtJDF6oJwe1j3Ow () main ! php ! net
[Download RAW message or body]

Author: Aaron Piotrowski (trowski)
Date: 2021-04-30T00:26:47-05:00

Commit: https://github.com/php/php-src/commit/416665329862960d3120b69e618005c1b7691a17
 Raw diff: https://github.com/php/php-src/commit/416665329862960d3120b69e618005c1b7691a17.diff


Fix exception thrown during fiber destruction

Previously an exception thrown during fiber destruction resulted in a fatal error, \
but that exception should be able to be caught (unless we've entered shutdown, then \
still use a fatal error so the error is not hidden).

Changed paths:
  A  Zend/tests/fibers/suspend-in-force-close-fiber-catching-exception.phpt
  M  Zend/tests/fibers/suspend-in-force-close-fiber-after-shutdown.phpt
  M  Zend/tests/fibers/suspend-in-force-close-fiber.phpt
  M  Zend/tests/fibers/unfinished-fiber-with-throw-in-finally.phpt
  M  Zend/zend_fibers.c


Diff:

diff --git a/Zend/tests/fibers/suspend-in-force-close-fiber-after-shutdown.phpt \
b/Zend/tests/fibers/suspend-in-force-close-fiber-after-shutdown.phpt index \
                2db5a14e45cee..ff7bf493206e3 100644
--- a/Zend/tests/fibers/suspend-in-force-close-fiber-after-shutdown.phpt
+++ b/Zend/tests/fibers/suspend-in-force-close-fiber-after-shutdown.phpt
@@ -1,5 +1,5 @@
 --TEST--
-Suspend in force closed fiber after shutdown
+Suspend in force-closed fiber after shutdown
 --FILE--
 <?php
 
@@ -19,7 +19,7 @@ echo "done\n";
 --EXPECTF--
 done
 
-Fatal error: Uncaught FiberError: Cannot suspend in a force closed fiber in \
%ssuspend-in-force-close-fiber-after-shutdown.php:%d +Fatal error: Uncaught \
FiberError: Cannot suspend in a force-closed fiber in \
%ssuspend-in-force-close-fiber-after-shutdown.php:%d  Stack trace:
 #0 %ssuspend-in-force-close-fiber-after-shutdown.php(%d): Fiber::suspend()
 #1 [internal function]: {closure}()
diff --git a/Zend/tests/fibers/suspend-in-force-close-fiber-catching-exception.phpt \
b/Zend/tests/fibers/suspend-in-force-close-fiber-catching-exception.phpt new file \
mode 100644 index 0000000000000..b6e0d1a929f5c
--- /dev/null
+++ b/Zend/tests/fibers/suspend-in-force-close-fiber-catching-exception.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Suspend in force-closed fiber, catching exception thrown from destructor
+--FILE--
+<?php
+
+try {
+    (function (): void {
+        $fiber = new Fiber(function (): void {
+            try {
+                Fiber::suspend();
+            } finally {
+                Fiber::suspend();
+            }
+        });
+
+        $fiber->start();
+    })();
+} catch (FiberError $exception) {
+    echo $exception->getMessage(), "\n";
+}
+
+echo "done\n";
+
+?>
+--EXPECTF--
+Cannot suspend in a force-closed fiber
+done
diff --git a/Zend/tests/fibers/suspend-in-force-close-fiber.phpt \
b/Zend/tests/fibers/suspend-in-force-close-fiber.phpt index \
                c2c2b2105857b..e552bab4c1efe 100644
--- a/Zend/tests/fibers/suspend-in-force-close-fiber.phpt
+++ b/Zend/tests/fibers/suspend-in-force-close-fiber.phpt
@@ -1,5 +1,5 @@
 --TEST--
-Suspend in force closed fiber
+Suspend in force-closed fiber
 --FILE--
 <?php
 
@@ -17,7 +17,7 @@ unset($fiber);
 
 ?>
 --EXPECTF--
-Fatal error: Uncaught FiberError: Cannot suspend in a force closed fiber in \
%ssuspend-in-force-close-fiber.php:%d +Fatal error: Uncaught FiberError: Cannot \
suspend in a force-closed fiber in %ssuspend-in-force-close-fiber.php:%d  Stack \
trace:  #0 %ssuspend-in-force-close-fiber.php(%d): Fiber::suspend()
 #1 [internal function]: {closure}()
diff --git a/Zend/tests/fibers/unfinished-fiber-with-throw-in-finally.phpt \
b/Zend/tests/fibers/unfinished-fiber-with-throw-in-finally.phpt index \
                fd0f856188a71..f1b17caeb5d7a 100644
--- a/Zend/tests/fibers/unfinished-fiber-with-throw-in-finally.phpt
+++ b/Zend/tests/fibers/unfinished-fiber-with-throw-in-finally.phpt
@@ -44,5 +44,5 @@ fiber
 inner finally
 finally exception
 outer finally
-Cannot suspend in a force closed fiber
+Cannot suspend in a force-closed fiber
 done
diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c
index 65e3a4cf45ccd..43a0845200cd1 100644
--- a/Zend/zend_fibers.c
+++ b/Zend/zend_fibers.c
@@ -349,8 +349,6 @@ static void ZEND_STACK_ALIGNED \
zend_fiber_execute(zend_fiber_context *context)  if (fiber->status == \
ZEND_FIBER_STATUS_SHUTDOWN) {  if (EXPECTED(zend_is_graceful_exit(EG(exception)) || \
zend_is_unwind_exit(EG(exception)))) {  zend_clear_exception();
-			} else {
-				zend_exception_error(EG(exception), E_ERROR);
 			}
 		} else {
 			fiber->status = ZEND_FIBER_STATUS_THREW;
@@ -380,14 +378,24 @@ static void zend_fiber_object_destroy(zend_object *object)
 {
 	zend_fiber *fiber = (zend_fiber *) object;
 
-	if (fiber->status == ZEND_FIBER_STATUS_SUSPENDED) {
-		zend_object *exception = EG(exception);
-		EG(exception) = NULL;
+	if (fiber->status != ZEND_FIBER_STATUS_SUSPENDED) {
+		return;
+	}
+
+	zend_object *exception = EG(exception);
+	EG(exception) = NULL;
+
+	fiber->status = ZEND_FIBER_STATUS_SHUTDOWN;
 
-		fiber->status = ZEND_FIBER_STATUS_SHUTDOWN;
+	zend_fiber_switch_to(fiber);
 
-		zend_fiber_switch_to(fiber);
+	if (EG(exception)) {
+		zend_exception_set_previous(EG(exception), exception);
 
+		if (EG(flags) & EG_FLAGS_IN_SHUTDOWN) {
+			zend_exception_error(EG(exception), E_ERROR);
+		}
+	} else {
 		EG(exception) = exception;
 	}
 }
@@ -471,7 +479,7 @@ ZEND_METHOD(Fiber, suspend)
 	}
 
 	if (UNEXPECTED(fiber->status == ZEND_FIBER_STATUS_SHUTDOWN)) {
-		zend_throw_error(zend_ce_fiber_error, "Cannot suspend in a force closed fiber");
+		zend_throw_error(zend_ce_fiber_error, "Cannot suspend in a force-closed fiber");
 		RETURN_THROWS();
 	}
 

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic