X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_request_datashare_api.c;h=1f48b7c0196c1e1fe9b35b8832820650494eab30;hp=efcdb848e657fd346b637a41560480ae4bddcbe5;hb=ad5f896b03adaa073134a00108a9cdf00720673a;hpb=d22651c805eca6f0d508c6d5a47e8daac36841fe diff --git a/http_request_datashare_api.c b/http_request_datashare_api.c index efcdb84..1f48b7c 100644 --- a/http_request_datashare_api.c +++ b/http_request_datashare_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-2010, Michael Wallner | +--------------------------------------------------------------------+ */ @@ -18,19 +18,21 @@ #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" -#ifndef HAVE_CURL_SHARE_STRERROR -# define curl_share_strerror(dummy) "unknown error" -#endif - static HashTable http_request_datashare_options; static http_request_datashare http_request_datashare_global; static int http_request_datashare_compare_handles(void *h1, void *h2); +static void http_request_datashare_destroy_handles(void *el); +#ifdef ZTS +static void *http_request_datashare_locks_init(void); +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); static void http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr); +#endif http_request_datashare *_http_request_datashare_global_get(void) { @@ -41,6 +43,19 @@ PHP_MINIT_FUNCTION(http_request_datashare) { curl_lock_data val; + 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, NULL)) { + return FAILURE; + } +#endif + + if (!http_request_datashare_init_ex(&http_request_datashare_global, 1)) { + return FAILURE; + } + zend_hash_init(&http_request_datashare_options, 4, NULL, NULL, 1); #define ADD_DATASHARE_OPT(name, opt) \ val = opt; \ @@ -50,8 +65,6 @@ PHP_MINIT_FUNCTION(http_request_datashare) ADD_DATASHARE_OPT("ssl", CURL_LOCK_DATA_SSL_SESSION); ADD_DATASHARE_OPT("connect", CURL_LOCK_DATA_CONNECT); - http_request_datashare_init_ex(&http_request_datashare_global, 1); - return SUCCESS; } @@ -63,9 +76,22 @@ PHP_MSHUTDOWN_FUNCTION(http_request_datashare) return SUCCESS; } +PHP_RINIT_FUNCTION(http_request_datashare) +{ + zend_llist_init(&HTTP_G->request.datashare.handles, sizeof(zval *), http_request_datashare_destroy_handles, 0); + + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(http_request_datashare) +{ + zend_llist_destroy(&HTTP_G->request.datashare.handles); + + return SUCCESS; +} + PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_request_datashare *share, zend_bool persistent TSRMLS_DC) { - int i; zend_bool free_share; if ((free_share = !share)) { @@ -73,26 +99,26 @@ PHP_HTTP_API http_request_datashare *_http_request_datashare_init_ex(http_reques } memset(share, 0, sizeof(http_request_datashare)); - HTTP_CHECK_CURL_INIT(share->ch, curl_share_init(), ;); - if (!share->ch) { + if (SUCCESS != http_persistent_handle_acquire("http_request_datashare", &share->ch)) { if (free_share) { pefree(share, persistent); } return NULL; } - if ((share->persistent = persistent)) { - share->locks = pecalloc(CURL_LOCK_DATA_LAST, sizeof(http_request_datashare_lock), 1); - for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) { - share->locks[i].mx = tsrm_mutex_alloc(); + if (!(share->persistent = persistent)) { + share->handle.list = emalloc(sizeof(zend_llist)); + zend_llist_init(share->handle.list, sizeof(zval *), ZVAL_PTR_DTOR, 0); +#ifdef ZTS + } else { + 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->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); +#endif } - zend_llist_init(&share->handles, sizeof(zval *), ZVAL_PTR_DTOR, persistent); - return share; } @@ -109,14 +135,15 @@ PHP_HTTP_API STATUS _http_request_datashare_attach(http_request_datashare *share } } + HTTP_CHECK_CURL_INIT(obj->request->ch, http_curl_init_ex(obj->request->ch, obj->request), return FAILURE); if (CURLE_OK != (rc = curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, share->ch))) { - http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not attach HttpRequest object(#%d) to the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_share_strerror(rc)); + http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not attach HttpRequest object(#%d) to the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_easy_strerror(rc)); return FAILURE; } obj->share = share; ZVAL_ADDREF(request); - zend_llist_add_element(&share->handles, (void *) &request); + zend_llist_add_element(HTTP_RSHARE_HANDLES(share), (void *) &request); return SUCCESS; } @@ -134,7 +161,7 @@ PHP_HTTP_API STATUS _http_request_datashare_detach(http_request_datashare *share http_error_ex(HE_WARNING, HTTP_E_REQUEST, "Could not detach HttpRequest object(#%d) from the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_share_strerror(rc)); } else { obj->share = NULL; - zend_llist_del_element(&share->handles, request, http_request_datashare_compare_handles); + zend_llist_del_element(HTTP_RSHARE_HANDLES(share), request, http_request_datashare_compare_handles); return SUCCESS; } return FAILURE; @@ -144,23 +171,23 @@ PHP_HTTP_API void _http_request_datashare_detach_all(http_request_datashare *sha { zval **r; - while ((r = zend_llist_get_first(&share->handles))) { + while ((r = zend_llist_get_first(HTTP_RSHARE_HANDLES(share)))) { http_request_datashare_detach(share, *r); } } PHP_HTTP_API void _http_request_datashare_dtor(http_request_datashare *share TSRMLS_DC) { - int i; - - zend_llist_destroy(&share->handles); - curl_share_cleanup(share->ch); + if (!share->persistent) { + zend_llist_destroy(share->handle.list); + efree(share->handle.list); + } + http_persistent_handle_release("http_request_datashare", &share->ch); +#ifdef ZTS if (share->persistent) { - for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) { - tsrm_mutex_free(share->locks[i].mx); - } - pefree(share->locks, 1); + http_persistent_handle_release("http_request_datashare_lock", (void *) &share->handle.locks); } +#endif } PHP_HTTP_API void _http_request_datashare_free(http_request_datashare **share TSRMLS_DC) @@ -189,23 +216,63 @@ static int http_request_datashare_compare_handles(void *h1, void *h2) return (Z_OBJ_HANDLE_PP((zval **) h1) == Z_OBJ_HANDLE_P((zval *) h2)); } +static void http_request_datashare_destroy_handles(void *el) +{ + zval **r = (zval **) el; + TSRMLS_FETCH(); + + { /* gcc 2.95 needs these braces */ + getObjectEx(http_request_object, obj, *r); + + curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, NULL); + zval_ptr_dtor(r); + } +} + +#ifdef ZTS +static void *http_request_datashare_locks_init(void) +{ + int i; + http_request_datashare_lock *locks = pecalloc(CURL_LOCK_DATA_LAST, sizeof(http_request_datashare_lock), 1); + + if (locks) { + for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) { + locks[i].mx = tsrm_mutex_alloc(); + } + } + + return locks; +} + +static void http_request_datashare_locks_dtor(void *l) +{ + int i; + http_request_datashare_lock *locks = (http_request_datashare_lock *) l; + + for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) { + tsrm_mutex_free(locks[i].mx); + } + pefree(locks, 1); +} + 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->locks[data].mx); - share->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->locks[data].ch == handle) { - tsrm_mutex_unlock(share->locks[data].mx); + if (locks[data].ch == handle) { + tsrm_mutex_unlock(locks[data].mx); } } +#endif #endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */