28
28
29
29
#define SAVE_CURLSH_ERROR (__handle , __err ) (__handle)->err.no = (int) __err;
30
30
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
+ }
32
41
33
42
/* {{{ Initialize a persistent curl share handle */
34
43
PHP_FUNCTION (curl_share_init_persistent )
35
44
{
36
- php_curlsh * sh ;
45
+ zend_string * id ;
37
46
38
- zend_string * persistent_id = NULL ;
39
- zend_string * persistent_key = NULL ;
47
+ zval * persisted ;
40
48
41
- zend_resource * persisted ;
49
+ php_curlsh * sh ;
42
50
43
51
zval * arr , * entry ;
52
+ CURLSHcode error ;
44
53
45
54
ZEND_PARSE_PARAMETERS_START (2 , 2 )
46
- Z_PARAM_STR_EX (persistent_id , 1 , 0 )
55
+ Z_PARAM_STR_EX (id , 1 , 0 )
47
56
Z_PARAM_ARRAY (arr )
48
57
ZEND_PARSE_PARAMETERS_END ();
49
58
50
- persistent_key = strpprintf (0 , "curl_share_init_persistent:id=%s" , ZSTR_VAL (persistent_id ));
51
-
52
59
object_init_ex (return_value , curl_share_ce );
53
-
54
60
sh = Z_CURL_SHARE_P (return_value );
55
61
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 ();
60
67
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 );
66
70
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 ));
69
72
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 ));
71
75
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 ();
77
79
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 ;
79
83
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
+ }
81
86
82
- cleanup :
83
- zend_string_release (persistent_key );
84
87
return ;
85
88
86
89
error :
87
- zend_string_release (persistent_key );
88
- curl_share_free_obj (Z_OBJ_P (return_value ));
90
+ zval_ptr_dtor (return_value );
89
91
90
92
RETURN_FALSE ;
91
93
}
@@ -105,14 +107,6 @@ PHP_FUNCTION(curl_share_init)
105
107
}
106
108
/* }}} */
107
109
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
-
116
110
/* {{{ Close a set of cURL handles */
117
111
PHP_FUNCTION (curl_share_close )
118
112
{
@@ -225,7 +219,7 @@ void curl_share_free_obj(zend_object *object)
225
219
{
226
220
php_curlsh * sh = curl_share_from_obj (object );
227
221
228
- if (!sh -> is_persistent ) {
222
+ if (!sh -> persistent ) {
229
223
curl_share_cleanup (sh -> share );
230
224
}
231
225
@@ -234,7 +228,7 @@ void curl_share_free_obj(zend_object *object)
234
228
235
229
static zend_object_handlers curl_share_handlers ;
236
230
237
- void curl_share_register_handlers (int module_number ) {
231
+ void curl_share_register_handlers (void ) {
238
232
curl_share_ce -> create_object = curl_share_create_object ;
239
233
curl_share_ce -> default_object_handlers = & curl_share_handlers ;
240
234
@@ -244,6 +238,4 @@ void curl_share_register_handlers(int module_number) {
244
238
curl_share_handlers .get_constructor = curl_share_get_constructor ;
245
239
curl_share_handlers .clone_obj = NULL ;
246
240
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 );
249
241
}
0 commit comments