From 6968eb8ac7ad68faefc1fc05b4d53389d004cf3c Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 9 Feb 2007 14:19:40 +0000 Subject: [PATCH] - finalize persistent handle support (probably) * make it a system ini option instead of a configure option = http.persistent.handles.limit controls the maximum of idle handles lingering around for a single provider * re-arrange stat() structure * display verbose phpinfo() --- config9.m4 | 11 -- docs/http.ini | 3 + http.c | 110 ++++++-------- http_api.c | 4 - http_functions.c | 7 +- http_persistent_handle_api.c | 239 +++++++++++++++++++++--------- http_request_api.c | 32 ++-- http_request_datashare_api.c | 46 ++---- http_request_object.c | 2 +- http_request_pool_api.c | 18 +-- php_http.h | 8 +- php_http_persistent_handle_api.h | 19 ++- php_http_request_api.h | 3 + php_http_request_pool_api.h | 2 - tests/persistent_handles_001.phpt | 111 ++++++++------ 15 files changed, 339 insertions(+), 276 deletions(-) diff --git a/config9.m4 b/config9.m4 index 6539daf..3edb363 100644 --- a/config9.m4 +++ b/config9.m4 @@ -4,9 +4,6 @@ dnl vim: noet ts=1 sw=1 PHP_ARG_ENABLE([http], [whether to enable extended HTTP support], [ --enable-http Enable extended HTTP support]) -PHP_ARG_ENABLE([http-persistent-handles], [whether to enable per-process persistent cURL handles], -[ --enable-http-persistent-handles - HTTP: enable per-process persistent cURL handles], "no", "no") PHP_ARG_WITH([http-shared-deps], [whether to depend on extensions which have been built shared], [ --with-http-shared-deps HTTP: disable to not depend on extensions like hash, @@ -270,14 +267,6 @@ dnl ---- [$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR] ) - dnl persistent cURL handles - AC_MSG_CHECKING([whether to enable per-process persistent cURL handles]) - if test "$PHP_HTTP_PERSISTENT_HANDLES" != "no"; then - AC_DEFINE([HTTP_HAVE_PERSISTENT_HANDLES], [1], [Have per-process persistent cURL handles]) - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi fi dnl ---- diff --git a/docs/http.ini b/docs/http.ini index a7ab0f6..a32ad46 100644 --- a/docs/http.ini +++ b/docs/http.ini @@ -54,5 +54,8 @@ ;http.request.datashare.cookie = 0 ;http.request.datashare.dns = 1 +; limit of idle persistent handles per provider +;http.persistent.handles.limit = -1 + ; default ident of persistent handles ;http.persistent.handles.ident = "GLOBAL" diff --git a/http.c b/http.c index 0118e6d..2ad9644 100644 --- a/http.c +++ b/http.c @@ -28,14 +28,12 @@ #include "php_http_cache_api.h" #include "php_http_send_api.h" #include "php_http_message_api.h" +#include "php_http_persistent_handle_api.h" #include "php_http_request_method_api.h" #ifdef HTTP_HAVE_CURL # include "php_http_request_api.h" # include "php_http_request_pool_api.h" # include "php_http_request_datashare_api.h" -# ifdef HTTP_HAVE_PERSISTENT_HANDLES -# include "php_http_persistent_handle_api.h" -# endif #endif #ifdef HTTP_HAVE_ZLIB # include "php_http_encoding_api.h" @@ -104,12 +102,10 @@ zend_function_entry http_functions[] = { PHP_FE(http_get_request_body, NULL) PHP_FE(http_get_request_body_stream, NULL) PHP_FE(http_match_request_header, NULL) -#ifdef HTTP_HAVE_CURL -# ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_FE(http_persistent_handles_count, NULL) PHP_FE(http_persistent_handles_clean, NULL) PHP_FE(http_persistent_handles_ident, NULL) -# endif +#ifdef HTTP_HAVE_CURL PHP_FE(http_get, http_arg_pass_ref_3) PHP_FE(http_head, http_arg_pass_ref_3) PHP_FE(http_post_data, http_arg_pass_ref_4) @@ -240,13 +236,11 @@ PHP_INI_MH(http_update_allowed_methods) http_check_allowed_methods(new_value, new_value_length); return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); } -#ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_INI_MH(http_update_persistent_handle_ident) { HTTP_G->persistent.handles.ident.h = zend_hash_func(new_value, HTTP_G->persistent.handles.ident.l = new_value_length+1); return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); } -#endif #ifndef ZEND_ENGINE_2 # define OnUpdateLong OnUpdateInt @@ -273,9 +267,8 @@ PHP_INI_BEGIN() HTTP_PHP_INI_ENTRY("http.send.deflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.deflate.start_auto) HTTP_PHP_INI_ENTRY("http.send.deflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.deflate.start_flags) #endif -#ifdef HTTP_HAVE_PERSISTENT_HANDLES + HTTP_PHP_INI_ENTRY("http.persistent.handles.limit", "-1", PHP_INI_SYSTEM, OnUpdateLong, persistent.handles.limit) HTTP_PHP_INI_ENTRY("http.persistent.handles.ident", "GLOBAL", PHP_INI_ALL, http_update_persistent_handle_ident, persistent.handles.ident.s) -#endif HTTP_PHP_INI_ENTRY("http.send.not_found_404", "1", PHP_INI_ALL, OnUpdateBool, send.not_found_404) #ifdef ZEND_ENGINE_2 HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions) @@ -293,19 +286,16 @@ PHP_MINIT_FUNCTION(http) REGISTER_INI_ENTRIES(); - if ( (SUCCESS != PHP_MINIT_CALL(http_support)) || + if ( (SUCCESS != PHP_MINIT_CALL(http_persistent_handle)) || /* first */ + (SUCCESS != PHP_MINIT_CALL(http_support)) || (SUCCESS != PHP_MINIT_CALL(http_cookie)) || (SUCCESS != PHP_MINIT_CALL(http_send)) || (SUCCESS != PHP_MINIT_CALL(http_url)) || + #ifdef HTTP_HAVE_CURL -# ifdef HTTP_HAVE_PERSISTENT_HANDLES - (SUCCESS != PHP_MINIT_CALL(http_persistent_handle)) || -# ifdef ZEND_ENGINE_2 - (SUCCESS != PHP_MINIT_CALL(http_request_pool)) || -# endif -# endif (SUCCESS != PHP_MINIT_CALL(http_request)) || # ifdef ZEND_ENGINE_2 + (SUCCESS != PHP_MINIT_CALL(http_request_pool)) || (SUCCESS != PHP_MINIT_CALL(http_request_datashare)) || # endif #endif /* HTTP_HAVE_CURL */ @@ -346,19 +336,17 @@ PHP_MINIT_FUNCTION(http) PHP_MSHUTDOWN_FUNCTION(http) { UNREGISTER_INI_ENTRIES(); -#ifdef HTTP_HAVE_CURL if ( +#ifdef HTTP_HAVE_CURL # ifdef ZEND_ENGINE_2 (SUCCESS != PHP_MSHUTDOWN_CALL(http_request_datashare)) || # endif - (SUCCESS != PHP_MSHUTDOWN_CALL(http_request)) -# ifdef HTTP_HAVE_PERSISTENT_HANDLES - || (SUCCESS != PHP_MSHUTDOWN_CALL(http_persistent_handle)) -# endif + (SUCCESS != PHP_MSHUTDOWN_CALL(http_request)) || +#endif + (SUCCESS != PHP_MSHUTDOWN_CALL(http_persistent_handle)) /* last */ ) { return FAILURE; } -#endif return SUCCESS; } /* }}} */ @@ -445,46 +433,6 @@ PHP_MINFO_FUNCTION(http) "http.chunked_decode, http.chunked_encode, http.deflate, http.inflate" #endif ); -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - { - phpstr s; - HashTable *ht; - HashPosition pos1, pos2; - HashKey key1 = initHashKey(0), key2 = initHashKey(0); - zval **val1, **val2; - - if ((ht = http_persistent_handle_statall()) && zend_hash_num_elements(ht)) { - phpstr_init(&s); - - FOREACH_HASH_KEYVAL(pos1, ht, key1, val1) { - phpstr_append(&s, key1.str, key1.len-1); - phpstr_appends(&s, " ("); - if (zend_hash_num_elements(Z_ARRVAL_PP(val1))) { - FOREACH_KEYVAL(pos2, *val1, key2, val2) { - phpstr_append(&s, key2.str, key2.len-1); - phpstr_appendf(&s, ":%ld, ", Z_LVAL_PP(val2)); - } - PHPSTR_LEN(&s) -= 2; - } else { - phpstr_appends(&s, "0"); - } - phpstr_appends(&s, "), "); - } - zend_hash_destroy(ht); - FREE_HASHTABLE(ht); - - PHPSTR_LEN(&s) -= 2; /* get rid of last ", " */ - phpstr_fix(&s); - - php_info_print_table_row(2, "Persistent Handles", PHPSTR_VAL(&s)); - phpstr_dtor(&s); - } else { - php_info_print_table_row(2, "Persistent Handles", "none"); - } - } -#else - php_info_print_table_row(2, "Persistent Handles", "disabled"); -#endif } php_info_print_table_end(); @@ -510,6 +458,42 @@ PHP_MINFO_FUNCTION(http) } php_info_print_table_end(); + php_info_print_table_start(); + php_info_print_table_colspan_header(4, "Persistent Handles"); + php_info_print_table_header(4, "Provider", "Ident", "used", "free"); + { + HashTable *ht; + HashPosition pos1, pos2; + HashKey provider = initHashKey(0), ident = initHashKey(0); + zval **val, **sub, **zused, **zfree; + + if ((ht = http_persistent_handle_statall()) && zend_hash_num_elements(ht)) { + FOREACH_HASH_KEYVAL(pos1, ht, provider, val) { + if (zend_hash_num_elements(Z_ARRVAL_PP(val))) { + FOREACH_KEYVAL(pos2, *val, ident, sub) { + if ( SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("used"), (void *) &zused) && + SUCCESS == zend_hash_find(Z_ARRVAL_PP(sub), ZEND_STRS("free"), (void *) &zfree)) { + convert_to_string(*zused); + convert_to_string(*zfree); + php_info_print_table_row(4, provider.str, ident.str, Z_STRVAL_PP(zused), Z_STRVAL_PP(zfree)); + } else { + php_info_print_table_row(4, provider.str, ident.str, "0", "0"); + } + } + } else { + php_info_print_table_row(4, provider.str, "N/A", "0", "0"); + } + } + } else { + php_info_print_table_row(4, "N/A", "N/A", "0", "0"); + } + if (ht) { + zend_hash_destroy(ht); + FREE_HASHTABLE(ht); + } + } + php_info_print_table_end(); + php_info_print_table_start(); php_info_print_table_colspan_header(2, "Request Methods"); { diff --git a/http_api.c b/http_api.c index 77f8df5..138b08e 100644 --- a/http_api.c +++ b/http_api.c @@ -32,7 +32,6 @@ PHP_MINIT_FUNCTION(http_support) HTTP_LONG_CONSTANT("HTTP_SUPPORT_MAGICMIME", HTTP_SUPPORT_MAGICMIME); HTTP_LONG_CONSTANT("HTTP_SUPPORT_ENCODINGS", HTTP_SUPPORT_ENCODINGS); HTTP_LONG_CONSTANT("HTTP_SUPPORT_SSLREQUESTS", HTTP_SUPPORT_SSLREQUESTS); - HTTP_LONG_CONSTANT("HTTP_SUPPORT_PERSISTENCE", HTTP_SUPPORT_PERSISTENCE); HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_COMMA", HTTP_PARAMS_ALLOW_COMMA); HTTP_LONG_CONSTANT("HTTP_PARAMS_ALLOW_FAILURE", HTTP_PARAMS_ALLOW_FAILURE); @@ -51,9 +50,6 @@ PHP_HTTP_API long _http_support(long feature) # ifdef HTTP_HAVE_SSL support |= HTTP_SUPPORT_SSLREQUESTS; # endif -# ifdef HTTP_HAVE_PERSISTENT_HANDLES - support |= HTTP_SUPPORT_PERSISTENCE; -# endif #endif #ifdef HTTP_HAVE_MAGIC support |= HTTP_SUPPORT_MAGICMIME; diff --git a/http_functions.c b/http_functions.c index 4ddbda1..737cce8 100644 --- a/http_functions.c +++ b/http_functions.c @@ -802,10 +802,6 @@ PHP_FUNCTION(http_match_request_header) } /* }}} */ -/* {{{ HAVE_CURL */ -#ifdef HTTP_HAVE_CURL -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - /* {{{ proto object http_persistent_handles_count() */ PHP_FUNCTION(http_persistent_handles_count) { @@ -845,7 +841,8 @@ PHP_FUNCTION(http_persistent_handles_ident) } /* }}} */ -#endif /* HTTP_HAVE_PERSISTENT_HANDLES */ +/* {{{ HAVE_CURL */ +#ifdef HTTP_HAVE_CURL #define RETVAL_RESPONSE_OR_BODY(request) \ { \ diff --git a/http_persistent_handle_api.c b/http_persistent_handle_api.c index b07caff..ec345fb 100644 --- a/http_persistent_handle_api.c +++ b/http_persistent_handle_api.c @@ -15,7 +15,6 @@ #include "php_http.h" #include "php_http_api.h" -#ifdef HTTP_HAVE_PERSISTENT_HANDLES #include "php_http_persistent_handle_api.h" #ifndef HTTP_DEBUG_PHANDLES @@ -36,66 +35,152 @@ typedef struct _http_persistent_handle_t { void *ptr; } http_persistent_handle; -typedef HashTable *http_persistent_handle_list; +typedef struct _http_persistent_handle_list_t { + HashTable free; + ulong used; +} http_persistent_handle_list; typedef struct _http_persistent_handle_provider_t { http_persistent_handle_list list; /* "ident" => array(handles) entries */ http_persistent_handle_ctor ctor; http_persistent_handle_dtor dtor; + http_persistent_handle_copy copy; } http_persistent_handle_provider; - -static inline STATUS http_persistent_handle_list_find(http_persistent_handle_list parent_list, http_persistent_handle_list **ident_list, int create TSRMLS_DC) +static inline http_persistent_handle_list *http_persistent_handle_list_init(http_persistent_handle_list *list) { - http_persistent_handle_list new_list; + int free_list; - if (SUCCESS == zend_hash_quick_find(parent_list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) ident_list)) { - return SUCCESS; + if ((free_list = !list)) { + list = pemalloc(sizeof(http_persistent_handle_list), 1); } - if (create) { - if ((new_list = pemalloc(sizeof(HashTable), 1))) { - if (SUCCESS == zend_hash_init(new_list, 0, NULL, NULL, 1)) { - if (SUCCESS == zend_hash_quick_add(parent_list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &new_list, sizeof(http_persistent_handle_list), (void *) ident_list)) { - return SUCCESS; - } - zend_hash_destroy(new_list); - } - pefree(new_list, 1); + list->used = 0; + + if (SUCCESS != zend_hash_init(&list->free, 0, NULL, NULL, 1)) { + if (free_list) { + pefree(list, 1); } + list = NULL; } - return FAILURE; + return list; } -static inline void http_persistent_handle_list_dtor(http_persistent_handle_list list, http_persistent_handle_dtor dtor) +static inline void http_persistent_handle_list_dtor(http_persistent_handle_list *list, http_persistent_handle_dtor dtor) { HashPosition pos; http_persistent_handle *handle; - FOREACH_HASH_VAL(pos, list, handle) { + FOREACH_HASH_VAL(pos, &list->free, handle) { #if HTTP_DEBUG_PHANDLES fprintf(stderr, "DESTROY: %p\n", handle->ptr); #endif dtor(handle->ptr); } - zend_hash_clean(list); + zend_hash_destroy(&list->free); +} + +static inline void http_persistent_handle_list_free(http_persistent_handle_list **list, http_persistent_handle_dtor dtor) +{ + http_persistent_handle_list_dtor(*list, dtor); + pefree(*list, 1); + *list = NULL; +} + +static inline http_persistent_handle_list *http_persistent_handle_list_find(http_persistent_handle_provider *provider TSRMLS_DC) +{ + http_persistent_handle_list **list, *new_list; + + if (SUCCESS == zend_hash_quick_find(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) { + return *list; + } + + if ((new_list = http_persistent_handle_list_init(NULL))) { + if (SUCCESS == zend_hash_quick_add(&provider->list.free, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &new_list, sizeof(http_persistent_handle_list *), (void *) &list)) { + return *list; + } + http_persistent_handle_list_free(&new_list, provider->dtor); + } + + return NULL; +} + +static inline STATUS http_persistent_handle_do_acquire(http_persistent_handle_provider *provider, void **handle_ptr TSRMLS_DC) +{ + ulong index; + http_persistent_handle *handle; + http_persistent_handle_list *list; + + if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) { + zend_hash_internal_pointer_end(&list->free); + if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&list->free, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(&list->free, (void *) &handle)) { + *handle_ptr = handle->ptr; + zend_hash_index_del(&list->free, index); + } else { + *handle_ptr = provider->ctor(); + } + + if (*handle_ptr) { + ++provider->list.used; + ++list->used; + return SUCCESS; + } + } + + return FAILURE; +} + +static inline STATUS http_persistent_handle_do_release(http_persistent_handle_provider *provider, void **handle_ptr TSRMLS_DC) +{ + http_persistent_handle_list *list; + + if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) { + if (provider->list.used >= HTTP_G->persistent.handles.limit) { + provider->dtor(*handle_ptr); + } else { + http_persistent_handle handle = {*handle_ptr}; + + if (SUCCESS != zend_hash_next_index_insert(&list->free, (void *) &handle, sizeof(http_persistent_handle), NULL)) { + return FAILURE; + } + } + + *handle_ptr = NULL; + --provider->list.used; + --list->used; + return SUCCESS; + } + + return FAILURE; +} + +static inline STATUS http_persistent_handle_do_accrete(http_persistent_handle_provider *provider, void *old_handle, void **new_handle TSRMLS_DC) +{ + http_persistent_handle_list *list; + + if (provider->copy && (*new_handle = provider->copy(old_handle))) { + if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) { + ++list->used; + } + ++provider->list.used; + return SUCCESS; + } + return FAILURE; } static void http_persistent_handles_hash_dtor(void *p) { http_persistent_handle_provider *provider = (http_persistent_handle_provider *) p; - http_persistent_handle_list *list; + http_persistent_handle_list **list; HashPosition pos; - FOREACH_HASH_VAL(pos, provider->list, list) { - http_persistent_handle_list_dtor(*list, provider->dtor); - zend_hash_destroy(*list); - pefree(*list, 1); + FOREACH_HASH_VAL(pos, &provider->list.free, list) { + http_persistent_handle_list_free(list, provider->dtor); } - zend_hash_destroy(provider->list); - pefree(provider->list, 1); + + zend_hash_destroy(&provider->list.free); } PHP_MINIT_FUNCTION(http_persistent_handle) @@ -116,26 +201,25 @@ PHP_MSHUTDOWN_FUNCTION(http_persistent_handle) return SUCCESS; } -PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor) +PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor, http_persistent_handle_copy copy) { STATUS status = FAILURE; http_persistent_handle_provider provider; LOCK(); - provider.list = pemalloc(sizeof(HashTable), 1); - if (provider.list) { + if (http_persistent_handle_list_init(&provider.list)) { provider.ctor = ctor; provider.dtor = dtor; - zend_hash_init(provider.list, 0, NULL, NULL, 1); + provider.copy = copy; #if HTTP_DEBUG_PHANDLES - fprintf(stderr, "PROVIDE: %p (%s)\n", provider.list, name_str); + fprintf(stderr, "PROVIDE: %s\n", name_str); #endif if (SUCCESS == zend_hash_add(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider, sizeof(http_persistent_handle_provider), NULL)) { status = SUCCESS; } else { - pefree(provider.list, 1); + http_persistent_handle_list_dtor(&provider.list, dtor); } } UNLOCK(); @@ -146,24 +230,12 @@ PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, siz PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, size_t name_len, void **handle_ptr TSRMLS_DC) { STATUS status = FAILURE; - ulong index; http_persistent_handle_provider *provider; - http_persistent_handle_list *list; - http_persistent_handle *handle; *handle_ptr = NULL; LOCK(); if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider)) { - if (SUCCESS == http_persistent_handle_list_find(provider->list, &list, 0 TSRMLS_CC)) { - zend_hash_internal_pointer_end(*list); - if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(*list, NULL, &index, 0) && SUCCESS == zend_hash_get_current_data(*list, (void *) &handle)) { - *handle_ptr = handle->ptr; - zend_hash_index_del(*list, index); - } - } - if (*handle_ptr || (*handle_ptr = provider->ctor())) { - status = SUCCESS; - } + status = http_persistent_handle_do_acquire(provider, handle_ptr TSRMLS_CC); } UNLOCK(); @@ -178,15 +250,10 @@ PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, siz { STATUS status = FAILURE; http_persistent_handle_provider *provider; - http_persistent_handle_list *list; - http_persistent_handle handle = {*handle_ptr}; LOCK(); if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider)) { - if ( SUCCESS == http_persistent_handle_list_find(provider->list, &list, 1 TSRMLS_CC) && - SUCCESS == zend_hash_next_index_insert(*list, (void *) &handle, sizeof(http_persistent_handle), NULL)) { - status = SUCCESS; - } + status = http_persistent_handle_do_release(provider, handle_ptr TSRMLS_CC); } UNLOCK(); @@ -196,35 +263,58 @@ PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, siz return status; } + +PHP_HTTP_API STATUS _http_persistent_handle_accrete_ex(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC) +{ + STATUS status = FAILURE; + http_persistent_handle_provider *provider; + + *new_handle = NULL; + LOCK(); + if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider)) { + status = http_persistent_handle_do_accrete(provider, old_handle, new_handle TSRMLS_CC); + } + UNLOCK(); + +#if HTTP_DEBUG_PHANDLES + fprintf(stderr, "ACCRETE: %p > %p (%s)\n", old_handle, *new_handle, name_str); +#endif + return status; +} + PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC) { http_persistent_handle_provider *provider; - http_persistent_handle_list *list; + http_persistent_handle_list *list, **listp; HashPosition pos1, pos2; LOCK(); if (name_str && name_len) { if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider)) { if (current_ident_only) { - if (SUCCESS == http_persistent_handle_list_find(provider->list, &list, 0 TSRMLS_CC)) { - http_persistent_handle_list_dtor(*list, provider->dtor); + if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) { + http_persistent_handle_list_dtor(list, provider->dtor); + http_persistent_handle_list_init(list); } } else { - FOREACH_HASH_VAL(pos1, provider->list, list) { - http_persistent_handle_list_dtor(*list, provider->dtor); + FOREACH_HASH_VAL(pos1, &provider->list.free, listp) { + http_persistent_handle_list_dtor(*listp, provider->dtor); + http_persistent_handle_list_init(*listp); } } } } else { FOREACH_HASH_VAL(pos1, &http_persistent_handles_hash, provider) { if (current_ident_only) { - if (SUCCESS == http_persistent_handle_list_find(provider->list, &list, 0 TSRMLS_CC)) { - http_persistent_handle_list_dtor(*list, provider->dtor); + if ((list = http_persistent_handle_list_find(provider TSRMLS_CC))) { + http_persistent_handle_list_dtor(list, provider->dtor); + http_persistent_handle_list_init(list); } } else { - FOREACH_HASH_VAL(pos2, provider->list, list) { - http_persistent_handle_list_dtor(*list, provider->dtor); + FOREACH_HASH_VAL(pos2, &provider->list.free, listp) { + http_persistent_handle_list_dtor(*listp, provider->dtor); + http_persistent_handle_list_init(*listp); } } } @@ -232,13 +322,13 @@ PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_ UNLOCK(); } -PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht) +PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht TSRMLS_DC) { - zval *zlist, *zentry; + zval *zentry[2]; HashPosition pos1, pos2; HashKey key1 = initHashKey(0), key2 = initHashKey(0); http_persistent_handle_provider *provider; - http_persistent_handle_list *list; + http_persistent_handle_list **list; LOCK(); if (zend_hash_num_elements(&http_persistent_handles_hash)) { @@ -248,14 +338,20 @@ PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht) } FOREACH_HASH_KEYVAL(pos1, &http_persistent_handles_hash, key1, provider) { - MAKE_STD_ZVAL(zlist); - array_init(zlist); - FOREACH_HASH_KEYVAL(pos2, provider->list, key2, list) { - MAKE_STD_ZVAL(zentry); - ZVAL_LONG(zentry, zend_hash_num_elements(*list)); - zend_hash_add(Z_ARRVAL_P(zlist), key2.str, key2.len, (void *) &zentry, sizeof(zval *), NULL); + MAKE_STD_ZVAL(zentry[0]); + array_init(zentry[0]); + + FOREACH_HASH_KEYVAL(pos2, &provider->list.free, key2, list) { + MAKE_STD_ZVAL(zentry[1]); + array_init(zentry[1]); + add_assoc_long_ex(zentry[1], ZEND_STRS("used"), (*list)->used); + add_assoc_long_ex(zentry[1], ZEND_STRS("free"), zend_hash_num_elements(&(*list)->free)); + + /* use zend_hash_* not add_assoc_* (which is zend_symtable_*) as we want a string even for numbers */ + zend_hash_add(Z_ARRVAL_P(zentry[0]), key2.str, key2.len, &zentry[1], sizeof(zval *), NULL); } - zend_hash_add(ht, key1.str, key1.len, (void *) &zlist, sizeof(zval *), NULL); + + zend_hash_add(ht, key1.str, key1.len, &zentry[0], sizeof(zval *), NULL); } } else if (ht) { ht = NULL; @@ -265,7 +361,6 @@ PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht) return ht; } -#endif /* HTTP_HAVE_PERSISTENT_HANDLES */ /* * Local variables: diff --git a/http_request_api.c b/http_request_api.c index 3396dba..e574eee 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -19,11 +19,9 @@ #ifdef HTTP_HAVE_CURL #include "php_http_api.h" +#include "php_http_persistent_handle_api.h" #include "php_http_request_api.h" #include "php_http_url_api.h" -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# include "php_http_persistent_handle_api.h" -#endif #ifdef ZEND_ENGINE_2 # include "php_http_request_object.h" @@ -112,11 +110,9 @@ PHP_MINIT_FUNCTION(http_request) return FAILURE; } -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - if (SUCCESS != http_persistent_handle_provide("http_request", curl_easy_init, curl_easy_cleanup)) { + if (SUCCESS != http_persistent_handle_provide("http_request", curl_easy_init, curl_easy_cleanup, curl_easy_duphandle)) { return FAILURE; } -#endif HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC); HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST); @@ -185,18 +181,10 @@ static int http_curl_dummy_callback(char *data, size_t n, size_t l, void *s) { r static curlioerr http_curl_ioctl_callback(CURL *, curliocmd, void *); /* }}} */ -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# define HTTP_CURL_HANDLE_CTOR(ch) (SUCCESS == http_persistent_handle_acquire("http_request", &(ch))) -# define HTTP_CURL_HANDLE_DTOR(chp) http_persistent_handle_release("http_request", (chp)) -#else -# define HTTP_CURL_HANDLE_CTOR(ch) ((ch) = curl_easy_init()) -# define HTTP_CURL_HANDLE_DTOR(chp) curl_easy_cleanup(*(chp)); *(chp) = NULL -#endif - /* {{{ CURL *http_curl_init(http_request *) */ PHP_HTTP_API CURL * _http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC) { - if (ch || HTTP_CURL_HANDLE_CTOR(ch)) { + if (ch || (SUCCESS == http_persistent_handle_acquire("http_request", &ch))) { #if defined(ZTS) curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L); #endif @@ -227,6 +215,18 @@ PHP_HTTP_API CURL * _http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC } /* }}} */ +/* {{{ CURL *http_curl_copy(CURL *) */ +PHP_HTTP_API CURL *_http_curl_copy(CURL *ch TSRMLS_DC) +{ + CURL *copy; + + if (SUCCESS == http_persistent_handle_accrete("http_request", ch, ©)) { + return copy; + } + return NULL; +} +/* }}} */ + /* {{{ void http_curl_free(CURL **) */ PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC) { @@ -236,7 +236,7 @@ PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC) curl_easy_setopt(*ch, CURLOPT_VERBOSE, 0L); curl_easy_setopt(*ch, CURLOPT_DEBUGFUNCTION, NULL); - HTTP_CURL_HANDLE_DTOR(ch); + http_persistent_handle_release("http_request", ch); } } /* }}} */ diff --git a/http_request_datashare_api.c b/http_request_datashare_api.c index 02c40b4..d86ef88 100644 --- a/http_request_datashare_api.c +++ b/http_request_datashare_api.c @@ -18,24 +18,10 @@ #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL) #include "php_http_api.h" +#include "php_http_persistent_handle_api.h" #include "php_http_request_datashare_api.h" #include "php_http_request_api.h" #include "php_http_request_object.h" -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# include "php_http_persistent_handle_api.h" -#endif - -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# define HTTP_CURL_SHARE_CTOR(ch) (SUCCESS == http_persistent_handle_acquire("http_request_datashare", &(ch))) -# define HTTP_CURL_SHARE_DTOR(chp) http_persistent_handle_release("http_request_datashare", (chp)) -# define HTTP_CURL_SLOCK_CTOR(l) (SUCCESS == http_persistent_handle_acquire("http_request_datashare_lock", (void *) &(l))) -# define HTTP_CURL_SLOCK_DTOR(lp) http_persistent_handle_release("http_request_datashare_lock", (void *) (lp)) -#else -# define HTTP_CURL_SHARE_CTOR(ch) ((ch) = curl_share_init()) -# define HTTP_CURL_SHARE_DTOR(chp) curl_share_cleanup(*(chp)); *(chp) = NULL -# define HTTP_CURL_SLOCK_CTOR(l) ((l) = http_request_datashare_locks_init()) -# define HTTP_CURL_SLOCK_DTOR(lp) http_request_datashare_locks_dtor(*(lp)); *(lp) = NULL -#endif static HashTable http_request_datashare_options; static http_request_datashare http_request_datashare_global; @@ -57,15 +43,13 @@ PHP_MINIT_FUNCTION(http_request_datashare) { curl_lock_data val; -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - if (SUCCESS != http_persistent_handle_provide("http_request_datashare", curl_share_init, (http_persistent_handle_dtor) curl_share_cleanup)) { + if (SUCCESS != http_persistent_handle_provide("http_request_datashare", curl_share_init, (http_persistent_handle_dtor) curl_share_cleanup, NULL)) { return FAILURE; } -# ifdef ZTS - if (SUCCESS != http_persistent_handle_provide("http_request_datashare_lock", http_request_datashare_locks_init, http_request_datashare_locks_dtor)) { +#ifdef ZTS + if (SUCCESS != http_persistent_handle_provide("http_request_datashare_lock", http_request_datashare_locks_init, http_request_datashare_locks_dtor, NULL)) { return FAILURE; } -# endif #endif if (!http_request_datashare_init_ex(&http_request_datashare_global, 1)) { @@ -115,7 +99,7 @@ PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_reques } memset(share, 0, sizeof(http_request_datashare)); - if (!HTTP_CURL_SHARE_CTOR(share->ch)) { + if (SUCCESS != http_persistent_handle_acquire("http_request_datashare", &share->ch)) { if (free_share) { pefree(share, persistent); } @@ -127,10 +111,10 @@ PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_reques zend_llist_init(share->handle.list, sizeof(zval *), ZVAL_PTR_DTOR, 0); #ifdef ZTS } else { - if (HTTP_CURL_SLOCK_CTOR(share->handle.locks)) { + if (SUCCESS == http_persistent_handle_acquire("http_request_datashare_lock", (void *) &share->handle.locks)) { curl_share_setopt(share->ch, CURLSHOPT_LOCKFUNC, http_request_datashare_lock_func); curl_share_setopt(share->ch, CURLSHOPT_UNLOCKFUNC, http_request_datashare_unlock_func); - curl_share_setopt(share->ch, CURLSHOPT_USERDATA, share); + curl_share_setopt(share->ch, CURLSHOPT_USERDATA, share->handle.locks); } #endif } @@ -198,10 +182,10 @@ PHP_HTTP_API void _http_request_datashare_dtor(http_request_datashare *share TSR zend_llist_destroy(share->handle.list); efree(share->handle.list); } - HTTP_CURL_SHARE_DTOR(&share->ch); + http_persistent_handle_release("http_request_datashare", &share->ch); #ifdef ZTS if (share->persistent) { - HTTP_CURL_SLOCK_DTOR(&share->handle.locks); + http_persistent_handle_release("http_request_datashare_lock", (void *) &share->handle.locks); } #endif } @@ -273,19 +257,19 @@ static void http_request_datashare_locks_dtor(void *l) static void http_request_datashare_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr) { - http_request_datashare *share = (http_request_datashare *) userptr; + http_request_datashare_lock *locks = (http_request_datashare_lock *) userptr; /* TSRM can't distinguish shared/exclusive locks */ - tsrm_mutex_lock(share->handle.locks[data].mx); - share->handle.locks[data].ch = handle; + tsrm_mutex_lock(locks[data].mx); + locks[data].ch = handle; } static void http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr) { - http_request_datashare *share = (http_request_datashare *) userptr; + http_request_datashare_lock *locks = (http_request_datashare_lock *) userptr; - if (share->handle.locks[data].ch == handle) { - tsrm_mutex_unlock(share->handle.locks[data].mx); + if (locks[data].ch == handle) { + tsrm_mutex_unlock(locks[data].mx); } } #endif diff --git a/http_request_object.c b/http_request_object.c index a380125..49e9103 100644 --- a/http_request_object.c +++ b/http_request_object.c @@ -484,7 +484,7 @@ zend_object_value _http_request_object_clone_obj(zval *this_ptr TSRMLS_DC) new_ov = http_request_object_new_ex(old_obj->zo.ce, NULL, &new_obj); if (old_obj->request->ch) { - http_curl_init_ex(curl_easy_duphandle(old_obj->request->ch), new_obj->request); + http_curl_init_ex(http_curl_copy(old_obj->request->ch), new_obj->request); } zend_objects_clone_members(&new_obj->zo, new_ov, &old_obj->zo, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); diff --git a/http_request_pool_api.c b/http_request_pool_api.c index 1c263af..27e1f0d 100644 --- a/http_request_pool_api.c +++ b/http_request_pool_api.c @@ -19,35 +19,25 @@ #include "php_http_api.h" #include "php_http_exception_object.h" +#include "php_http_persistent_handle_api.h" #include "php_http_request_api.h" #include "php_http_request_object.h" #include "php_http_request_pool_api.h" #include "php_http_requestpool_object.h" -#include "php_http_persistent_handle_api.h" #ifndef HTTP_DEBUG_REQPOOLS # define HTTP_DEBUG_REQPOOLS 0 #endif -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# define HTTP_CURL_MULTI_CTOR(ch) (SUCCESS == http_persistent_handle_acquire("http_request_pool", &(ch))) -# define HTTP_CURL_MULTI_DTOR(chp) http_persistent_handle_release("http_request_pool", (chp)) -#else -# define HTTP_CURL_MULTI_CTOR(ch) ((ch) = curl_multi_init()) -# define HTTP_CURL_MULTI_DTOR(chp) curl_multi_cleanup(*(chp)); *(chp) = NULL -#endif - static int http_request_pool_compare_handles(void *h1, void *h2); -#ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_MINIT_FUNCTION(http_request_pool) { - if (SUCCESS != http_persistent_handle_provide("http_request_pool", curl_multi_init, (http_persistent_handle_dtor) curl_multi_cleanup)) { + if (SUCCESS != http_persistent_handle_provide("http_request_pool", curl_multi_init, (http_persistent_handle_dtor) curl_multi_cleanup, NULL)) { return FAILURE; } return SUCCESS; } -#endif /* {{{ http_request_pool *http_request_pool_init(http_request_pool *) */ PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool TSRMLS_DC) @@ -63,7 +53,7 @@ PHP_HTTP_API http_request_pool *_http_request_pool_init(http_request_pool *pool pool->ch = NULL; } - if (!HTTP_CURL_MULTI_CTOR(pool->ch)) { + if (SUCCESS != http_persistent_handle_acquire("http_request_pool", &pool->ch)) { if (free_pool) { efree(pool); } @@ -259,7 +249,7 @@ PHP_HTTP_API void _http_request_pool_dtor(http_request_pool *pool TSRMLS_DC) pool->unfinished = 0; zend_llist_clean(&pool->finished); zend_llist_clean(&pool->handles); - HTTP_CURL_MULTI_DTOR(&pool->ch); + http_persistent_handle_release("http_request_pool", &pool->ch); } /* }}} */ diff --git a/php_http.h b/php_http.h index 005498b..44ef1f9 100644 --- a/php_http.h +++ b/php_http.h @@ -138,9 +138,9 @@ ZEND_BEGIN_MODULE_GLOBALS(http) #endif } request; -#ifdef HTTP_HAVE_PERSISTENT_HANDLES struct _http_globals_persistent { struct _http_globals_persistent_handles { + ulong limit; struct _http_globals_persistent_handles_ident { ulong h; char *s; @@ -148,7 +148,7 @@ ZEND_BEGIN_MODULE_GLOBALS(http) } ident; } handles; } persistent; -#endif + #ifdef ZEND_ENGINE_2 zend_bool only_exceptions; #endif @@ -213,12 +213,10 @@ PHP_FUNCTION(http_get_request_headers); PHP_FUNCTION(http_get_request_body); PHP_FUNCTION(http_get_request_body_stream); PHP_FUNCTION(http_match_request_header); -#ifdef HTTP_HAVE_CURL -# ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_FUNCTION(http_persistent_handles_count); PHP_FUNCTION(http_persistent_handles_clean); PHP_FUNCTION(http_persistent_handles_ident); -# endif +#ifdef HTTP_HAVE_CURL PHP_FUNCTION(http_get); PHP_FUNCTION(http_head); PHP_FUNCTION(http_post_data); diff --git a/php_http_persistent_handle_api.h b/php_http_persistent_handle_api.h index fc5507c..8e00a0e 100644 --- a/php_http_persistent_handle_api.h +++ b/php_http_persistent_handle_api.h @@ -15,24 +15,24 @@ #ifndef HTTP_PERSISTENT_HANDLE_H #define HTTP_PERSISTENT_HANDLE_H -#ifdef HTTP_HAVE_PERSISTENT_HANDLES typedef void *(*http_persistent_handle_ctor)(void); typedef void (*http_persistent_handle_dtor)(void *handle); +typedef void *(*http_persistent_handle_copy)(void *handle); PHP_MINIT_FUNCTION(http_persistent_handle); PHP_MSHUTDOWN_FUNCTION(http_persistent_handle); -#define http_persistent_handle_provide(n, c, d) _http_persistent_handle_provide_ex((n), strlen(n), (c), (d)) -#define http_persistent_handle_provide_ex(n, l, c, d) _http_persistent_handle_provide_ex((n), (l), (c), (d)) -PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor); +#define http_persistent_handle_provide(n, c, d, cc) _http_persistent_handle_provide_ex((n), strlen(n), (c), (d), (cc)) +#define http_persistent_handle_provide_ex(n, l, c, d, cc) _http_persistent_handle_provide_ex((n), (l), (c), (d), (cc)) +PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor, http_persistent_handle_copy copy); #define http_persistent_handle_cleanup(n, c) _http_persistent_handle_cleanup_ex((n), strlen(n), (c) TSRMLS_CC) #define http_persistent_handle_cleanup_ex(n, l,c ) _http_persistent_handle_cleanup_ex((n), (l), (c) TSRMLS_CC) PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_t name_len, int current_ident_only TSRMLS_DC); -#define http_persistent_handle_statall() _http_persistent_handle_statall_ex(NULL) -#define http_persistent_handle_statall_ex(ht) _http_persistent_handle_statall_ex((ht)) -PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht); +#define http_persistent_handle_statall() _http_persistent_handle_statall_ex(NULL TSRMLS_CC) +#define http_persistent_handle_statall_ex(ht) _http_persistent_handle_statall_ex((ht) TSRMLS_CC) +PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht TSRMLS_DC); #define http_persistent_handle_acquire(n, h) _http_persistent_handle_acquire_ex((n), strlen(n), (h) TSRMLS_CC) #define http_persistent_handle_acquire_ex(n, l, h) _http_persistent_handle_acquire_ex((n), (l), (h) TSRMLS_CC) @@ -42,7 +42,10 @@ PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, siz #define http_persistent_handle_release_ex(n, l, h) _http_persistent_handle_release_ex((n), (l), (h) TSRMLS_CC) PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, size_t name_len, void **handle TSRMLS_DC); -#endif /* HTTP_HAVE_PERSISTENT_HANDLES */ +#define http_persistent_handle_accrete(n, oh, nh) _http_persistent_handle_accrete_ex((n), strlen(n), (oh), (nh) TSRMLS_CC) +#define http_persistent_handle_accrete_ex(n, l, oh, nh) _http_persistent_handle_accrete_ex((n), (l), (oh), (nh) TSRMLS_CC) +PHP_HTTP_API STATUS _http_persistent_handle_accrete_ex(const char *name_str, size_t name_len, void *old_handle, void **new_handle TSRMLS_DC); + #endif /* HTTP_PERSISTENT_HANDLE_H */ /* diff --git a/php_http_request_api.h b/php_http_request_api.h index dfc50f6..65d62e1 100644 --- a/php_http_request_api.h +++ b/php_http_request_api.h @@ -59,6 +59,9 @@ PHP_HTTP_API CURL *_http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC) #define http_curl_free(c) _http_curl_free((c) TSRMLS_CC) PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC); +#define http_curl_copy(c) _http_curl_copy((c) TSRMLS_CC) +PHP_HTTP_API CURL *_http_curl_copy(CURL *ch TSRMLS_DC); + #define http_request_new() _http_request_init_ex(NULL, NULL, 0, NULL ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC) #define http_request_init(r) _http_request_init_ex((r), NULL, 0, NULL ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC) #define http_request_init_ex(r, c, m, u) _http_request_init_ex((r), (c), (m), (u) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC TSRMLS_CC) diff --git a/php_http_request_pool_api.h b/php_http_request_pool_api.h index 4523b49..34294a9 100644 --- a/php_http_request_pool_api.h +++ b/php_http_request_pool_api.h @@ -26,9 +26,7 @@ typedef struct _http_request_pool_t { typedef int (*http_request_pool_apply_func)(http_request_pool *pool, zval *request TSRMLS_DC); typedef int (*http_request_pool_apply_with_arg_func)(http_request_pool *pool, zval *request, void *arg TSRMLS_DC); -#ifdef HTTP_HAVE_PERSISTENT_HANDLES PHP_MINIT_FUNCTION(http_request_pool); -#endif #define http_request_pool_responsehandler(p, r, c) _http_request_pool_responsehandler((p), (r), (c) TSRMLS_CC) extern int _http_request_pool_responsehandler(http_request_pool *pool, zval *req, void *ch TSRMLS_DC); diff --git a/tests/persistent_handles_001.phpt b/tests/persistent_handles_001.phpt index f5a6309..45332d9 100644 --- a/tests/persistent_handles_001.phpt +++ b/tests/persistent_handles_001.phpt @@ -3,65 +3,88 @@ persistent handles --SKIPIF-- --INI-- +http.persistent.handles.limit=-1 http.persistent.handles.ident=GLOBAL --FILE-- $idents) { + foreach ((array)$idents as $ident => $counts) { + if (!empty($counts["free"])) { + printf("%s, %s, %s\n", $provider, $ident, $counts["free"]); + } + } +} + http_get("http://www.google.com/", null, $info[]); -echo "One free request handle within GLOBAL:\n"; -var_dump(http_persistent_handles_count()->http_request["GLOBAL"]); -echo "Reusing request handle:\n"; + +echo "One free request handle within GLOBAL: "; +var_dump(http_persistent_handles_count()->http_request["GLOBAL"]["free"]); + +echo "Reusing request handle: "; http_get("http://www.google.com/", null, $info[]); -var_dump($info[0]["pretransfer_time"] > 100 * $info[1]["pretransfer_time"], $info[0]["pretransfer_time"], $info[1]["pretransfer_time"]); +var_dump($info[0]["pretransfer_time"] > 10 * $info[1]["pretransfer_time"], $info[0]["pretransfer_time"], $info[1]["pretransfer_time"]); + echo "Handles' been cleaned up:\n"; -#http_persistent_handles_clean(); -var_dump(http_persistent_handles_count()); +http_persistent_handles_clean(); +print_r(http_persistent_handles_count()); + echo "Done\n"; ?> --EXPECTF-- %sTEST -No free handles: -object(stdClass)#%d (%d) { - ["http_request_pool"]=> - array(0) { - } - ["http_request"]=> - array(0) { - } - ["http_request_datashare"]=> - array(0) { - } - ["http_request_datashare_lock"]=> - array(0) { - } -} -One free request handle within GLOBAL: -int(1) -Reusing request handle: -bool(true) +No free handles! +One free request handle within GLOBAL: int(1) +Reusing request handle: bool(true) float(%f) float(%f) Handles' been cleaned up: -object(stdClass)#%d (%d) { - ["http_request_pool"]=> - array(0) { - } - ["http_request"]=> - array(1) { - ["GLOBAL"]=> - int(1) - } - ["http_request_datashare"]=> - array(0) { - } - ["http_request_datashare_lock"]=> - array(0) { - } -} +stdClass Object +( + [http_request] => Array + ( + [GLOBAL] => Array + ( + [used] => 0 + [free] => 0 + ) + + ) + + [http_request_pool] => Array + ( + [GLOBAL] => Array + ( + [used] => 0 + [free] => 0 + ) + + ) + + [http_request_datashare] => Array + ( + [GLOBAL] => Array + ( + [used] => 0 + [free] => 0 + ) + + ) + + [http_request_datashare_lock] => Array + ( + [GLOBAL] => Array + ( + [used] => 0 + [free] => 0 + ) + + ) + +) Done -- 2.30.2