Skip to content

Implement GC for PDO SQLite driver data #6262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ext/pdo/pdo_dbh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
5 changes: 5 additions & 0 deletions ext/pdo/php_pdo_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
};

/* }}} */
Expand Down
3 changes: 2 additions & 1 deletion ext/pdo_dblib/dblib_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion ext/pdo_firebird/firebird_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};
/* }}} */

Expand Down
3 changes: 2 additions & 1 deletion ext/pdo_mysql/mysql_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};
/* }}} */

Expand Down
7 changes: 4 additions & 3 deletions ext/pdo_oci/oci_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) /* {{{ */
Expand Down
6 changes: 5 additions & 1 deletion ext/pdo_odbc/odbc_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) /* {{{ */
Expand Down
1 change: 1 addition & 0 deletions ext/pdo_pgsql/pgsql_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) /* {{{ */
Expand Down
22 changes: 21 additions & 1 deletion ext/pdo_sqlite/sqlite_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down
24 changes: 24 additions & 0 deletions ext/pdo_sqlite/tests/gc.phpt
Original file line number Diff line number Diff line change
@@ -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===