X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_persistent_handle_api.c;h=b07caffdda4220966b5dc4564d48292387fd6a20;hp=a2e0ba908b258b6cc9e5b8750b69d306aefd5b54;hb=18dc0cdcdaf502f2cf2ad9e824212cfab0df7808;hpb=e5e656c7f4a22c11763c6519b899523734e93015 diff --git a/http_persistent_handle_api.c b/http_persistent_handle_api.c index a2e0ba9..b07caff 100644 --- a/http_persistent_handle_api.c +++ b/http_persistent_handle_api.c @@ -6,7 +6,7 @@ | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ - | Copyright (c) 2004-2006, Michael Wallner | + | Copyright (c) 2004-2007, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -18,6 +18,10 @@ #ifdef HTTP_HAVE_PERSISTENT_HANDLES #include "php_http_persistent_handle_api.h" +#ifndef HTTP_DEBUG_PHANDLES +# define HTTP_DEBUG_PHANDLES 0 +#endif + static HashTable http_persistent_handles_hash; #ifdef ZTS # define LOCK() tsrm_mutex_lock(http_persistent_handles_lock) @@ -40,17 +44,53 @@ typedef struct _http_persistent_handle_provider_t { http_persistent_handle_dtor dtor; } 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) +{ + http_persistent_handle_list new_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 (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); + } + } + + return FAILURE; +} + +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) { +#if HTTP_DEBUG_PHANDLES + fprintf(stderr, "DESTROY: %p\n", handle->ptr); +#endif + + dtor(handle->ptr); + } + zend_hash_clean(list); +} + 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 *handle; - HashPosition pos1, pos2; + HashPosition pos; - FOREACH_HASH_VAL(pos1, provider->list, list) { - FOREACH_HASH_VAL(pos2, *list, handle) { - provider->dtor(handle->ptr); - } + FOREACH_HASH_VAL(pos, provider->list, list) { + http_persistent_handle_list_dtor(*list, provider->dtor); zend_hash_destroy(*list); pefree(*list, 1); } @@ -87,6 +127,11 @@ PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, siz provider.ctor = ctor; provider.dtor = dtor; zend_hash_init(provider.list, 0, NULL, NULL, 1); + +#if HTTP_DEBUG_PHANDLES + fprintf(stderr, "PROVIDE: %p (%s)\n", provider.list, 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 { @@ -109,7 +154,7 @@ PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, siz *handle_ptr = NULL; LOCK(); if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &provider)) { - if (SUCCESS == zend_hash_quick_find(provider->list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) { + 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; @@ -122,6 +167,10 @@ PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, siz } UNLOCK(); +#if HTTP_DEBUG_PHANDLES + fprintf(stderr, "ACQUIRE: %p (%s)\n", *handle_ptr, name_str); +#endif + return status; } @@ -129,25 +178,22 @@ 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, new_list; + 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 == zend_hash_quick_find(provider->list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) { - status = zend_hash_next_index_insert(*list, (void *) &handle, sizeof(http_persistent_handle), NULL); - } else if ((new_list = pemalloc(sizeof(HashTable), 1))) { - zend_hash_init(new_list, 0, NULL, NULL, 1); - if ( SUCCESS == zend_hash_next_index_insert(new_list, (void *) &handle, sizeof(http_persistent_handle), NULL) && - SUCCESS == zend_hash_quick_add(provider->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 *), NULL)) { - status = SUCCESS; - } else { - pefree(new_list, 1); - } + 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; } } UNLOCK(); +#if HTTP_DEBUG_PHANDLES + fprintf(stderr, "RELEASE: %p (%s)\n", *handle_ptr, name_str); +#endif + return status; } @@ -155,43 +201,30 @@ PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_ { http_persistent_handle_provider *provider; http_persistent_handle_list *list; - http_persistent_handle *handle; - HashPosition pos1, pos2, pos3; + 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 == zend_hash_quick_find(provider->list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) { - FOREACH_HASH_VAL(pos1, *list, handle) { - provider->dtor(handle->ptr); - } - zend_hash_clean(*list); + if (SUCCESS == http_persistent_handle_list_find(provider->list, &list, 0 TSRMLS_CC)) { + http_persistent_handle_list_dtor(*list, provider->dtor); } } else { FOREACH_HASH_VAL(pos1, provider->list, list) { - FOREACH_HASH_VAL(pos2, *list, handle) { - provider->dtor(handle->ptr); - } - zend_hash_clean(*list); + http_persistent_handle_list_dtor(*list, provider->dtor); } } } } else { FOREACH_HASH_VAL(pos1, &http_persistent_handles_hash, provider) { if (current_ident_only) { - if (SUCCESS == zend_hash_quick_find(provider->list, HTTP_G->persistent.handles.ident.s, HTTP_G->persistent.handles.ident.l, HTTP_G->persistent.handles.ident.h, (void *) &list)) { - FOREACH_HASH_VAL(pos2, *list, handle) { - provider->dtor(handle->ptr); - } - zend_hash_clean(*list); + if (SUCCESS == http_persistent_handle_list_find(provider->list, &list, 0 TSRMLS_CC)) { + http_persistent_handle_list_dtor(*list, provider->dtor); } } else { FOREACH_HASH_VAL(pos2, provider->list, list) { - FOREACH_HASH_VAL(pos3, *list, handle) { - provider->dtor(handle->ptr); - } - zend_hash_clean(*list); + http_persistent_handle_list_dtor(*list, provider->dtor); } } } @@ -220,9 +253,9 @@ PHP_HTTP_API HashTable *_http_persistent_handle_statall_ex(HashTable *ht) FOREACH_HASH_KEYVAL(pos2, provider->list, key2, list) { MAKE_STD_ZVAL(zentry); ZVAL_LONG(zentry, zend_hash_num_elements(*list)); - zend_hash_quick_add(Z_ARRVAL_P(zlist), key2.str, key2.len, key2.num, (void *) &zentry, sizeof(zval *), NULL); + zend_hash_add(Z_ARRVAL_P(zlist), key2.str, key2.len, (void *) &zentry, sizeof(zval *), NULL); } - zend_hash_quick_add(ht, key1.str, key1.len, key1.num, (void *) &zlist, sizeof(zval *), NULL); + zend_hash_add(ht, key1.str, key1.len, (void *) &zlist, sizeof(zval *), NULL); } } else if (ht) { ht = NULL;