@@ -81,11 +81,42 @@ static void odbc_insert_new_result(odbc_connection *connection, zval *result) {
81
81
ZEND_ASSERT (Z_TYPE_P (result ) == IS_OBJECT && instanceof_function (Z_OBJCE_P (result ), odbc_result_ce ));
82
82
83
83
odbc_result * res = Z_ODBC_RESULT_P (result );
84
+
84
85
res -> index = connection -> results .nNextFreeElement ;
85
- zend_hash_next_index_insert_new (& connection -> results , result );
86
+ zend_hash_index_add_new (& connection -> results , res -> index , result );
86
87
Z_ADDREF_P (result );
87
88
}
88
89
90
+ static inline odbc_link * odbc_link_from_obj (zend_object * obj ) {
91
+ return (odbc_link * )((char * )(obj ) - XtOffsetOf (odbc_link , std ));
92
+ }
93
+
94
+ static int _close_pconn_with_res (zval * zv , void * p )
95
+ {
96
+ zend_resource * le = Z_RES_P (zv );
97
+ if (le -> type != le_pconn ) {
98
+ return ZEND_HASH_APPLY_KEEP ;
99
+ }
100
+
101
+ odbc_connection * list_conn = ((odbc_connection * )(le -> ptr ));
102
+ odbc_connection * obj_conn = odbc_link_from_obj ((zend_object * )p )-> connection ;
103
+ if (list_conn == obj_conn ) {
104
+ return ZEND_HASH_APPLY_REMOVE ;
105
+ }
106
+
107
+ return ZEND_HASH_APPLY_KEEP ;
108
+ }
109
+
110
+ static int _close_pconn (zval * zv )
111
+ {
112
+ zend_resource * le = Z_RES_P (zv );
113
+ if (le -> type == le_pconn ) {
114
+ return ZEND_HASH_APPLY_REMOVE ;
115
+ } else {
116
+ return ZEND_HASH_APPLY_KEEP ;
117
+ }
118
+ }
119
+
89
120
static void odbc_link_free (odbc_link * link )
90
121
{
91
122
ZEND_ASSERT (link -> connection && "link has already been closed" );
@@ -101,6 +132,7 @@ static void odbc_link_free(odbc_link *link)
101
132
}
102
133
link -> connection -> hdbc = NULL ;
103
134
link -> connection -> henv = NULL ;
135
+ zend_hash_destroy (& link -> connection -> results );
104
136
efree (link -> connection );
105
137
ODBCG (num_links )-- ;
106
138
@@ -117,10 +149,6 @@ static void odbc_link_free(odbc_link *link)
117
149
}
118
150
}
119
151
120
- static inline odbc_link * odbc_link_from_obj (zend_object * obj ) {
121
- return (odbc_link * )((char * )(obj ) - XtOffsetOf (odbc_link , std ));
122
- }
123
-
124
152
static zend_object * odbc_connection_create_object (zend_class_entry * class_type ) {
125
153
odbc_link * intern = zend_object_alloc (sizeof (odbc_link ), class_type );
126
154
@@ -253,9 +281,10 @@ static void close_results_with_connection(odbc_connection *conn) {
253
281
if (result -> conn_ptr ) {
254
282
odbc_result_free (result );
255
283
}
284
+ GC_DELREF (& result -> std );
256
285
} ZEND_HASH_FOREACH_END ();
257
286
258
- zend_hash_destroy (& conn -> results );
287
+ zend_hash_clean (& conn -> results );
259
288
}
260
289
261
290
/* disconnect, and if it fails, then issue a rollback for any pending transaction (lurcher) */
@@ -277,14 +306,14 @@ static void _close_odbc_pconn(zend_resource *rsrc)
277
306
odbc_connection * conn = (odbc_connection * )rsrc -> ptr ;
278
307
279
308
close_results_with_connection (conn );
309
+ zend_hash_destroy (& conn -> results );
280
310
281
311
/* If aborted via timer expiration, don't try to call any unixODBC function */
282
312
if (!(PG (connection_status ) & PHP_CONNECTION_TIMEOUT )) {
283
313
safe_odbc_disconnect (conn -> hdbc );
284
314
SQLFreeConnect (conn -> hdbc );
285
315
SQLFreeEnv (conn -> henv );
286
316
}
287
- free (conn );
288
317
289
318
ODBCG (num_links )-- ;
290
319
ODBCG (num_persistent )-- ;
@@ -855,12 +884,7 @@ PHP_FUNCTION(odbc_close_all)
855
884
856
885
zend_hash_clean (& ODBCG (non_persistent_connections ));
857
886
858
- /* Loop through the persistent connection list, now close all persistent connections and their results */
859
- ZEND_HASH_FOREACH_VAL (& EG (persistent_list ), zv ) {
860
- if (Z_RES_P (zv )-> type == le_pconn ) {
861
- zend_list_close (Z_RES_P (zv ));
862
- }
863
- } ZEND_HASH_FOREACH_END ();
887
+ zend_hash_apply (& EG (persistent_list ), _close_pconn );
864
888
}
865
889
/* }}} */
866
890
@@ -2388,7 +2412,7 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
2388
2412
/* {{{ Close an ODBC connection */
2389
2413
PHP_FUNCTION (odbc_close )
2390
2414
{
2391
- zval * pv_conn , * zv ;
2415
+ zval * pv_conn ;
2392
2416
odbc_link * link ;
2393
2417
2394
2418
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O" , & pv_conn , odbc_connection_ce ) == FAILURE ) {
@@ -2398,13 +2422,11 @@ PHP_FUNCTION(odbc_close)
2398
2422
link = Z_ODBC_LINK_P (pv_conn );
2399
2423
CHECK_ODBC_CONNECTION (link -> connection );
2400
2424
2401
- odbc_link_free (link );
2425
+ if (link -> persistent ) {
2426
+ zend_hash_apply_with_argument (& EG (persistent_list ), _close_pconn_with_res , (void * ) Z_OBJ_P (pv_conn ));
2427
+ }
2402
2428
2403
- ZEND_HASH_FOREACH_VAL (& EG (persistent_list ), zv ) {
2404
- if (Z_RES_P (zv )-> type == le_pconn && link -> connection == Z_RES_P (zv )-> ptr ) {
2405
- zend_list_close (Z_RES_P (zv ));
2406
- }
2407
- } ZEND_HASH_FOREACH_END ();
2429
+ odbc_link_free (link );
2408
2430
}
2409
2431
/* }}} */
2410
2432
0 commit comments