Looks like mozilla buggered up the attachment. Alan Knowles wrote:
> Well, after half a dozen bug reports that didnt actually work... - > this one should, could somebody comment/commit etc. > > The patch includes a number of changes... - > pcntl_zend_extension_active does not appear to be getting set when > using modules > this little magic trick to get the zval stored in the hash table for > callbacks > > + MAKE_STD_ZVAL(handle_copy); > + *handle_copy = **handle; > + zval_copy_ctor(handle_copy); > > I deleted this as it was confusing me alot :) - obviously not > essential to the patch > old_pcntl_signal_handler(int signo) > > added a new function > pcntl_doevents = works a bit like gtk::do_events(); > basically calls any pending signal callbacks. - as the > pcntl_zend_extension_statement_handler did not appear to get called > when running from a module. > > > best regards > alan > > > > > > > > > >
Index: pcntl.c =================================================================== RCS file: /repository/php4/ext/pcntl/pcntl.c,v retrieving revision 1.18 diff -u -r1.18 pcntl.c --- pcntl.c 4 Jan 2002 14:08:25 -0000 1.18 +++ pcntl.c 21 Jan 2002 08:36:05 -0000 @@ -18,7 +18,7 @@ /* $Id: pcntl.c,v 1.18 2002/01/04 14:08:25 hholzgra Exp $ */ -#define PCNTL_DEBUG 0 +#define PCNTL_DEBUG 0 #if PCNTL_DEBUG #define DEBUG_OUT printf("DEBUG: ");printf @@ -51,6 +51,7 @@ PHP_FE(pcntl_wtermsig, NULL) PHP_FE(pcntl_wstopsig, NULL) PHP_FE(pcntl_exec, NULL) + PHP_FE(pcntl_doevents, NULL) {NULL, NULL, NULL} }; @@ -208,7 +209,7 @@ PHP_FUNCTION(pcntl_fork) { pid_t id; - + pcntl_zend_extension_active=1; id=fork(); if (id == -1) { php_error(E_ERROR, "Error %d in %s", errno, get_active_function_name(TSRMLS_C)); @@ -463,8 +464,9 @@ PHP_FUNCTION(pcntl_signal) { zval **signo, **handle; + zval *handle_copy; char *func_name; - + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &signo, &handle) == FAILURE) { WRONG_PARAM_COUNT; } @@ -474,7 +476,7 @@ /* Special long value case for SIG_DFL and SIG_IGN */ if (Z_TYPE_PP(handle)==IS_LONG) { if (Z_LVAL_PP(handle)!= (long) SIG_DFL && Z_LVAL_PP(handle) != (long) SIG_IGN) { - php_error(E_WARNING, "Invalid value for handle argument specifEied in %s", get_active_function_name(TSRMLS_C)); + php_error(E_WARNING, "Invalid value for handle argument +specified in %s", get_active_function_name(TSRMLS_C)); } if (php_signal(Z_LVAL_PP(signo), (Sigfunc *) Z_LVAL_PP(handle))==SIG_ERR) { php_error(E_WARNING, "Error assigning singal in %s", get_active_function_name(TSRMLS_C)); @@ -483,22 +485,18 @@ RETURN_TRUE; } - if (Z_TYPE_PP(handle)!=IS_STRING) { - php_error(E_WARNING, "Invalid type specified for handle argument in %s", get_active_function_name(TSRMLS_C)); - RETURN_FALSE; - } - - convert_to_string_ex(handle); /* Just in case */ - if (!zend_is_callable(*handle, 0, &func_name)) { - php_error(E_WARNING, "%s: %s is not a callable function name error", get_active_function_name(TSRMLS_C), func_name); + if (!zend_is_callable(*handle, 0, &func_name)) { + php_error(E_WARNING, "%s: Argument is not a callable function or +method", get_active_function_name(TSRMLS_C), func_name); efree(func_name); RETURN_FALSE; } efree(func_name); - - /* Add the function name to our signal table */ - zend_hash_index_update(&PCNTL_G(php_signal_table), Z_LVAL_PP(signo), Z_STRVAL_PP(handle), (Z_STRLEN_PP(handle) + 1) * sizeof(char), NULL); - + MAKE_STD_ZVAL(handle_copy); + *handle_copy = **handle; + zval_copy_ctor(handle_copy); + + zend_hash_index_update(&PCNTL_G(php_signal_table), Z_LVAL_PP(signo), +&handle_copy , sizeof(zval *), NULL); + if (php_signal(Z_LVAL_PP(signo), pcntl_signal_handler)==SIG_ERR) { php_error(E_WARNING, "Error assigning singal in %s", get_active_function_name(TSRMLS_C)); RETURN_FALSE; @@ -507,43 +505,14 @@ } /* }}} */ -/* Note Old */ -static void old_pcntl_signal_handler(int signo) -{ - char *func_name; - zval *param, *call_name, *retval; - TSRMLS_FETCH(); - - DEBUG_OUT("Caught signal: %d\n", signo); - if (zend_hash_index_find(&PCNTL_G(php_signal_table), (long) signo, (void *) &func_name)==FAILURE) { - DEBUG_OUT("Signl handler not fount"); - return; - } - /* DEBUG_OUT("Signal handler found, Calling %s\n", func_name); */ - MAKE_STD_ZVAL(param); - MAKE_STD_ZVAL(call_name); - MAKE_STD_ZVAL(retval); - ZVAL_LONG(param, signo); - ZVAL_STRING(call_name, func_name, 1); - - /* Call php singal handler - Note that we do not report errors, and we ignore the return value */ - call_user_function(EG(function_table), NULL, call_name, retval, 1, ¶m TSRMLS_CC); - - zval_dtor(call_name); - efree(call_name); - efree(param); - efree(retval); - - return; -} - + /* Our custom signal handler that calls the appropriate php_function */ static void pcntl_signal_handler(int signo) { long signal_num=signo; TSRMLS_FETCH(); - DEBUG_OUT("Caught signo %d\n", signo); + DEBUG_OUT("Caught signo %d,%d,%d\n", +signo,PCNTL_G(processing_signal_queue),pcntl_zend_extension_active); if (! PCNTL_G(processing_signal_queue) && pcntl_zend_extension_active ) { zend_llist_add_element(&PCNTL_G(php_signal_queue), &signal_num); PCNTL_G(signal_queue_ready)=1; @@ -588,59 +557,91 @@ return; } + /* Custom hook to ensure signals only get called at a safe poing in Zend's execute process */ void pcntl_zend_extension_statement_handler(zend_op_array *op_array) { zend_llist_element *element; - zval *param, *call_name, *retval; + zval *param, *retval; + zval **callback; char *func_name; + int error; TSRMLS_FETCH(); - + /* Bail if the queue is empty or if we are already playing the queue*/ if (! PCNTL_G(signal_queue_ready) || PCNTL_G(processing_signal_queue)) return; - /* Mark our queue empty */ PCNTL_G(signal_queue_ready)=0; - /* If for some reason our signal queue is empty then return */ if (zend_llist_count(&PCNTL_G(php_signal_queue)) <= 0) { return; } - + /* Disable queue so this function is not infinate */ PCNTL_G(processing_signal_queue)=1; /* Allocate */ MAKE_STD_ZVAL(param); - MAKE_STD_ZVAL(call_name); - MAKE_STD_ZVAL(retval); + MAKE_STD_ZVAL(retval); /* Traverse through our signal queue and call the appropriate php functions */ for (element=(&PCNTL_G(php_signal_queue))->head; element; element=element->next) { long *signal_num=(long *)&element->data; - if (zend_hash_index_find(&PCNTL_G(php_signal_table), *signal_num, (void *) &func_name)==FAILURE) { + DEBUG_OUT("sig %d\n",*signal_num); + + + if (zend_hash_index_find(&PCNTL_G(php_signal_table), *signal_num, +(void **) &callback)==FAILURE) { + php_error(E_WARNING, "%s: Signal callback for %d Not found", +get_active_function_name(TSRMLS_C),*signal_num); + DEBUG_OUT("NOT FOUND"); continue; } + if (!zend_is_callable( *callback, 0, &func_name)) { + php_error(E_WARNING, "%s: %s is not a callable function or +method", func_name, get_active_function_name(TSRMLS_C)); + continue; + } + convert_to_long_ex(¶m); - convert_to_string_ex(&call_name); - ZVAL_LONG(param, *signal_num); - ZVAL_STRING(call_name, func_name, 0); - - /* Call php singal handler - Note that we do not report errors, and we ignore the return value */ - call_user_function(EG(function_table), NULL, call_name, retval, 1, ¶m TSRMLS_CC); + ZVAL_LONG(param, *signal_num); + + /* Call php singal handler - Note that we do not report errors, and we +ignore the return value */ + error = call_user_function(EG(function_table), NULL, *callback, +retval, 1, ¶m TSRMLS_CC); + if (error == FAILURE) { + php_error(E_WARNING, "Couldn't call the SIGNAL FUNCTION"); + + } } + + + /* Clear */ - zend_llist_clean(&PCNTL_G(php_signal_queue)); - + zend_llist_clean(&PCNTL_G(php_signal_queue)); + /* Re-enable queue */ PCNTL_G(processing_signal_queue)=0; /* Clean up */ efree(param); - efree(call_name); + //efree(callback); efree(retval); + + +} + + +/* {{{ proto bool pcntl_doevents() + Calls any pending events - if you compile pcntl as a module, the + statement handler does not work, you have to do it manually */ +PHP_FUNCTION(pcntl_doevents) +{ + zend_op_array *op_array=NULL; + TSRMLS_FETCH(); + + pcntl_zend_extension_statement_handler(op_array); + + RETURN_TRUE; } +/* }}} */ /* * Local variables:
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]