Persistent resources are "thread-local".

Register persistent resources through new functions zend_register_persistent_resource()/zend_register_persistent_resource_ex().
This commit is contained in:
Dmitry Stogov 2017-11-01 15:19:31 +03:00
parent f5664a1492
commit 67d5f39a47
11 changed files with 59 additions and 41 deletions

View file

@ -16,6 +16,7 @@ PHP 7.2 INTERNALS UPGRADE NOTES
m. AST and IS_CONSTANT
n. GC_REFCOUNT()
o. zend_get_parameters()
p. zend_register_persistent_resource()
2. Build system changes
a. Unix build system changes
@ -112,6 +113,10 @@ PHP 7.2 INTERNALS UPGRADE NOTES
o. The zend_get_parameters() and zend_get_parameters_ex() functions were
removed. Instead zend_parse_parameters() should be used.
p. New functions zend_register_persistent_resource() or
zend_register_persistent_resource_ex() should beused to register
persistent resources, instead of manual insertion into EG(persistent_list).
========================
2. Build system changes
========================

View file

@ -337,6 +337,36 @@ const char *zend_rsrc_list_get_rsrc_type(zend_resource *res)
}
}
ZEND_API zend_resource* zend_register_persistent_resource_ex(zend_string *key, void *rsrc_pointer, int rsrc_type)
{
zval *zv;
zval tmp;
ZVAL_NEW_PERSISTENT_RES(&tmp, -1, rsrc_pointer, rsrc_type);
GC_MAKE_PERSISTENT_LOCAL(Z_COUNTED(tmp));
GC_MAKE_PERSISTENT_LOCAL(key);
zv = zend_hash_update(&EG(persistent_list), key, &tmp);
if (UNEXPECTED(zv == NULL)) {
free(Z_RES(tmp));
return NULL;
}
return Z_RES_P(zv);
}
ZEND_API zend_resource* zend_register_persistent_resource(const char *key, size_t key_len, void *rsrc_pointer, int rsrc_type)
{
zend_string *str = zend_string_init(key, key_len, 1);
zend_resource *ret = zend_register_persistent_resource_ex(str, rsrc_pointer, rsrc_type);
if (UNEXPECTED(ret == NULL)) {
free(str);
}
return ret;
}
/*
* Local variables:
* tab-width: 4

View file

@ -68,6 +68,9 @@ ZEND_API void *zend_fetch_resource2_ex(zval *res, const char *resource_type_name
ZEND_API const char *zend_rsrc_list_get_rsrc_type(zend_resource *res);
ZEND_API int zend_fetch_list_dtor_id(const char *type_name);
ZEND_API zend_resource* zend_register_persistent_resource(const char *key, size_t key_len, void *rsrc_pointer, int rsrc_type);
ZEND_API zend_resource* zend_register_persistent_resource_ex(zend_string *key, void *rsrc_pointer, int rsrc_type);
extern ZEND_API int le_index_ptr; /* list entry type for index pointers */
END_EXTERN_C()

View file

@ -997,10 +997,7 @@ restart:
info->argv = NULL;
if (persistent) {
zval new_le;
ZVAL_NEW_PERSISTENT_RES(&new_le, -1, info, le_pdb);
if (zend_hash_str_update(&EG(persistent_list), key, keylen, &new_le) == NULL) {
if (zend_register_persistent_resource(key, keylen, info, le_pdb) == NULL) {
dba_close(info);
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Could not register persistent resource");
FREENOW;

View file

@ -991,18 +991,13 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
RETVAL_RES(zend_register_resource(ib_link, le_link));
} else {
zend_resource new_le;
ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
if (!ib_link) {
RETURN_FALSE;
}
/* hash it up */
new_le.type = le_plink;
new_le.ptr = ib_link;
if (zend_hash_str_update_mem(&EG(persistent_list), hash, sizeof(hash)-1,
(void *) &new_le, sizeof(zend_resource)) == NULL) {
if (zend_register_persistent_resource(hash, sizeof(hash)-1, ib_link, le_plink) == NULL) {
free(ib_link);
RETURN_FALSE;
}

View file

@ -196,12 +196,10 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
} while (0);
}
} else {
zend_resource le;
le.type = php_le_pmysqli();
le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
plist = calloc(1, sizeof(mysqli_plist_entry));
zend_ptr_stack_init_ex(&plist->free_links, 1);
zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(hash_key), ZSTR_LEN(hash_key), &le, sizeof(le));
zend_register_persistent_resource(ZSTR_VAL(hash_key), ZSTR_LEN(hash_key), plist, php_le_pmysqli());
}
}
}

View file

@ -2041,8 +2041,10 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
/* add to the appropriate hash */
if (connection->is_persistent) {
#if PHP_VERSION_ID < 70300
new_le.ptr = connection;
new_le.type = le_pconnection;
#endif
connection->used_this_request = 1;
PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection);
@ -2053,7 +2055,11 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
if (OCI_G(old_oci_close_semantics)) {
GC_ADDREF(connection->id);
}
#if PHP_VERSION_ID < 70300
zend_hash_update_mem(&EG(persistent_list), connection->hash_key, (void *)&new_le, sizeof(zend_resource));
#else
zend_register_persistent_resource_ex(connection->hash_key, connection, le_pconnection);
#endif
OCI_G(num_persistent)++;
OCI_G(num_links)++;
} else if (!exclusive) {
@ -2874,7 +2880,9 @@ static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *
{
smart_str spool_hashed_details = {0};
php_oci_spool *session_pool = NULL;
#if PHP_VERSION_ID < 70300
zend_resource spool_le = {{0}};
#endif
zend_resource *spool_out_le = NULL;
zend_bool iserror = 0;
zval *spool_out_zv = NULL;
@ -2921,10 +2929,14 @@ static php_oci_spool *php_oci_get_spool(char *username, int username_len, char *
iserror = 1;
goto exit_get_spool;
}
#if PHP_VERSION_ID < 70300
spool_le.ptr = session_pool;
spool_le.type = le_psessionpool;
PHP_OCI_REGISTER_RESOURCE(session_pool, le_psessionpool);
zend_hash_update_mem(&EG(persistent_list), session_pool->spool_hash_key, (void *)&spool_le, sizeof(zend_resource));
#else
zend_register_persistent_resource_ex(session_pool->spool_hash_key, session_pool, le_psessionpool);
#endif
} else if (spool_out_le->type == le_psessionpool &&
ZSTR_LEN(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key) == ZSTR_LEN(spool_hashed_details.s) &&
memcmp(ZSTR_VAL(((php_oci_spool *)(spool_out_le->ptr))->spool_hash_key), ZSTR_VAL(spool_hashed_details.s), ZSTR_LEN(spool_hashed_details.s)) == 0) {

View file

@ -2571,8 +2571,6 @@ try_and_get_another_connection:
/* the link is not in the persistent list */
if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_len)) == NULL) {
zend_resource new_le;
if (ODBCG(max_links) != -1 && ODBCG(num_links) >= ODBCG(max_links)) {
php_error_docref(NULL, E_WARNING, "Too many open links (%ld)", ODBCG(num_links));
efree(hashed_details);
@ -2589,11 +2587,7 @@ try_and_get_another_connection:
RETURN_FALSE;
}
new_le.type = le_pconn;
new_le.ptr = db_conn;
new_le.handle = -1;
if (zend_hash_str_update_mem(&EG(persistent_list), hashed_details, hashed_len, &new_le,
sizeof(zend_resource)) == NULL) {
if (zend_register_persistent_resource(hashed_details, hashed_len, db_conn, le_pconn) == NULL) {
free(db_conn);
efree(hashed_details);
RETURN_FALSE;

View file

@ -359,18 +359,11 @@ static PHP_METHOD(PDO, dbh_constructor)
/* all set */
if (is_persistent) {
zend_resource le;
/* register in the persistent list etc. */
/* we should also need to replace the object store entry,
since it was created with emalloc */
le.type = php_pdo_list_entry();
le.ptr = dbh;
GC_SET_REFCOUNT(&le, 1);
if ((zend_hash_str_update_mem(&EG(persistent_list),
(char*)dbh->persistent_id, dbh->persistent_id_len, &le, sizeof(le))) == NULL) {
if ((zend_register_persistent_resource(
(char*)dbh->persistent_id, dbh->persistent_id_len, dbh, php_pdo_list_entry())) == NULL) {
php_error_docref(NULL, E_ERROR, "Failed to register persistent entry");
}
}

View file

@ -1357,8 +1357,6 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
/* try to find if we already have this link in our persistent list */
if ((le = zend_hash_find_ptr(&EG(persistent_list), str.s)) == NULL) { /* we don't */
zend_resource new_le;
if (PGG(max_links) != -1 && PGG(num_links) >= PGG(max_links)) {
php_error_docref(NULL, E_WARNING,
"Cannot create new link. Too many open links (" ZEND_LONG_FMT ")", PGG(num_links));
@ -1385,9 +1383,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
}
/* hash it up */
new_le.type = le_plink;
new_le.ptr = pgsql;
if (zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(str.s), ZSTR_LEN(str.s), &new_le, sizeof(zend_resource)) == NULL) {
if (zend_register_persistent_resource(ZSTR_VAL(str.s), ZSTR_LEN(str.s), pgsql, le_plink) == NULL) {
goto err;
}
PGG(num_links)++;

View file

@ -296,12 +296,7 @@ fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persiste
}
if (persistent_id) {
zval tmp;
ZVAL_NEW_PERSISTENT_RES(&tmp, -1, ret, le_pstream);
if (NULL == zend_hash_str_update(&EG(persistent_list), persistent_id,
strlen(persistent_id), &tmp)) {
if (NULL == zend_register_persistent_resource(persistent_id, strlen(persistent_id), ret, le_pstream)) {
pefree(ret, 1);
return NULL;
}