@@ -3561,18 +3561,6 @@ static inline void php_phongo_pclient_destroy(php_phongo_pclient_t* pclient)
35613561 pefree (pclient , 1 );
35623562}
35633563
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-
35763564/* {{{ PHP_RINIT_FUNCTION */
35773565PHP_RINIT_FUNCTION (mongodb )
35783566{
@@ -3605,7 +3593,7 @@ PHP_GINIT_FUNCTION(mongodb)
36053593 mongodb_globals -> bsonMemVTable = bsonMemVTable ;
36063594
36073595 /* 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 );
36093597}
36103598/* }}} */
36113599
@@ -3762,10 +3750,42 @@ PHP_MINIT_FUNCTION(mongodb)
37623750/* {{{ PHP_MSHUTDOWN_FUNCTION */
37633751PHP_MSHUTDOWN_FUNCTION (mongodb )
37643752{
3753+ HashTable * pclients = & MONGODB_G (pclients );
37653754 (void ) type ; /* We don't care if we are loaded via dl() or extension= */
37663755
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. */
37693789 zend_hash_destroy (& MONGODB_G (pclients ));
37703790
37713791 bson_mem_restore_vtable ();
0 commit comments