Correct use of zend_list_delete

php.internals

Marco Bambini

20 years ago
Maybe this is a question too simple for this list, but I am writing my first php extension (using php 4.4 SDK) so please, be patient... My extension (rsql) returns a custom struct to php so my code in my rsql_connect looks like: ZEND_FUNCTION(rsql_connect) { .... RETURN_RESOURCE(zend_list_insert(rsqldb, rsql_connection)); } The relevant code is: ZEND_FUNCTION(rsql_disconnect) { ... ZEND_FETCH_RESOURCE2(rsqldb, void*, theConnectionParameter, -1, kConnIDString, rsql_connection, rsql_pconnection); if (rsqldb) zend_list_delete(Z_LVAL_PP(theConnectionParameter)); if (rsqldb) myCustomFree(rsqldb); } static void rsql_realconnectionclose(zend_rsrc_list_entry *rsrc) { void *rsqldb; if (rsrc != NULL) { rsqldb = rsrc->ptr; if (rsqldb != NULL) { rsqlserver_disconnect(rsqldb, kTRUE); rsqldb = NULL; if (persistent == kTRUE) RSQL_G(num_persistent)--; } } } PHP_MINIT_FUNCTION(rsql) { rsql_connection = zend_register_list_destructors_ex (rsql_realconnectionclose, NULL, kConnIDString, module_number); } What is the issue I encounter with this code? This php code crashes: for ($i=0; $i<10; $i++){ $dbconn = rsql_connect("127.0.0.1","admin","admin"); if (is_resource($dbconn) == 0){ print "Connection to database server failed."; exit(); } rsql_disconnect($dbconn); } and also this one: for ($i=0; $i<10; $i++){ $dbconn = rsql_connect("127.0.0.1","admin","admin"); if (is_resource($dbconn) == 0){ print "Connection to database server failed."; exit(); } } What I think is that when rsql_disconnect is called explicitly or by the destructor (rsql_realconnectionclose) my custom struct isn't really deleted from the zend_list. I really appreciate any help for my issue... Thanks a lot, Marco Bambini

Wez Furlong

20 years ago
On 11/9/05, Marco Bambini <marco@vampiresoft.com> wrote:
> ZEND_FUNCTION(rsql_disconnect) > { > ... > ZEND_FETCH_RESOURCE2(rsqldb, void*, theConnectionParameter, -1, > kConnIDString, rsql_connection, rsql_pconnection); > if (rsqldb) zend_list_delete(Z_LVAL_PP(theConnectionParameter)); > if (rsqldb) myCustomFree(rsqldb);
Removing the call to myCustomFree should solve your problem; the list destructor is calling it once for you, and you're then trying to free somthing that is no longer valid. --Wez