mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Add GC support for PDO driver data
Add a get_gc method that can be implemented by drivers, which can be used to add additional zvals to the GC buffer. Implement GC support for PDO SQLite callbacks in particular. Closes GH-6262.
This commit is contained in:
parent
d731b764e5
commit
e735de6eae
10 changed files with 75 additions and 10 deletions
|
@ -1291,8 +1291,12 @@ static int dbh_compare(zval *object1, zval *object2)
|
|||
static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
|
||||
{
|
||||
pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(object);
|
||||
*gc_data = &dbh->def_stmt_ctor_args;
|
||||
*gc_count = 1;
|
||||
zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
|
||||
zend_get_gc_buffer_add_zval(gc_buffer, &dbh->def_stmt_ctor_args);
|
||||
if (dbh->methods->get_gc) {
|
||||
dbh->methods->get_gc(dbh, gc_buffer);
|
||||
}
|
||||
zend_get_gc_buffer_use(gc_buffer, gc_data, gc_count);
|
||||
return zend_std_get_properties(object);
|
||||
}
|
||||
|
||||
|
|
|
@ -286,6 +286,10 @@ typedef int (*pdo_dbh_check_liveness_func)(pdo_dbh_t *dbh);
|
|||
* scope */
|
||||
typedef void (*pdo_dbh_request_shutdown)(pdo_dbh_t *dbh);
|
||||
|
||||
/* Called when the PDO handle is scanned for GC. Should populate the get_gc buffer
|
||||
* with any zvals in the driver_data that would be freed if the handle is destroyed. */
|
||||
typedef void (*pdo_dbh_get_gc_func)(pdo_dbh_t *dbh, zend_get_gc_buffer *buffer);
|
||||
|
||||
/* for adding methods to the dbh or stmt objects
|
||||
pointer to a list of driver specific functions. The convention is
|
||||
to prefix the function names using the PDO driver name; this will
|
||||
|
@ -316,6 +320,7 @@ struct pdo_dbh_methods {
|
|||
pdo_dbh_get_driver_methods_func get_driver_methods;
|
||||
pdo_dbh_request_shutdown persistent_shutdown;
|
||||
pdo_dbh_txn_func in_transaction;
|
||||
pdo_dbh_get_gc_func get_gc;
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
|
|
@ -417,7 +417,8 @@ static const struct pdo_dbh_methods dblib_methods = {
|
|||
NULL, /* check liveness */
|
||||
NULL, /* get driver methods */
|
||||
NULL, /* request shutdown */
|
||||
NULL /* in transaction */
|
||||
NULL, /* in transaction */
|
||||
NULL /* get gc */
|
||||
};
|
||||
|
||||
static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
|
||||
|
|
|
@ -1005,7 +1005,11 @@ static const struct pdo_dbh_methods firebird_methods = { /* {{{ */
|
|||
NULL, /* last_id not supported */
|
||||
pdo_firebird_fetch_error_func,
|
||||
firebird_handle_get_attribute,
|
||||
NULL /* check_liveness */
|
||||
NULL, /* check_liveness */
|
||||
NULL, /* get driver methods */
|
||||
NULL, /* request shutdown */
|
||||
NULL, /* in transaction */
|
||||
NULL /* get gc */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -563,7 +563,8 @@ static const struct pdo_dbh_methods mysql_methods = {
|
|||
pdo_mysql_check_liveness,
|
||||
NULL,
|
||||
pdo_mysql_request_shutdown,
|
||||
pdo_mysql_in_transaction
|
||||
pdo_mysql_in_transaction,
|
||||
NULL /* get_gc */
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -705,9 +705,10 @@ static const struct pdo_dbh_methods oci_methods = {
|
|||
pdo_oci_fetch_error_func,
|
||||
oci_handle_get_attribute,
|
||||
pdo_oci_check_liveness, /* check_liveness */
|
||||
NULL, /* get_driver_methods */
|
||||
NULL,
|
||||
NULL
|
||||
NULL, /* get_driver_methods */
|
||||
NULL, /* request_shutdown */
|
||||
NULL, /* in_transaction */
|
||||
NULL /* get_gc */
|
||||
};
|
||||
|
||||
static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
|
||||
|
|
|
@ -384,7 +384,11 @@ static const struct pdo_dbh_methods odbc_methods = {
|
|||
NULL, /* last id */
|
||||
pdo_odbc_fetch_error_func,
|
||||
odbc_handle_get_attr, /* get attr */
|
||||
NULL, /* check_liveness */
|
||||
NULL, /* check_liveness */
|
||||
NULL, /* get_driver_methods */
|
||||
NULL, /* request_shutdown */
|
||||
NULL, /* in_transaction */
|
||||
NULL /* get_gc */
|
||||
};
|
||||
|
||||
static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
|
||||
|
|
|
@ -1179,6 +1179,7 @@ static const struct pdo_dbh_methods pgsql_methods = {
|
|||
pdo_pgsql_get_driver_methods, /* get_driver_methods */
|
||||
NULL,
|
||||
pgsql_handle_in_transaction,
|
||||
NULL /* get_gc */
|
||||
};
|
||||
|
||||
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
|
||||
|
|
|
@ -695,6 +695,25 @@ static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)
|
|||
}
|
||||
}
|
||||
|
||||
static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
|
||||
{
|
||||
pdo_sqlite_db_handle *H = dbh->driver_data;
|
||||
|
||||
struct pdo_sqlite_func *func = H->funcs;
|
||||
while (func) {
|
||||
zend_get_gc_buffer_add_zval(gc_buffer, &func->func);
|
||||
zend_get_gc_buffer_add_zval(gc_buffer, &func->step);
|
||||
zend_get_gc_buffer_add_zval(gc_buffer, &func->fini);
|
||||
func = func->next;
|
||||
}
|
||||
|
||||
struct pdo_sqlite_collation *collation = H->collations;
|
||||
while (collation) {
|
||||
zend_get_gc_buffer_add_zval(gc_buffer, &collation->callback);
|
||||
collation = collation->next;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pdo_dbh_methods sqlite_methods = {
|
||||
sqlite_handle_closer,
|
||||
sqlite_handle_preparer,
|
||||
|
@ -710,7 +729,8 @@ static const struct pdo_dbh_methods sqlite_methods = {
|
|||
NULL, /* check_liveness: not needed */
|
||||
get_driver_methods,
|
||||
pdo_sqlite_request_shutdown,
|
||||
NULL
|
||||
NULL, /* in_transaction */
|
||||
pdo_sqlite_get_gc
|
||||
};
|
||||
|
||||
static char *make_filename_safe(const char *filename)
|
||||
|
|
24
ext/pdo_sqlite/tests/gc.phpt
Normal file
24
ext/pdo_sqlite/tests/gc.phpt
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
GC support for PDO Sqlite driver data
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Obj {
|
||||
public $a;
|
||||
public function callback() { }
|
||||
}
|
||||
|
||||
$obj = new Obj;
|
||||
$obj->a = new PDO('sqlite::memory:');
|
||||
$obj->a->sqliteCreateFunction('func1', function() use ($obj) {}, 1);
|
||||
$obj->a->sqliteCreateAggregate('func2', function() use ($obj) {}, function() use($obj) {});
|
||||
$obj->a->sqliteCreateCollation('col', function() use ($obj) {});
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
Loading…
Add table
Add a link
Reference in a new issue