1--TEST-- 2Fibers in destructors 004: Suspend and throw in destructor 3--FILE-- 4<?php 5 6register_shutdown_function(function () { 7 printf("Shutdown\n"); 8}); 9 10class Cycle { 11 public static $counter = 0; 12 public $self; 13 public function __construct() { 14 $this->self = $this; 15 } 16 public function __destruct() { 17 $id = self::$counter++; 18 printf("%d: Start destruct\n", $id); 19 if ($id === 0) { 20 global $f2; 21 $f2 = Fiber::getCurrent(); 22 Fiber::suspend(new stdClass); 23 } 24 printf("%d: End destruct\n", $id); 25 throw new \Exception(sprintf("%d exception", $id)); 26 } 27} 28 29$f = new Fiber(function () { 30 global $f2; 31 new Cycle(); 32 new Cycle(); 33 new Cycle(); 34 try { 35 gc_collect_cycles(); 36 } catch (\Exception $e) { 37 echo $e, "\n"; 38 } 39 $f2->resume(); 40}); 41 42$f->start(); 43 44?> 45--EXPECTF-- 460: Start destruct 471: Start destruct 481: End destruct 492: Start destruct 502: End destruct 51Exception: 1 exception in %s:%d 52Stack trace: 53#0 [internal function]: Cycle->__destruct() 54#1 [internal function]: gc_destructor_fiber() 55#2 %s(%d): gc_collect_cycles() 56#3 [internal function]: {closure:%s:%d}() 57#4 %s(%d): Fiber->start() 58#5 {main} 59 60Next Exception: 2 exception in %s:%d 61Stack trace: 62#0 [internal function]: Cycle->__destruct() 63#1 [internal function]: gc_destructor_fiber() 64#2 %s(%d): gc_collect_cycles() 65#3 [internal function]: {closure:%s:%d}() 66#4 %s(%d): Fiber->start() 67#5 {main} 680: End destruct 69 70Fatal error: Uncaught Exception: 0 exception in %s:%d 71Stack trace: 72#0 [internal function]: Cycle->__destruct() 73#1 [internal function]: gc_destructor_fiber() 74#2 %s(%d): Fiber->resume() 75#3 [internal function]: {closure:%s:%d}() 76#4 %s(%d): Fiber->start() 77#5 {main} 78 thrown in %s on line %d 79Shutdown 80