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_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)
{
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)) {
return NULL;
}
- if ((share->persistent = persistent)) {
+ if (!(share->persistent = persistent)) {
+ share->handles = emalloc(sizeof(zend_llist));
+ zend_llist_init(share->handles, sizeof(zval *), ZVAL_PTR_DTOR, 0);
+#ifdef ZTS
+ } else {
+ int i;
+
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();
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;
}
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;
}
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;
{
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);
+ if (!share->persistent) {
+ zend_llist_destroy(share->handles);
+ efree(share->handles);
+ }
curl_share_cleanup(share->ch);
+#ifdef ZTS
if (share->persistent) {
+ int i;
+
for (i = 0; i < CURL_LOCK_DATA_LAST; ++i) {
tsrm_mutex_free(share->locks[i].mx);
}
pefree(share->locks, 1);
}
+#endif
}
PHP_HTTP_API void _http_request_datashare_free(http_request_datashare **share TSRMLS_DC)
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();
+ 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_lock_func(CURL *handle, curl_lock_data data, curl_lock_access locktype, void *userptr)
{
http_request_datashare *share = (http_request_datashare *) userptr;
tsrm_mutex_unlock(share->locks[data].mx);
}
}
+#endif
#endif /* ZEND_ENGINE_2 && HTTP_HAVE_CURL */
#define PHP_HTTP_REQUEST_DATASHARE_API_H
#ifdef HTTP_HAVE_CURL
+#ifdef ZTS
typedef struct _http_request_datashare_lock_t {
CURL *ch;
MUTEX_T mx;
} http_request_datashare_lock;
+#endif
typedef struct _http_request_datashare_t {
CURLSH *ch;
- zend_llist handles;
zend_bool persistent;
+ zend_llist *handles;
+#ifdef ZTS
http_request_datashare_lock *locks;
+#endif
} http_request_datashare;
+#define HTTP_RSHARE_HANDLES(s) ((s)->persistent ? &HTTP_G->request.datashare.handles : (s)->handles)
+
#define http_request_datashare_global_get _http_request_datashare_global_get
extern http_request_datashare *_http_request_datashare_global_get(void);
extern PHP_MINIT_FUNCTION(http_request_datashare);
extern PHP_MSHUTDOWN_FUNCTION(http_request_datashare);
+extern PHP_RINIT_FUNCTION(http_request_datashare);
+extern PHP_RSHUTDOWN_FUNCTION(http_request_datashare);
#define http_request_datashare_new() _http_request_datashare_init_ex(NULL, 0 TSRMLS_CC)
#define http_request_datashare_init(s) _http_request_datashare_init_ex((s), 0 TSRMLS_CC)
PHP_HTTP_API void _http_request_datashare_dtor(http_request_datashare *share TSRMLS_DC);
#define http_request_datashare_free(s) _http_request_datashare_free((s) TSRMLS_CC)
-PHP_HTTP_API void _http_request_datashaere_free(http_request_datashare **share TSRMLS_DC);
+PHP_HTTP_API void _http_request_datashare_free(http_request_datashare **share TSRMLS_DC);
#define http_request_datashare_set(s, o, l, e) _http_request_datashare_set((s), (o), (l), (e) TSRMLS_CC)
PHP_HTTP_API STATUS _http_request_datashare_set(http_request_datashare *share, const char *option, size_t option_len, zend_bool enable TSRMLS_DC);