[php-src] master: ext/pdo: persistent_shutdown run while the connection is still shared.

From: Date: Thu, 22 Oct 2026 11:15:01 +0000
Subject: [php-src] master: ext/pdo: persistent_shutdown run while the connection is still shared.
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142557@lists.php.net to get a copy of this message
Author: David Carlier (devnexen) Date: 2026-10-22T12:05:15+01:00 Commit: https://github.com/php/php-src/commit/a9138d768ad1760ad87308b5fcadd532bba29b05 Raw diff: https://github.com/php/php-src/commit/a9138d768ad1760ad87308b5fcadd532bba29b05.diff ext/pdo: persistent_shutdown run while the connection is still shared. Only call it for the last PDO object, like the rollback before it. Changed paths: A ext/pdo_pgsql/tests/gh24461_shared_connection.phpt M ext/pdo/pdo_dbh.c Diff: diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 58bb3b1727f6..9ccaebd5e8bb 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1606,7 +1606,7 @@ static void pdo_dbh_free_storage(zend_object *std) dbh->in_txn = false; } - if (dbh->is_persistent && dbh->driver_data && dbh->methods && dbh->methods->persistent_shutdown) { + if (dbh->is_persistent && dbh->refcount <= 2 && dbh->driver_data && dbh->methods && dbh->methods->persistent_shutdown) { dbh->methods->persistent_shutdown(dbh); } zend_object_std_dtor(std); diff --git a/ext/pdo_pgsql/tests/gh24461_shared_connection.phpt b/ext/pdo_pgsql/tests/gh24461_shared_connection.phpt new file mode 100644 index 000000000000..f341beecb081 --- /dev/null +++ b/ext/pdo_pgsql/tests/gh24461_shared_connection.phpt @@ -0,0 +1,46 @@ +--TEST-- +GH-24461 (Persistent connections: session state is not reset while another PDO object still uses the connection) +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- +<?php +require __DIR__ . '/config.inc'; +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; +PDOTest::skip(); +?> +--FILE-- +<?php +putenv('PDOTEST_ATTR='.serialize([PDO::ATTR_PERSISTENT => true])); + +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; + +$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt'); +$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid1 = (int) $pdo1->query('SELECT pg_backend_pid()')->fetchColumn(); +$pid2 = (int) $pdo2->query('SELECT pg_backend_pid()')->fetchColumn(); +var_dump($pid1 === $pid2); + +$pdo2->exec("SET application_name = 'gh24461'"); +$pdo2->exec('CREATE TEMP TABLE gh24461_shared (i int)'); +$pdo2->query('SELECT pg_advisory_lock(24461)'); +$stmt = $pdo2->prepare('SELECT 42'); +$stmt->execute(); +$stmt->closeCursor(); + +$pdo1 = null; + +var_dump($pdo2->query('SHOW application_name')->fetchColumn()); +var_dump($pdo2->query('SELECT count(*) FROM gh24461_shared')->fetchColumn()); +var_dump($pdo2->query("SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND objid = 24461 AND pid = pg_backend_pid()")->fetchColumn()); +$stmt->execute(); +var_dump($stmt->fetchColumn()); + +$pdo2->query('SELECT pg_advisory_unlock_all()'); +?> +--EXPECT-- +bool(true) +string(7) "gh24461" +string(1) "0" +string(1) "1" +string(2) "42"

« previous php.cvs (#142557) next »