push a load of changes before holidays
[m6w6/ext-http] / php_http_request_datashare.c
index c1df14bd41f7427b3a8d281a1a2a1499522447b0..68e4c073eadefe4e869be5aa702b83af39987314 100644 (file)
 
 #include "php_http.h"
 
-static HashTable php_http_request_datashare_options;
-static php_http_request_datashare_t php_http_request_datashare_global;
+#include <ext/standard/php_string.h>
+#include <ext/spl/spl_iterators.h>
+
 static int php_http_request_datashare_compare_handles(void *h1, void *h2);
-static void php_http_request_datashare_destroy_handles(void *el);
 
 #ifdef ZTS
 static void *php_http_request_datashare_locks_init(void);
 static void php_http_request_datashare_locks_dtor(void *l);
 static void php_http_request_datashare_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr);
 static void php_http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr);
+static MUTEX_T php_http_request_datashare_global_shares_lock;
 #endif
-
-php_http_request_datashare_t *php_http_request_datashare_global_get(void)
-{
-       return &php_http_request_datashare_global;
-}
-
-PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *share, zend_bool persistent TSRMLS_DC)
+static HashTable php_http_request_datashare_global_shares;
+php_http_request_datashare_t *php_http_request_datashare_global_get(const char *driver_str, size_t driver_len TSRMLS_DC)
 {
-       zend_bool free_share;
+       php_http_request_datashare_t *s = NULL, **s_ptr;
+       char *lower_str = php_strtolower(estrndup(driver_str, driver_len), driver_len);
 
-       if ((free_share = !share)) {
-               share = pemalloc(sizeof(php_http_request_datashare_t), persistent);
-       }
-       memset(share, 0, sizeof(php_http_request_datashare_t));
+#ifdef ZTS
+       tsrm_mutex_lock(php_http_request_datashare_global_shares_lock);
+#endif
+       if (zend_hash_find(&php_http_request_datashare_global_shares, lower_str, driver_len + 1, (void *) &s_ptr)) {
+               s = *s_ptr;
+       } else {
+               php_http_request_factory_driver_t driver;
 
-       if (SUCCESS != php_http_persistent_handle_acquire(ZEND_STRL("http_request_datashare"), &share->ch TSRMLS_CC)) {
-               if (free_share) {
-                       pefree(share, persistent);
+               if ((SUCCESS == php_http_request_factory_get_driver(driver_str, driver_len, &driver)) && driver.request_datashare_ops) {
+                       s = php_http_request_datashare_init(NULL, driver.request_datashare_ops, NULL, 1 TSRMLS_CC);
+                       zend_hash_add(&php_http_request_datashare_global_shares, lower_str, driver_len + 1, &s, sizeof(php_http_request_datashare_t *), NULL);
                }
-               return NULL;
        }
-
-       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 == php_http_persistent_handle_acquire(ZEND_STRL("http_request_datashare_lock"), (void *) &share->handle.locks)) {
-                       curl_share_setopt(share->ch, CURLSHOPT_LOCKFUNC, php_http_request_datashare_lock_func);
-                       curl_share_setopt(share->ch, CURLSHOPT_UNLOCKFUNC, php_http_request_datashare_unlock_func);
-                       curl_share_setopt(share->ch, CURLSHOPT_USERDATA, share->handle.locks);
-               }
+       tsrm_mutex_unlock(php_http_request_datashare_global_shares_lock);
 #endif
-       }
-
-       TSRMLS_SET_CTX(share->ts);
 
-       return share;
+       efree(lower_str);
+       return s;
 }
 
-PHP_HTTP_API STATUS php_http_request_datashare_attach(php_http_request_datashare_t *share, zval *request)
+PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_init(php_http_request_datashare_t *h, php_http_request_datashare_ops_t *ops, void *init_arg, zend_bool persistent TSRMLS_DC)
 {
-       CURLcode rc;
-       TSRMLS_FETCH_FROM_CTX(share->ts);
-       php_http_request_object_t *obj = zend_object_store_get_object(request TSRMLS_CC);
+       php_http_request_datashare_t *free_h;
 
-       if (obj->share) {
-               if (obj->share == share)  {
-                       return SUCCESS;
-               } else if (SUCCESS != php_http_request_datashare_detach(obj->share, request)) {
-                       return FAILURE;
-               }
+       if (!h) {
+               free_h = h = pemalloc(sizeof(*h), persistent);
        }
+       memset(h, sizeof(*h), 0);
 
-       PHP_HTTP_CHECK_CURL_INIT(obj->request->ch, php_http_curl_init(obj->request->ch, obj->request TSRMLS_CC), return FAILURE);
-       if (CURLE_OK != (rc = curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, share->ch))) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "Could not attach HttpRequest object(#%d) to the HttpRequestDataShare: %s", Z_OBJ_HANDLE_P(request), curl_easy_strerror(rc));
-               return FAILURE;
+       if (!(h->persistent = persistent)) {
+               h->requests = emalloc(sizeof(*h->requests));
+               zend_llist_init(h->requests, sizeof(zval *), ZVAL_PTR_DTOR, 0);
+               TSRMLS_SET_CTX(h->ts);
        }
+       h->ops = ops;
 
-       obj->share = share;
-       Z_ADDREF_P(request);
-       zend_llist_add_element(PHP_HTTP_RSHARE_HANDLES(share), (void *) &request);
+       if (h->ops->init) {
+               if (!(h = h->ops->init(h, init_arg))) {
+                       if (free_h) {
+                               pefree(free_h, persistent);
+                       }
+               }
+       }
 
-       return SUCCESS;
+       return h;
 }
 
-PHP_HTTP_API STATUS php_http_request_datashare_detach(php_http_request_datashare_t *share, zval *request)
+PHP_HTTP_API php_http_request_datashare_t *php_http_request_datashare_copy(php_http_request_datashare_t *from, php_http_request_datashare_t *to)
 {
-       CURLcode rc;
-       TSRMLS_FETCH_FROM_CTX(share->ts);
-       php_http_request_object_t *obj = zend_object_store_get_object(request TSRMLS_CC);
-
-       if (!obj->share) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "HttpRequest object(#%d) is not attached to any HttpRequestDataShare", Z_OBJ_HANDLE_P(request));
-       } else if (obj->share != share) {
-               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "HttpRequest object(#%d) is not attached to this HttpRequestDataShare", Z_OBJ_HANDLE_P(request));
-       } else if (CURLE_OK != (rc = curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, NULL))) {
-               php_http_error(HE_WARNING, PHP_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(PHP_HTTP_RSHARE_HANDLES(share), request, php_http_request_datashare_compare_handles);
-               return SUCCESS;
+       if (from->ops->copy) {
+               return from->ops->copy(from, to);
        }
-       return FAILURE;
-}
 
-PHP_HTTP_API void php_http_request_datashare_detach_all(php_http_request_datashare_t *share)
-{
-       zval **r;
-
-       while ((r = zend_llist_get_first(PHP_HTTP_RSHARE_HANDLES(share)))) {
-               php_http_request_datashare_detach(share, *r);
-       }
+       return NULL;
 }
 
-PHP_HTTP_API void php_http_request_datashare_dtor(php_http_request_datashare_t *share)
+PHP_HTTP_API void php_http_request_datashare_dtor(php_http_request_datashare_t *h)
 {
-       TSRMLS_FETCH_FROM_CTX(share->ts);
-
-       if (!share->persistent) {
-               zend_llist_destroy(share->handle.list);
-               efree(share->handle.list);
+       if (h->ops->dtor) {
+               h->ops->dtor(h);
        }
-       php_http_persistent_handle_release(ZEND_STRL("http_request_datashare"), &share->ch TSRMLS_CC);
-#ifdef ZTS
-       if (share->persistent) {
-               php_http_persistent_handle_release(ZEND_STRL("http_request_datashare_lock"), (void *) &share->handle.locks TSRMLS_CC);
+       if (h->requests) {
+               zend_llist_destroy(h->requests);
+               pefree(h->requests, h->persistent);
+               h->requests = NULL;
        }
-#endif
 }
 
-PHP_HTTP_API void php_http_request_datashare_free(php_http_request_datashare_t **share)
+PHP_HTTP_API void php_http_request_datashare_free(php_http_request_datashare_t **h)
 {
-       php_http_request_datashare_dtor(*share);
-       pefree(*share, (*share)->persistent);
-       *share = NULL;
+       php_http_request_datashare_dtor(*h);
+       pefree(*h, (*h)->persistent);
+       *h = NULL;
 }
 
-PHP_HTTP_API STATUS php_http_request_datashare_set(php_http_request_datashare_t *share, const char *option, size_t option_len, zend_bool enable)
+PHP_HTTP_API STATUS php_http_request_datashare_attach(php_http_request_datashare_t *h, zval *request)
 {
-       curl_lock_data *opt;
-       CURLSHcode rc;
-       TSRMLS_FETCH_FROM_CTX(share->ts);
+       TSRMLS_FETCH_FROM_CTX(h->ts);
+
+       if (h->ops->attach) {
+               php_http_request_object_t *obj = zend_object_store_get_object(request TSRMLS_CC);
 
-       if (SUCCESS == zend_hash_find(&php_http_request_datashare_options, (char *) option, option_len + 1, (void *) &opt)) {
-               if (CURLSHE_OK == (rc = curl_share_setopt(share->ch, enable ? CURLSHOPT_SHARE : CURLSHOPT_UNSHARE, *opt))) {
+               if (SUCCESS == h->ops->attach(h, obj->request)) {
+                       Z_ADDREF_P(request);
+                       zend_llist_add_element(PHP_HTTP_REQUEST_DATASHARE_REQUESTS(h), &request);
                        return SUCCESS;
                }
-               php_http_error(HE_WARNING, PHP_HTTP_E_REQUEST, "Could not %s sharing of %s data: %s",  enable ? "enable" : "disable", option, curl_share_strerror(rc));
        }
+
        return FAILURE;
 }
 
@@ -151,70 +117,60 @@ static int php_http_request_datashare_compare_handles(void *h1, void *h2)
        return (Z_OBJ_HANDLE_PP((zval **) h1) == Z_OBJ_HANDLE_P((zval *) h2));
 }
 
-static void php_http_request_datashare_destroy_handles(void *el)
+PHP_HTTP_API STATUS php_http_request_datashare_detach(php_http_request_datashare_t *h, zval *request)
 {
-       zval **r = (zval **) el;
-       TSRMLS_FETCH();
-
-       { /* gcc 2.95 needs these braces */
-               php_http_request_object_t *obj = zend_object_store_get_object(*r TSRMLS_CC);
+       TSRMLS_FETCH_FROM_CTX(h->ts);
 
-               curl_easy_setopt(obj->request->ch, CURLOPT_SHARE, NULL);
-               zval_ptr_dtor(r);
-       }
-}
+       if (h->ops->detach) {
+               php_http_request_object_t *obj = zend_object_store_get_object(request TSRMLS_CC);
 
-#ifdef ZTS
-static void *php_http_request_datashare_locks_init(void)
-{
-       int i;
-       php_http_request_datashare_lock_t *locks = pecalloc(CURL_LOCK_DATA_LAST, sizeof(php_http_request_datashare_lock_t), 1);
-
-       if (locks) {
-               for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) {
-                       locks[i].mx = tsrm_mutex_alloc();
+               if (SUCCESS == h->ops->detach(h, obj->request)) {
+                       zend_llist_del_element(PHP_HTTP_REQUEST_DATASHARE_REQUESTS(h), request, php_http_request_datashare_compare_handles);
+                       return SUCCESS;
                }
        }
-
-       return locks;
+       return FAILURE;
 }
 
-static void php_http_request_datashare_locks_dtor(void *l)
+PHP_HTTP_API STATUS php_http_request_datashare_setopt(php_http_request_datashare_t *h, php_http_request_datashare_setopt_opt_t opt, void *arg)
 {
-       int i;
-       php_http_request_datashare_lock_t *locks = (php_http_request_datashare_lock_t *) l;
-
-       for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) {
-               tsrm_mutex_free(locks[i].mx);
+       if (h->ops->setopt) {
+               return h->ops->setopt(h, opt, arg);
        }
-       pefree(locks, 1);
+       return FAILURE;
 }
 
-static void php_http_request_datashare_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr)
+static void detach(void *r, void *h TSRMLS_DC)
 {
-       php_http_request_datashare_lock_t *locks = (php_http_request_datashare_lock_t *) userptr;
-
-       /* TSRM can't distinguish shared/exclusive locks */
-       tsrm_mutex_lock(locks[data].mx);
-       locks[data].ch = handle;
+       ((php_http_request_datashare_t *) h)->ops->detach(h, ((php_http_request_object_t *) zend_object_store_get_object(*((zval **) r) TSRMLS_CC))->request);
 }
 
-static void php_http_request_datashare_unlock_func(CURL *handle, curl_lock_data data, void *userptr)
+PHP_HTTP_API void php_http_request_datashare_reset(php_http_request_datashare_t *h)
 {
-       php_http_request_datashare_lock_t *locks = (php_http_request_datashare_lock_t *) userptr;
+       if (h->ops->reset) {
+               h->ops->reset(h);
+       } else if (h->ops->detach) {
+               TSRMLS_FETCH_FROM_CTX(h->ts);
 
-       if (locks[data].ch == handle) {
-               tsrm_mutex_unlock(locks[data].mx);
+               zend_llist_apply_with_argument(PHP_HTTP_REQUEST_DATASHARE_REQUESTS(h), detach, h TSRMLS_CC);
        }
+
+       zend_llist_clean(PHP_HTTP_REQUEST_DATASHARE_REQUESTS(h));
 }
-#endif
 
+static void php_http_request_datashare_global_requests_dtor(void *el)
+{
+       //php_http_request_datashare_detach(php_http_request_datashare_global_get(), *((zval **) el));
+       zval_ptr_dtor(el);
+}
 
 #define PHP_HTTP_BEGIN_ARGS(method, req_args)  PHP_HTTP_BEGIN_ARGS_EX(HttpRequestDataShare, method, 0, req_args)
 #define PHP_HTTP_EMPTY_ARGS(method)                            PHP_HTTP_EMPTY_ARGS_EX(HttpRequestDataShare, method, 0)
 #define PHP_HTTP_RSHARE_ME(method, visibility) PHP_ME(HttpRequestDataShare, method, PHP_HTTP_ARGS(HttpRequestDataShare, method), visibility)
 
+PHP_HTTP_EMPTY_ARGS(__construct);
 PHP_HTTP_EMPTY_ARGS(__destruct);
+PHP_HTTP_EMPTY_ARGS(reset);
 PHP_HTTP_EMPTY_ARGS(count);
 
 PHP_HTTP_BEGIN_ARGS(attach, 1)
@@ -224,23 +180,17 @@ PHP_HTTP_BEGIN_ARGS(detach, 1)
        PHP_HTTP_ARG_OBJ(http\\Request, request, 0)
 PHP_HTTP_END_ARGS;
 
-PHP_HTTP_EMPTY_ARGS(reset);
-
-PHP_HTTP_EMPTY_ARGS(getGlobalInstance);
-
-
-static zval *php_http_request_datashare_object_read_prop(zval *object, zval *member, int type, const zend_literal *literal_key TSRMLS_DC);
 static void php_http_request_datashare_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC);
 
-#define THIS_CE php_http_request_datashare_class_entry
+#define php_http_request_datashare_class_entry php_http_request_datashare_class_entry
 zend_class_entry *php_http_request_datashare_class_entry;
 zend_function_entry php_http_request_datashare_method_entry[] = {
+       PHP_HTTP_RSHARE_ME(__construct, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
        PHP_HTTP_RSHARE_ME(__destruct, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
        PHP_HTTP_RSHARE_ME(count, ZEND_ACC_PUBLIC)
        PHP_HTTP_RSHARE_ME(attach, ZEND_ACC_PUBLIC)
        PHP_HTTP_RSHARE_ME(detach, ZEND_ACC_PUBLIC)
        PHP_HTTP_RSHARE_ME(reset, ZEND_ACC_PUBLIC)
-       PHP_HTTP_RSHARE_ME(getGlobalInstance, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
        EMPTY_FUNCTION_ENTRY
 };
 static zend_object_handlers php_http_request_datashare_object_handlers;
@@ -262,7 +212,7 @@ zend_object_value php_http_request_datashare_object_new_ex(zend_class_entry *ce,
        if (share) {
                o->share = share;
        } else {
-               o->share = php_http_request_datashare_init(NULL, 0 TSRMLS_CC);
+               o->share = php_http_request_datashare_init(NULL, NULL, NULL, 0 TSRMLS_CC);
        }
 
        if (ptr) {
@@ -286,24 +236,24 @@ void php_http_request_datashare_object_free(void *object TSRMLS_DC)
        efree(o);
 }
 
-static zval *php_http_request_datashare_object_read_prop(zval *object, zval *member, int type, const zend_literal *literal_key TSRMLS_DC)
-{
-       if (type == BP_VAR_W && zend_get_property_info(THIS_CE, member, 1 TSRMLS_CC)) {
-               zend_error(E_ERROR, "Cannot access HttpRequestDataShare default properties by reference or array key/index");
-               return NULL;
-       }
-
-       return zend_get_std_object_handlers()->read_property(object, member, type, literal_key TSRMLS_CC);
-}
-
 static void php_http_request_datashare_object_write_prop(zval *object, zval *member, zval *value, const zend_literal *literal_key TSRMLS_DC)
 {
-       if (zend_get_property_info(THIS_CE, member, 1 TSRMLS_CC)) {
-               int status;
+       zend_property_info *pi;
+
+       if ((pi = zend_get_property_info(php_http_request_datashare_class_entry, member, 1 TSRMLS_CC))) {
+               zend_bool enable = i_zend_is_true(value);
+               php_http_request_datashare_setopt_opt_t opt;
                php_http_request_datashare_object_t *obj = zend_object_store_get_object(object TSRMLS_CC);
 
-               status = php_http_request_datashare_set(obj->share, Z_STRVAL_P(member), Z_STRLEN_P(member), (zend_bool) i_zend_is_true(value));
-               if (SUCCESS != status) {
+               if (!strcmp(pi->name, "cookie")) {
+                       opt = PHP_HTTP_REQUEST_DATASHARE_OPT_COOKIES;
+               } else if (!strcmp(pi->name, "dns")) {
+                       opt = PHP_HTTP_REQUEST_DATASHARE_OPT_RESOLVER;
+               } else {
+                       return;
+               }
+
+               if (SUCCESS != php_http_request_datashare_setopt(obj->share, opt, &enable)) {
                        return;
                }
        }
@@ -311,6 +261,25 @@ static void php_http_request_datashare_object_write_prop(zval *object, zval *mem
        zend_get_std_object_handlers()->write_property(object, member, value, literal_key TSRMLS_CC);
 }
 
+static zval **php_http_request_datashare_object_get_prop_ptr(zval *object, zval *member, const zend_literal *literal_key TSRMLS_DC)
+{
+       zend_property_info *pi;
+
+       if ((pi = zend_get_property_info(php_http_request_datashare_class_entry, member, 1 TSRMLS_CC))) {
+               return &php_http_property_proxy_init(NULL, object, member TSRMLS_CC)->myself;
+       }
+
+       return zend_get_std_object_handlers()->get_property_ptr_ptr(object, member, literal_key TSRMLS_CC);
+}
+
+
+PHP_METHOD(HttpRequestDataShare, __construct)
+{
+       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
+               zend_parse_parameters_none();
+       } end_error_handling();
+}
+
 PHP_METHOD(HttpRequestDataShare, __destruct)
 {
        php_http_request_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
@@ -319,7 +288,7 @@ PHP_METHOD(HttpRequestDataShare, __destruct)
                ; /* we always want to clean up */
        }
 
-       php_http_request_datashare_detach_all(obj->share);
+       php_http_request_datashare_reset(obj->share);
 }
 
 PHP_METHOD(HttpRequestDataShare, count)
@@ -327,7 +296,7 @@ PHP_METHOD(HttpRequestDataShare, count)
        if (SUCCESS == zend_parse_parameters_none()) {
                php_http_request_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
-               RETURN_LONG(zend_llist_count(PHP_HTTP_RSHARE_HANDLES(obj->share)));
+               RETURN_LONG(zend_llist_count(PHP_HTTP_REQUEST_DATASHARE_REQUESTS(obj->share)));
        }
        RETURN_FALSE;
 }
@@ -363,105 +332,55 @@ PHP_METHOD(HttpRequestDataShare, reset)
        if (SUCCESS == zend_parse_parameters_none()) {
                php_http_request_datashare_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
-               php_http_request_datashare_detach_all(obj->share);
+               php_http_request_datashare_reset(obj->share);
                RETURN_TRUE;
        }
        RETURN_FALSE;
 }
 
-PHP_METHOD(HttpRequestDataShare, getGlobalInstance)
-{
-       with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
-               if (SUCCESS == zend_parse_parameters_none()) {
-                       zval *instance = *zend_std_get_static_property(THIS_CE, ZEND_STRL("instance"), 0, NULL TSRMLS_CC);
-
-                       if (Z_TYPE_P(instance) != IS_OBJECT) {
-                               MAKE_STD_ZVAL(instance);
-                               ZVAL_OBJVAL(instance, php_http_request_datashare_object_new_ex(THIS_CE, php_http_request_datashare_global_get(), NULL TSRMLS_CC), 1);
-                               zend_update_static_property(THIS_CE, ZEND_STRL("instance"), instance TSRMLS_CC);
-
-                               if (PHP_HTTP_G->request_datashare.cookie) {
-                                       zend_update_property_bool(THIS_CE, instance, ZEND_STRL("cookie"), PHP_HTTP_G->request_datashare.cookie TSRMLS_CC);
-                               }
-                               if (PHP_HTTP_G->request_datashare.dns) {
-                                       zend_update_property_bool(THIS_CE, instance, ZEND_STRL("dns"), PHP_HTTP_G->request_datashare.dns TSRMLS_CC);
-                               }
-                               if (PHP_HTTP_G->request_datashare.ssl) {
-                                       zend_update_property_bool(THIS_CE, instance, ZEND_STRL("ssl"), PHP_HTTP_G->request_datashare.ssl TSRMLS_CC);
-                               }
-                               if (PHP_HTTP_G->request_datashare.connect) {
-                                       zend_update_property_bool(THIS_CE, instance, ZEND_STRL("connect"), PHP_HTTP_G->request_datashare.connect TSRMLS_CC);
-                               }
-                       }
-
-                       RETVAL_ZVAL(instance, 0, 0);
-               }
-       }end_error_handling();
-}
-
 PHP_MINIT_FUNCTION(http_request_datashare)
 {
-       curl_lock_data val;
-
-       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_datashare"), curl_share_init, (php_http_persistent_handle_dtor_t) curl_share_cleanup, NULL)) {
-               return FAILURE;
-       }
-#ifdef ZTS
-       if (SUCCESS != php_http_persistent_handle_provide(ZEND_STRL("http_request_datashare_lock"), php_http_request_datashare_locks_init, php_http_request_datashare_locks_dtor, NULL)) {
-               return FAILURE;
-       }
-#endif
-
-       if (!php_http_request_datashare_init(&php_http_request_datashare_global, 1 TSRMLS_CC)) {
-               return FAILURE;
-       }
-
-       zend_hash_init(&php_http_request_datashare_options, 4, NULL, NULL, 1);
-#define ADD_DATASHARE_OPT(name, opt) \
-       val = opt; \
-       zend_hash_add(&php_http_request_datashare_options, name, sizeof(name), &val, sizeof(curl_lock_data), NULL)
-       ADD_DATASHARE_OPT("cookie", CURL_LOCK_DATA_COOKIE);
-       ADD_DATASHARE_OPT("dns", CURL_LOCK_DATA_DNS);
-       ADD_DATASHARE_OPT("ssl", CURL_LOCK_DATA_SSL_SESSION);
-       ADD_DATASHARE_OPT("connect", CURL_LOCK_DATA_CONNECT);
-
        PHP_HTTP_REGISTER_CLASS(http\\request, DataShare, http_request_datashare, php_http_object_class_entry, 0);
        php_http_request_datashare_class_entry->create_object = php_http_request_datashare_object_new;
        memcpy(&php_http_request_datashare_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
        php_http_request_datashare_object_handlers.clone_obj = NULL;
-       php_http_request_datashare_object_handlers.read_property = php_http_request_datashare_object_read_prop;
        php_http_request_datashare_object_handlers.write_property = php_http_request_datashare_object_write_prop;
-       php_http_request_datashare_object_handlers.get_property_ptr_ptr = NULL;
+       php_http_request_datashare_object_handlers.get_property_ptr_ptr = php_http_request_datashare_object_get_prop_ptr;
 
        zend_class_implements(php_http_request_datashare_class_entry TSRMLS_CC, 1, spl_ce_Countable);
 
-       zend_declare_property_null(THIS_CE, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
-       zend_declare_property_bool(THIS_CE, ZEND_STRL("cookie"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_bool(THIS_CE, ZEND_STRL("dns"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_bool(THIS_CE, ZEND_STRL("ssl"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
-       zend_declare_property_bool(THIS_CE, ZEND_STRL("connect"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
+       zend_declare_property_null(php_http_request_datashare_class_entry, ZEND_STRL("instance"), (ZEND_ACC_STATIC|ZEND_ACC_PRIVATE) TSRMLS_CC);
+       zend_declare_property_bool(php_http_request_datashare_class_entry, ZEND_STRL("cookie"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
+       zend_declare_property_bool(php_http_request_datashare_class_entry, ZEND_STRL("dns"), 0, ZEND_ACC_PUBLIC TSRMLS_CC);
+
+#ifdef ZTS
+       php_http_request_datashare_global_shares_lock = tsrm_mutex_alloc();
+#endif
+       zend_hash_init(&php_http_request_datashare_global_shares, 0, NULL, (dtor_func_t) php_http_request_datashare_free, 1);
 
        return SUCCESS;
 }
 
 PHP_MSHUTDOWN_FUNCTION(http_request_datashare)
 {
-       php_http_request_datashare_dtor(&php_http_request_datashare_global);
-       zend_hash_destroy(&php_http_request_datashare_options);
+       zend_hash_destroy(&php_http_request_datashare_global_shares);
+#ifdef ZTS
+       tsrm_mutex_free(php_http_request_datashare_global_shares_lock);
+#endif
 
        return SUCCESS;
 }
 
 PHP_RINIT_FUNCTION(http_request_datashare)
 {
-       zend_llist_init(&PHP_HTTP_G->request_datashare.handles, sizeof(zval *), php_http_request_datashare_destroy_handles, 0);
+       zend_llist_init(&PHP_HTTP_G->request_datashare.requests, sizeof(zval *), php_http_request_datashare_global_requests_dtor, 0);
 
        return SUCCESS;
 }
 
 PHP_RSHUTDOWN_FUNCTION(http_request_datashare)
 {
-       zend_llist_destroy(&PHP_HTTP_G->request_datashare.handles);
+       zend_llist_destroy(&PHP_HTTP_G->request_datashare.requests);
 
        return SUCCESS;
 }