This patch should remove all of the concerns about my previous patches.
You'll notice that there has been no extension to SAPI, and no explicit
closing of the socket.  Instead I've returned the Apache SAPI module to its
previous execution code path.  The only modification is that the
shutdown_functions are now executed in php_module_main instead of calling
php_request_shutdown which is called as a cleanup function.  This retains
the functionality of the existing register_shutdown_function command.  An
additional abstraction of the register_shutdown_function procedure allowed
me to minimize the amount of repeated code, and call different types of
shutdown functions.  An additional test within php_request_shutdown allows
shutdown_functions on other platforms to operate as in previous versions
without requiring changes to any code.

PHP implementations using mod_php4 on Apache web servers should see an
improvement of speed over the initial 4.3.0 release as the PHP cleanup phase
happens after the http request is terminated.

Please review and send me any comments.

Joseph
P.S.  As I have an immediate need for this functionality, I have written the
patch against the php_4_3_0 tagged version of php4.  If approved, I'll
rewrite it for PHP_4_3 and HEAD.
? php4/ext/mysql/.libs
Index: php4/ext/standard/basic_functions.c
===================================================================
RCS file: /repository/php4/ext/standard/basic_functions.c,v
retrieving revision 1.543.2.4
diff -u -b -r1.543.2.4 basic_functions.c
--- php4/ext/standard/basic_functions.c 20 Dec 2002 16:37:44 -0000      1.543.2.4
+++ php4/ext/standard/basic_functions.c 7 Jan 2003 21:00:30 -0000
@@ -1121,6 +1121,7 @@
        }
 #endif
        BG(user_shutdown_function_names) = NULL;
+       BG(user_apache_shutdown_function_names) = NULL;
 
 #if HAVE_CRYPT
        PHP_RINIT(crypt) (INIT_FUNC_ARGS_PASSTHRU);
@@ -2085,32 +2086,28 @@
        }
 }
 
-void php_call_shutdown_functions(void)
+PHPAPI void php_call_shutdown_functions(HashTable ** names)
 {
        TSRMLS_FETCH();
 
-       if (BG(user_shutdown_function_names))
+       if (*names){
                zend_try {
-                       zend_hash_apply(BG(user_shutdown_function_names), 
(apply_func_t) user_shutdown_function_call TSRMLS_CC);
+                       zend_hash_apply(*names, (apply_func_t) 
+user_shutdown_function_call TSRMLS_CC);
                        memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf));
-                       zend_hash_destroy(BG(user_shutdown_function_names));
-                       efree(BG(user_shutdown_function_names));
+                       zend_hash_destroy(*names);
+                       efree(*names);
+                       *names = NULL;
                }
                zend_end_try();
+       }
 }
 
-/* {{{ proto void register_shutdown_function(string function_name)
-   Register a user-level function to be called on request termination */
-PHP_FUNCTION(register_shutdown_function)
+PHPAPI void register_shutdown_function_entry(HashTable ** names, int ht, zval * 
+return_value)
 {
        php_shutdown_function_entry shutdown_function_entry;
        int i;
 
-       shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
-
-       if (shutdown_function_entry.arg_count < 1) {
-               WRONG_PARAM_COUNT;
-       }
+       shutdown_function_entry.arg_count = (ht);
 
        shutdown_function_entry.arguments = (pval **) emalloc(sizeof(pval *) 
*shutdown_function_entry.arg_count);
 
@@ -2118,14 +2115,26 @@
                RETURN_FALSE;
        }
        if (!BG(user_shutdown_function_names)) {
-               ALLOC_HASHTABLE(BG(user_shutdown_function_names));
-               zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void 
(*)(void *)) user_shutdown_function_dtor, 0);
+               ALLOC_HASHTABLE(*names);
+               zend_hash_init(*names, 0, NULL, (void (*)(void *)) 
+user_shutdown_function_dtor, 0);
        }
 
        for (i = 0; i < shutdown_function_entry.arg_count; i++) {
                shutdown_function_entry.arguments[i]->refcount++;
        }
-       zend_hash_next_index_insert(BG(user_shutdown_function_names), 
&shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
+       zend_hash_next_index_insert(*names, &shutdown_function_entry, 
+sizeof(php_shutdown_function_entry), NULL);
+       RETURN_TRUE;
+}
+
+/* {{{ proto void register_shutdown_function(string function_name)
+   Register a user-level function to be called on request termination */
+PHP_FUNCTION(register_shutdown_function)
+{
+       if (ZEND_NUM_ARGS() < 1) {
+               WRONG_PARAM_COUNT;
+       }
+
+       register_shutdown_function_entry(&BG(user_shutdown_function_names), ht, 
+return_value);
 }
 /* }}} */
 
Index: php4/ext/standard/basic_functions.h
===================================================================
RCS file: /repository/php4/ext/standard/basic_functions.h,v
retrieving revision 1.109
diff -u -b -r1.109 basic_functions.h
--- php4/ext/standard/basic_functions.h 5 Nov 2002 06:05:48 -0000       1.109
+++ php4/ext/standard/basic_functions.h 7 Jan 2003 21:00:30 -0000
@@ -74,6 +74,8 @@
 PHP_FUNCTION(highlight_string);
 ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini 
*syntax_highlighter_ini);
 
+PHPAPI void register_shutdown_function_entry(HashTable **names, int ht, zval 
+*return_value);
+
 PHP_FUNCTION(ini_get);
 PHP_FUNCTION(ini_get_all);
 PHP_FUNCTION(ini_set);
@@ -130,6 +132,7 @@
 
 typedef struct {
        HashTable *user_shutdown_function_names;
+       HashTable *user_apache_shutdown_function_names;
        HashTable putenv_ht;
        zval *strtok_zval;
        char *strtok_string;
Index: php4/main/main.c
===================================================================
RCS file: /repository/php4/main/main.c,v
retrieving revision 1.512.2.5
diff -u -b -r1.512.2.5 main.c
--- php4/main/main.c    16 Dec 2002 15:44:06 -0000      1.512.2.5
+++ php4/main/main.c    7 Jan 2003 21:00:31 -0000
@@ -920,8 +920,10 @@
                sapi_send_headers(TSRMLS_C);
        } zend_end_try();
 
-       if (PG(modules_activated)) zend_try {
-               php_call_shutdown_functions();
+       if (PG(modules_activated) && BG(user_shutdown_function_names)) zend_try {
+               /* under Apache, this will not execute because the HashTable will not 
+exist.
+                */
+               php_call_shutdown_functions(& BG(user_shutdown_function_names));
        } zend_end_try();
        
        if (PG(modules_activated)) {
Index: php4/main/php_main.h
===================================================================
RCS file: /repository/php4/main/php_main.h,v
retrieving revision 1.23
diff -u -b -r1.23 php_main.h
--- php4/main/php_main.h        18 Sep 2002 21:57:29 -0000      1.23
+++ php4/main/php_main.h        7 Jan 2003 21:00:31 -0000
@@ -47,7 +47,7 @@
 
 PHPAPI void php_html_puts(const char *str, uint siz TSRMLS_DC);
 
-extern void php_call_shutdown_functions(void);
+extern void php_call_shutdown_functions(HashTable **names);
 
 /* environment module */
 extern int php_init_environ(void);
Index: php4/sapi/apache/mod_php4.c
===================================================================
RCS file: /repository/php4/sapi/apache/mod_php4.c,v
retrieving revision 1.146.2.1
diff -u -b -r1.146.2.1 mod_php4.c
--- php4/sapi/apache/mod_php4.c 21 Dec 2002 20:09:09 -0000      1.146.2.1
+++ php4/sapi/apache/mod_php4.c 7 Jan 2003 21:00:31 -0000
@@ -295,8 +295,13 @@
        SG(server_context) = NULL; /* The server context (request) is invalid by the 
time run_cleanups() is called */
        if (AP(in_request)) {
                AP(in_request) = 0;
-               php_request_shutdown(dummy);
        }
+       else{
+               php_call_shutdown_functions(& BG(user_apache_shutdown_function_names));
+       }
+       zend_try {
+               php_request_shutdown(dummy);
+       } zend_end_try();
 }
 /* }}} */
 
Index: php4/sapi/apache/mod_php4.h
===================================================================
RCS file: /repository/php4/sapi/apache/mod_php4.h,v
retrieving revision 1.17
diff -u -b -r1.17 mod_php4.h
--- php4/sapi/apache/mod_php4.h 28 Feb 2002 08:27:19 -0000      1.17
+++ php4/sapi/apache/mod_php4.h 7 Jan 2003 21:00:31 -0000
@@ -35,6 +35,7 @@
 } php_apache_info_struct;
 
 extern zend_module_entry apache_module_entry;
+extern void php_call_apache_shutdown_functions(HashTable **names);
 
 #ifdef ZTS
 extern int php_apache_info_id;
Index: php4/sapi/apache/php_apache.c
===================================================================
RCS file: /repository/php4/sapi/apache/php_apache.c,v
retrieving revision 1.69.2.1
diff -u -b -r1.69.2.1 php_apache.c
--- php4/sapi/apache/php_apache.c       5 Dec 2002 23:19:02 -0000       1.69.2.1
+++ php4/sapi/apache/php_apache.c       7 Jan 2003 21:00:31 -0000
@@ -44,6 +44,7 @@
 PHP_FUNCTION(apache_lookup_uri);
 PHP_FUNCTION(apache_child_terminate);
 PHP_FUNCTION(apache_setenv);
+PHP_FUNCTION(apache_register_shutdown_function);
 
 PHP_MINFO_FUNCTION(apache);
 
@@ -54,6 +55,7 @@
        PHP_FE(apache_lookup_uri,                                               NULL)
        PHP_FE(apache_child_terminate,                                  NULL)
        PHP_FE(apache_setenv,                                                   NULL)
+       PHP_FE(apache_register_shutdown_function,               NULL)
        PHP_FE(apache_response_headers,                                 NULL)
        PHP_FALIAS(getallheaders, apache_request_headers, NULL)
        {NULL, NULL, NULL}
@@ -471,6 +473,22 @@
        }
 
        destroy_sub_req(rr);
+}
+/* }}} */
+
+/* {{{ proto void apache_register_shutdown_function(string function_name)
+ * Register a user-level function to be called on request termination: executed after 
+the
+ * connection has closed.  This function is only available on Apache web servers 
+using the
+ * SAPI module as it uses Apache calls to execute the functions after the connection 
+has
+ * closed.  Nothing using "print"/"echo" will be sent to the client.
+ */
+PHP_FUNCTION(apache_register_shutdown_function)
+{
+       if (ZEND_NUM_ARGS() < 1) {
+               WRONG_PARAM_COUNT;
+       }
+
+       register_shutdown_function_entry(&BG(user_apache_shutdown_function_names), ht, 
+return_value);
 }
 /* }}} */
 
Index: php4/sapi/apache/sapi_apache.c
===================================================================
RCS file: /repository/php4/sapi/apache/sapi_apache.c,v
retrieving revision 1.40
diff -u -b -r1.40 sapi_apache.c
--- php4/sapi/apache/sapi_apache.c      23 Apr 2002 03:01:30 -0000      1.40
+++ php4/sapi/apache/sapi_apache.c      7 Jan 2003 21:00:31 -0000
@@ -57,9 +57,19 @@
 
        AP(in_request) = 0;
        
+       /* Call the shutdown functions while the connection is still active. */
+       if (PG(modules_activated)) zend_try {
+               php_call_shutdown_functions(& BG(user_shutdown_function_names));
+       } zend_end_try();
+
+#if 0
+       /* Removed by jtate Jan. 7, 2003 because php_request_shutdown is now called as
+        * an Apache cleanup function.
+        */
        zend_try {
                php_request_shutdown(NULL);
        } zend_end_try();
+#endif
        
        return (OK);
 }

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to