@@ -579,6 +579,31 @@ public function testProcessWillExitFasterThanExitInterval()
579579 $ this ->assertLessThan (0.1 , $ time );
580580 }
581581
582+ /**
583+ * @requires PHP 8
584+ */
585+ public function testProcessWithSocketIoWillExitFasterThanExitInterval ()
586+ {
587+ $ loop = $ this ->createLoop ();
588+ $ process = new Process (
589+ DIRECTORY_SEPARATOR === '\\' ? 'cmd /c echo hi ' : 'echo hi ' ,
590+ null ,
591+ null ,
592+ array (
593+ array ('socket ' ),
594+ array ('socket ' ),
595+ array ('socket ' )
596+ )
597+ );
598+ $ process ->start ($ loop , 2 );
599+
600+ $ time = microtime (true );
601+ $ loop ->run ();
602+ $ time = microtime (true ) - $ time ;
603+
604+ $ this ->assertLessThan (0.1 , $ time );
605+ }
606+
582607 public function testDetectsClosingStdoutWithoutHavingToWaitForExit ()
583608 {
584609 if (DIRECTORY_SEPARATOR === '\\' ) {
@@ -606,6 +631,39 @@ public function testDetectsClosingStdoutWithoutHavingToWaitForExit()
606631 $ this ->assertTrue ($ closed );
607632 }
608633
634+ /**
635+ * @requires PHP 8
636+ */
637+ public function testDetectsClosingStdoutSocketWithoutHavingToWaitForExit ()
638+ {
639+ $ loop = $ this ->createLoop ();
640+ $ process = new Process (
641+ (DIRECTORY_SEPARATOR === '\\' ? '' : 'exec ' ) . $ this ->getPhpBinary () . ' -r ' . escapeshellarg ('fclose(STDOUT); sleep(1); ' ),
642+ null ,
643+ null ,
644+ array (
645+ array ('socket ' ),
646+ array ('socket ' ),
647+ array ('socket ' )
648+ )
649+ );
650+ $ process ->start ($ loop );
651+
652+ $ closed = false ;
653+ $ process ->stdout ->on ('close ' , function () use (&$ closed , $ loop ) {
654+ $ closed = true ;
655+ $ loop ->stop ();
656+ });
657+
658+ // run loop for maximum of 0.5s only
659+ $ loop ->addTimer (0.5 , function () use ($ loop ) {
660+ $ loop ->stop ();
661+ });
662+ $ loop ->run ();
663+
664+ $ this ->assertTrue ($ closed );
665+ }
666+
609667 public function testKeepsRunningEvenWhenAllStdioPipesHaveBeenClosed ()
610668 {
611669 if (DIRECTORY_SEPARATOR === '\\' ) {
@@ -642,6 +700,48 @@ public function testKeepsRunningEvenWhenAllStdioPipesHaveBeenClosed()
642700 $ this ->assertTrue ($ process ->isRunning ());
643701 }
644702
703+ /**
704+ * @requires PHP 8
705+ */
706+ public function testKeepsRunningEvenWhenAllStdioSocketsHaveBeenClosed ()
707+ {
708+ $ loop = $ this ->createLoop ();
709+ $ process = new Process (
710+ (DIRECTORY_SEPARATOR === '\\' ? '' : 'exec ' ) . $ this ->getPhpBinary () . ' -r ' . escapeshellarg ('fclose(STDIN);fclose(STDOUT);fclose(STDERR);sleep(1); ' ),
711+ null ,
712+ null ,
713+ array (
714+ array ('socket ' ),
715+ array ('socket ' ),
716+ array ('socket ' )
717+ )
718+ );
719+ $ process ->start ($ loop );
720+
721+ $ closed = 0 ;
722+ $ process ->stdout ->on ('close ' , function () use (&$ closed , $ loop ) {
723+ ++$ closed ;
724+ if ($ closed === 2 ) {
725+ $ loop ->stop ();
726+ }
727+ });
728+ $ process ->stderr ->on ('close ' , function () use (&$ closed , $ loop ) {
729+ ++$ closed ;
730+ if ($ closed === 2 ) {
731+ $ loop ->stop ();
732+ }
733+ });
734+
735+ // run loop for maximum 0.5s only
736+ $ loop ->addTimer (0.5 , function () use ($ loop ) {
737+ $ loop ->stop ();
738+ });
739+ $ loop ->run ();
740+
741+ $ this ->assertEquals (2 , $ closed );
742+ $ this ->assertTrue ($ process ->isRunning ());
743+ }
744+
645745 public function testDetectsClosingProcessEvenWhenAllStdioPipesHaveBeenClosed ()
646746 {
647747 if (DIRECTORY_SEPARATOR === '\\' ) {
@@ -662,16 +762,42 @@ public function testDetectsClosingProcessEvenWhenAllStdioPipesHaveBeenClosed()
662762 $ this ->assertSame (0 , $ process ->getExitCode ());
663763 }
664764
665- public function testDetectsClosingProcessEvenWhenStartedWithoutPipes ()
765+ /**
766+ * @requires PHP 8
767+ */
768+ public function testDetectsClosingProcessEvenWhenAllStdioSocketsHaveBeenClosed ()
666769 {
667770 $ loop = $ this ->createLoop ();
771+ $ process = new Process (
772+ (DIRECTORY_SEPARATOR === '\\' ? '' : 'exec ' ) . $ this ->getPhpBinary () . ' -r ' . escapeshellarg ('fclose(STDIN);fclose(STDOUT);fclose(STDERR);usleep(10000); ' ),
773+ null ,
774+ null ,
775+ array (
776+ array ('socket ' ),
777+ array ('socket ' ),
778+ array ('socket ' )
779+ )
780+ );
781+ $ process ->start ($ loop , 0.001 );
668782
669- if (DIRECTORY_SEPARATOR === '\\' ) {
670- $ process = new Process ('cmd /c exit 0 ' , null , null , array ());
671- } else {
672- $ process = new Process ('exit 0 ' , null , null , array ());
673- }
783+ $ time = microtime (true );
784+ $ loop ->run ();
785+ $ time = microtime (true ) - $ time ;
786+
787+ $ this ->assertLessThan (0.5 , $ time );
788+ $ this ->assertSame (0 , $ process ->getExitCode ());
789+ }
674790
791+ public function testDetectsClosingProcessEvenWhenStartedWithoutPipes ()
792+ {
793+ $ loop = $ this ->createLoop ();
794+
795+ $ process = new Process (
796+ (DIRECTORY_SEPARATOR === '\\' ? 'cmd /c ' : '' ) . 'exit 0 ' ,
797+ null ,
798+ null ,
799+ array ()
800+ );
675801 $ process ->start ($ loop , 0.001 );
676802
677803 $ time = microtime (true );
0 commit comments