2828
2929#define SAVE_CURLSH_ERROR (__handle , __err ) (__handle)->err.no = (int) __err;
3030
31- static int le_pcurlsh ;
31+ void curl_share_free_persistent (zval * data )
32+ {
33+ CURLSH * handle = Z_PTR_P (data );
34+
35+ if (!handle ) {
36+ return ;
37+ }
38+
39+ curl_share_cleanup (handle );
40+ }
3241
3342/* {{{ Initialize a persistent curl share handle */
3443PHP_FUNCTION (curl_share_init_persistent )
3544{
36- php_curlsh * sh ;
45+ zend_string * id ;
3746
38- zend_string * persistent_id = NULL ;
39- zend_string * persistent_key = NULL ;
47+ zval * persisted ;
4048
41- zend_resource * persisted ;
49+ php_curlsh * sh ;
4250
4351 zval * arr , * entry ;
52+ CURLSHcode error ;
4453
4554 ZEND_PARSE_PARAMETERS_START (2 , 2 )
46- Z_PARAM_STR_EX (persistent_id , 1 , 0 )
55+ Z_PARAM_STR_EX (id , 1 , 0 )
4756 Z_PARAM_ARRAY (arr )
4857 ZEND_PARSE_PARAMETERS_END ();
4958
50- persistent_key = strpprintf (0 , "curl_share_init_persistent:id=%s" , ZSTR_VAL (persistent_id ));
51-
5259 object_init_ex (return_value , curl_share_ce );
53-
5460 sh = Z_CURL_SHARE_P (return_value );
5561
56- if ((persisted = zend_hash_find_ptr (& EG (persistent_list ), persistent_key )) != NULL ) {
57- if (persisted -> type == le_pcurlsh ) {
58- sh -> share = persisted -> ptr ;
59- sh -> is_persistent = 1 ;
62+ if ((persisted = zend_hash_find (& CURL_G (persistent_share_handles ), id )) != NULL ) {
63+ sh -> share = Z_PTR_P (persisted );
64+ sh -> persistent = 1 ;
65+ } else {
66+ sh -> share = curl_share_init ();
6067
61- goto cleanup ;
62- }
63- }
64-
65- sh -> share = curl_share_init ();
68+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (arr ), entry ) {
69+ ZVAL_DEREF (entry );
6670
67- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (arr ), entry ) {
68- ZVAL_DEREF (entry );
71+ error = curl_share_setopt (sh -> share , CURLSHOPT_SHARE , zval_get_long (entry ));
6972
70- CURLSHcode error = curl_share_setopt (sh -> share , CURLSHOPT_SHARE , zval_get_long (entry ));
73+ if (error != CURLSHE_OK ) {
74+ php_error_docref (NULL , E_WARNING , "could not construct persistent curl share: %s" , curl_share_strerror (error ));
7175
72- if (error != CURLSHE_OK ) {
73- php_error_docref (NULL , E_WARNING , "could not construct persistent curl share: %s" , curl_share_strerror (error ));
74- goto error ;
75- }
76- } ZEND_HASH_FOREACH_END ();
76+ goto error ;
77+ }
78+ } ZEND_HASH_FOREACH_END ();
7779
78- zend_register_persistent_resource (ZSTR_VAL (persistent_key ), ZSTR_LEN (persistent_key ), sh -> share , le_pcurlsh );
80+ // It's important not to mark this as persistent until *after* we've successfully set all of the share options,
81+ // as otherwise the curl_share_free_obj in the error handler won't free the CURLSH.
82+ sh -> persistent = 1 ;
7983
80- sh -> is_persistent = 1 ;
84+ zend_hash_str_add_new_ptr (& CURL_G (persistent_share_handles ), ZSTR_VAL (id ), ZSTR_LEN (id ), sh -> share );
85+ }
8186
82- cleanup :
83- zend_string_release (persistent_key );
8487 return ;
8588
8689 error :
87- zend_string_release (persistent_key );
88- curl_share_free_obj (Z_OBJ_P (return_value ));
90+ zval_ptr_dtor (return_value );
8991
9092 RETURN_FALSE ;
9193}
@@ -105,14 +107,6 @@ PHP_FUNCTION(curl_share_init)
105107}
106108/* }}} */
107109
108- ZEND_RSRC_DTOR_FUNC (php_pcurlsh_dtor )
109- {
110- if (res -> ptr ) {
111- curl_share_cleanup (res -> ptr );
112- res -> ptr = NULL ;
113- }
114- }
115-
116110/* {{{ Close a set of cURL handles */
117111PHP_FUNCTION (curl_share_close )
118112{
@@ -225,7 +219,7 @@ void curl_share_free_obj(zend_object *object)
225219{
226220 php_curlsh * sh = curl_share_from_obj (object );
227221
228- if (!sh -> is_persistent ) {
222+ if (!sh -> persistent ) {
229223 curl_share_cleanup (sh -> share );
230224 }
231225
@@ -234,7 +228,7 @@ void curl_share_free_obj(zend_object *object)
234228
235229static zend_object_handlers curl_share_handlers ;
236230
237- void curl_share_register_handlers (int module_number ) {
231+ void curl_share_register_handlers (void ) {
238232 curl_share_ce -> create_object = curl_share_create_object ;
239233 curl_share_ce -> default_object_handlers = & curl_share_handlers ;
240234
@@ -244,6 +238,4 @@ void curl_share_register_handlers(int module_number) {
244238 curl_share_handlers .get_constructor = curl_share_get_constructor ;
245239 curl_share_handlers .clone_obj = NULL ;
246240 curl_share_handlers .compare = zend_objects_not_comparable ;
247-
248- le_pcurlsh = zend_register_list_destructors_ex (NULL , php_pcurlsh_dtor , "Curl persistent shared handle" , module_number );
249241}
0 commit comments