@@ -856,10 +856,7 @@ PHP_FUNCTION(stream_select)
856856static void user_space_stream_notifier (php_stream_context * context , int notifycode , int severity ,
857857 char * xmsg , int xcode , size_t bytes_sofar , size_t bytes_max , void * ptr )
858858{
859- zval * callback = & context -> notifier -> ptr ;
860- zval retval ;
861859 zval zvs [6 ];
862- int i ;
863860
864861 ZVAL_LONG (& zvs [0 ], notifycode );
865862 ZVAL_LONG (& zvs [1 ], severity );
@@ -872,21 +869,19 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco
872869 ZVAL_LONG (& zvs [4 ], bytes_sofar );
873870 ZVAL_LONG (& zvs [5 ], bytes_max );
874871
875- if (FAILURE == call_user_function (NULL , NULL , callback , & retval , 6 , zvs )) {
876- php_error_docref (NULL , E_WARNING , "Failed to call user notifier" );
877- }
878- for (i = 0 ; i < 6 ; i ++ ) {
879- zval_ptr_dtor (& zvs [i ]);
880- }
881- zval_ptr_dtor (& retval );
872+ zend_call_known_fcc (context -> notifier -> fcc , NULL , 6 , zvs , NULL );
873+ /* Free refcounted string parameter */
874+ zval_ptr_dtor_str (& zvs [2 ]);
882875}
883876
884877static void user_space_stream_notifier_dtor (php_stream_notifier * notifier )
885878{
886- if (notifier && Z_TYPE (notifier -> ptr ) != IS_UNDEF ) {
887- zval_ptr_dtor (& notifier -> ptr );
888- ZVAL_UNDEF (& notifier -> ptr );
889- }
879+ ZEND_ASSERT (notifier );
880+ ZEND_ASSERT (notifier -> fcc );
881+ ZEND_ASSERT (notifier -> fcc -> function_handler );
882+ zend_fcc_dtor (notifier -> fcc );
883+ efree (notifier -> fcc );
884+ notifier -> fcc = NULL ;
890885}
891886
892887static zend_result parse_context_options (php_stream_context * context , HashTable * options )
@@ -924,9 +919,19 @@ static zend_result parse_context_params(php_stream_context *context, HashTable *
924919 context -> notifier = NULL ;
925920 }
926921
922+ zend_fcall_info_cache * fcc = emalloc (sizeof (* fcc ));
923+ char * error ;
924+ if (!zend_is_callable_ex (tmp , NULL , 0 , NULL , fcc , & error )) {
925+ zend_argument_type_error (1 , "must be an array with valid callbacks as values, %s" , error );
926+ efree (fcc );
927+ efree (error );
928+ return FAILURE ;
929+ }
930+ zend_fcc_addref (fcc );
931+
927932 context -> notifier = php_stream_notification_alloc ();
928933 context -> notifier -> func = user_space_stream_notifier ;
929- ZVAL_COPY ( & context -> notifier -> ptr , tmp ) ;
934+ context -> notifier -> fcc = fcc ;
930935 context -> notifier -> dtor = user_space_stream_notifier_dtor ;
931936 }
932937 if (NULL != (tmp = zend_hash_str_find (params , "options" , sizeof ("options" )- 1 ))) {
@@ -1123,9 +1128,11 @@ PHP_FUNCTION(stream_context_get_params)
11231128 }
11241129
11251130 array_init (return_value );
1126- if (context -> notifier && Z_TYPE (context -> notifier -> ptr ) != IS_UNDEF && context -> notifier -> func == user_space_stream_notifier ) {
1127- Z_TRY_ADDREF (context -> notifier -> ptr );
1128- add_assoc_zval_ex (return_value , "notification" , sizeof ("notification" )- 1 , & context -> notifier -> ptr );
1131+ if (context -> notifier && context -> notifier -> fcc ) {
1132+ ZEND_ASSERT (context -> notifier -> func == user_space_stream_notifier );
1133+ zval fn ;
1134+ zend_get_callable_zval_from_fcc (context -> notifier -> fcc , & fn );
1135+ add_assoc_zval_ex (return_value , ZEND_STRL ("notification" ), & fn );
11291136 }
11301137 Z_TRY_ADDREF (context -> options );
11311138 add_assoc_zval_ex (return_value , "options" , sizeof ("options" )- 1 , & context -> options );
0 commit comments