@@ -3561,18 +3561,6 @@ static inline void php_phongo_pclient_destroy(php_phongo_pclient_t* pclient)
3561
3561
pefree (pclient , 1 );
3562
3562
}
3563
3563
3564
- #if PHP_VERSION_ID >= 70000
3565
- static void php_phongo_pclient_dtor (zval * zv )
3566
- {
3567
- php_phongo_pclient_destroy ((php_phongo_pclient_t * ) Z_PTR_P (zv ));
3568
- }
3569
- #else
3570
- static void php_phongo_pclient_dtor (void * pp )
3571
- {
3572
- php_phongo_pclient_destroy (* ((php_phongo_pclient_t * * ) pp ));
3573
- }
3574
- #endif
3575
-
3576
3564
/* {{{ PHP_RINIT_FUNCTION */
3577
3565
PHP_RINIT_FUNCTION (mongodb )
3578
3566
{
@@ -3605,7 +3593,7 @@ PHP_GINIT_FUNCTION(mongodb)
3605
3593
mongodb_globals -> bsonMemVTable = bsonMemVTable ;
3606
3594
3607
3595
/* Initialize HashTable for persistent clients */
3608
- zend_hash_init_ex (& mongodb_globals -> pclients , 0 , NULL , php_phongo_pclient_dtor , 1 , 0 );
3596
+ zend_hash_init_ex (& mongodb_globals -> pclients , 0 , NULL , NULL , 1 , 0 );
3609
3597
}
3610
3598
/* }}} */
3611
3599
@@ -3762,10 +3750,42 @@ PHP_MINIT_FUNCTION(mongodb)
3762
3750
/* {{{ PHP_MSHUTDOWN_FUNCTION */
3763
3751
PHP_MSHUTDOWN_FUNCTION (mongodb )
3764
3752
{
3753
+ HashTable * pclients = & MONGODB_G (pclients );
3765
3754
(void ) type ; /* We don't care if we are loaded via dl() or extension= */
3766
3755
3767
- /* Destroy HashTable for persistent clients. The HashTable destructor will
3768
- * destroy any mongoc_client_t objects that were created by this process. */
3756
+ /* Destroy mongoc_client_t objects in reverse order. This is necessary to
3757
+ * prevent segmentation faults as clients may reference other clients in
3758
+ * encryption settings. */
3759
+ #if PHP_VERSION_ID >= 70000
3760
+ {
3761
+ zval * z_ptr ;
3762
+
3763
+ ZEND_HASH_REVERSE_FOREACH_VAL (pclients , z_ptr )
3764
+ {
3765
+ if ((Z_TYPE_P (z_ptr ) != IS_PTR )) {
3766
+ continue ;
3767
+ }
3768
+
3769
+ php_phongo_pclient_destroy ((php_phongo_pclient_t * ) Z_PTR_P (z_ptr ));
3770
+ }
3771
+ ZEND_HASH_FOREACH_END ();
3772
+ }
3773
+ #else
3774
+ {
3775
+ HashPosition pos ;
3776
+ php_phongo_pclient_t * * pclient ;
3777
+
3778
+ for (
3779
+ zend_hash_internal_pointer_end_ex (pclients , & pos );
3780
+ zend_hash_get_current_data_ex (pclients , (void * * ) & pclient , & pos ) == SUCCESS ;
3781
+ zend_hash_move_backwards_ex (pclients , & pos )) {
3782
+
3783
+ php_phongo_pclient_destroy (* pclient );
3784
+ }
3785
+ }
3786
+ #endif
3787
+
3788
+ /* Destroy HashTable for persistent clients. mongoc_client_t objects have been destroyed earlier. */
3769
3789
zend_hash_destroy (& MONGODB_G (pclients ));
3770
3790
3771
3791
bson_mem_restore_vtable ();
0 commit comments