Skip to content

Commit

Permalink
Feature v5.1.x 同步main分支源码 (#753)
Browse files Browse the repository at this point in the history
* 完善 upgrade php version to 8.1.29 (#752)

* update

* sync php code

* update extension swoole code

* update setup-php-runtime.sh (#751)

* upate ext/swoole to v5.1.4

* 添加目录说明
  • Loading branch information
jingjingxyk authored Aug 29, 2024
1 parent 10d12ad commit 4e05fd5
Show file tree
Hide file tree
Showing 23 changed files with 314 additions and 115 deletions.
133 changes: 84 additions & 49 deletions TSRM/TSRM.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,23 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
return 1;
}/*}}}*/

static void ts_free_resources(tsrm_tls_entry *thread_resources)
{
/* Need to destroy in reverse order to respect dependencies. */
for (int i = thread_resources->count - 1; i >= 0; i--) {
if (!resource_types_table[i].done) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
}

if (!resource_types_table[i].fast_offset) {
free(thread_resources->storage[i]);
}
}
}

free(thread_resources->storage);
}

/* Shutdown TSRM (call once for the entire process) */
TSRM_API void tsrm_shutdown(void)
Expand All @@ -183,20 +200,13 @@ TSRM_API void tsrm_shutdown(void)
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;

while (p) {
int j;

next_p = p->next;
for (j=0; j<p->count; j++) {
if (p->storage[j]) {
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
}
if (!resource_types_table[j].fast_offset) {
free(p->storage[j]);
}
}
if (resource_types_table) {
/* This call will already free p->storage for us */
ts_free_resources(p);
} else {
free(p->storage);
}
free(p->storage);
free(p);
p = next_p;
}
Expand Down Expand Up @@ -283,9 +293,9 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
tsrm_resource_type *_tmp;
_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
if (!_tmp) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
*rsrc_id = 0;
tsrm_mutex_unlock(tsmm_mutex);
return 0;
}
resource_types_table = _tmp;
Expand Down Expand Up @@ -326,10 +336,10 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz

size = TSRM_ALIGNED_SIZE(size);
if (tsrm_reserved_size - tsrm_reserved_pos < size) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate space for fast resource"));
*rsrc_id = 0;
*offset = 0;
tsrm_mutex_unlock(tsmm_mutex);
return 0;
}

Expand All @@ -341,9 +351,9 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz
tsrm_resource_type *_tmp;
_tmp = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
if (!_tmp) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
*rsrc_id = 0;
tsrm_mutex_unlock(tsmm_mutex);
return 0;
}
resource_types_table = _tmp;
Expand All @@ -362,7 +372,13 @@ TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, siz
return *rsrc_id;
}/*}}}*/

static void set_thread_local_storage_resource_to(tsrm_tls_entry *thread_resource)
{
tsrm_tls_set(thread_resource);
TSRMLS_CACHE = thread_resource;
}

/* Must be called with tsmm_mutex held */
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
{/*{{{*/
int i;
Expand All @@ -378,8 +394,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
(*thread_resources_ptr)->next = NULL;

/* Set thread local storage to this new thread resources structure */
tsrm_tls_set(*thread_resources_ptr);
TSRMLS_CACHE = *thread_resources_ptr;
set_thread_local_storage_resource_to(*thread_resources_ptr);

if (tsrm_new_thread_begin_handler) {
tsrm_new_thread_begin_handler(thread_id);
Expand All @@ -402,17 +417,14 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
if (tsrm_new_thread_end_handler) {
tsrm_new_thread_end_handler(thread_id);
}

tsrm_mutex_unlock(tsmm_mutex);
}/*}}}*/


/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
{/*{{{*/
THREAD_T thread_id;
int hash_value;
tsrm_tls_entry *thread_resources;
tsrm_tls_entry *thread_resources, **last_thread_resources;

if (!th_id) {
/* Fast path for looking up the resources for the current
Expand Down Expand Up @@ -443,25 +455,55 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)

if (!thread_resources) {
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
tsrm_mutex_unlock(tsmm_mutex);
return ts_resource_ex(id, &thread_id);
} else {
do {
if (thread_resources->thread_id == thread_id) {
break;
}
last_thread_resources = &tsrm_tls_table[hash_value];
while (thread_resources->thread_id != thread_id) {
last_thread_resources = &thread_resources->next;
if (thread_resources->next) {
thread_resources = thread_resources->next;
} else {
allocate_new_resource(&thread_resources->next, thread_id);
tsrm_mutex_unlock(tsmm_mutex);
return ts_resource_ex(id, &thread_id);
/*
* thread_resources = thread_resources->next;
* break;
*/
}
} while (thread_resources);
}
}

/* It's possible that the current thread resources are requested, and that we get here.
* This means that the TSRM key pointer and cached pointer are NULL, but there is still
* a thread resource associated with this ID in the hashtable. This can occur if a thread
* goes away, but its resources are never cleaned up, and then that thread ID is reused.
* Since we don't always have a way to know when a thread goes away, we can't clean up
* the thread's resources before the new thread spawns.
* To solve this issue, we'll free up the old thread resources gracefully (gracefully
* because there might still be resources open like database connection which need to
* be shut down cleanly). After freeing up, we'll create the new resources for this thread
* as if the stale resources never existed in the first place. From that point forward,
* it is as if that situation never occurred.
* The fact that this situation happens isn't that bad because a child process containing
* threads will eventually be respawned anyway by the SAPI, so the stale threads won't last
* forever. */
TSRM_ASSERT(thread_resources->thread_id == thread_id);
if (thread_id == tsrm_thread_id() && !tsrm_tls_get()) {
tsrm_tls_entry *next = thread_resources->next;
/* In case that extensions don't use the pointer passed from the dtor, but incorrectly
* use the global pointer, we need to setup the global pointer temporarily here. */
set_thread_local_storage_resource_to(thread_resources);
/* Free up the old resource from the old thread instance */
ts_free_resources(thread_resources);
free(thread_resources);
/* Allocate a new resource at the same point in the linked list, and relink the next pointer */
allocate_new_resource(last_thread_resources, thread_id);
thread_resources = *last_thread_resources;
thread_resources->next = next;
/* We don't have to tail-call ts_resource_ex, we can take the fast path to the return
* because we already have the correct pointer. */
}

tsrm_mutex_unlock(tsmm_mutex);

/* Read a specific resource from the thread's resources.
* This is called outside of a mutex, so have to be aware about external
* changes to the structure as we read it.
Expand All @@ -474,7 +516,6 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
void ts_free_thread(void)
{/*{{{*/
tsrm_tls_entry *thread_resources;
int i;
THREAD_T thread_id = tsrm_thread_id();
int hash_value;
tsrm_tls_entry *last=NULL;
Expand All @@ -487,17 +528,7 @@ void ts_free_thread(void)

while (thread_resources) {
if (thread_resources->thread_id == thread_id) {
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i]);
}
}
for (i=0; i<thread_resources->count; i++) {
if (!resource_types_table[i].fast_offset) {
free(thread_resources->storage[i]);
}
}
free(thread_resources->storage);
ts_free_resources(thread_resources);
if (last) {
last->next = thread_resources->next;
} else {
Expand Down Expand Up @@ -531,11 +562,13 @@ void ts_free_id(ts_rsrc_id id)

while (p) {
if (p->count > j && p->storage[j]) {
if (resource_types_table && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
}
if (!resource_types_table[j].fast_offset) {
free(p->storage[j]);
if (resource_types_table) {
if (resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j]);
}
if (!resource_types_table[j].fast_offset) {
free(p->storage[j]);
}
}
p->storage[j] = NULL;
}
Expand Down Expand Up @@ -729,13 +762,15 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
#if defined(__APPLE__) && defined(__x86_64__)
// TODO: Implement support for fast JIT ZTS code ???
return 0;
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
size_t ret;

asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret));
return ret;
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
size_t ret;

asm ("leal _tsrm_ls_cache@ntpoff,%0"
Expand Down
2 changes: 1 addition & 1 deletion TSRM/TSRM.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ TSRM_API const char *tsrm_api_name(void);
# define __has_attribute(x) 0
#endif

#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__)
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__)
# define TSRM_TLS_MODEL_ATTR
#elif __PIC__
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
Expand Down
41 changes: 37 additions & 4 deletions TSRM/tsrm_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "tsrm_win32.h"
#include "zend_virtual_cwd.h"
#include "win32/ioutil.h"
#include "win32/winutil.h"

#ifdef ZTS
static ts_rsrc_id win32_globals_id;
Expand Down Expand Up @@ -90,7 +91,7 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals)
TSRM_API void tsrm_win32_startup(void)
{/*{{{*/
#ifdef ZTS
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_dtor)tsrm_win32_dtor);
#else
tsrm_win32_ctor(&win32_globals);
#endif
Expand Down Expand Up @@ -613,6 +614,22 @@ TSRM_API int pclose(FILE *stream)
#define DESCRIPTOR_PREFIX "TSRM_SHM_DESCRIPTOR:"
#define INT_MIN_AS_STRING "-2147483648"


#define TSRM_BASE_SHM_KEY_ADDRESS 0x20000000
/* Returns a number between 0x2000_0000 and 0x3fff_ffff. On Windows, key_t is int. */
static key_t tsrm_choose_random_shm_key(key_t prev_key) {
unsigned char buf[4];
if (php_win32_get_random_bytes(buf, 4) != SUCCESS) {
return prev_key + 2;
}
uint32_t n =
((uint32_t)(buf[0]) << 24) |
(((uint32_t)buf[1]) << 16) |
(((uint32_t)buf[2]) << 8) |
(((uint32_t)buf[3]));
return (n & 0x1fffffff) + TSRM_BASE_SHM_KEY_ADDRESS;
}

TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
shm_pair *shm;
Expand All @@ -626,6 +643,9 @@ TSRM_API int shmget(key_t key, size_t size, int flags)

shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
} else {
/* IPC_PRIVATE always creates a new segment even if IPC_CREAT flag isn't passed. */
flags |= IPC_CREAT;
}

if (!shm_handle && !info_handle) {
Expand Down Expand Up @@ -662,6 +682,19 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
}
}

if (key == IPC_PRIVATE) {
/* This should call shm_get with a brand new key id that isn't used yet. See https://man7.org/linux/man-pages/man2/shmget.2.html
* Because extensions such as shmop/sysvshm can be used in userland to attach to shared memory segments, use unpredictable high positive numbers to avoid accidentally conflicting with userland. */
key = tsrm_choose_random_shm_key(TSRM_BASE_SHM_KEY_ADDRESS);
for (shm_pair *ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
if (ptr->descriptor && ptr->descriptor->shm_perm.key == key) {
key = tsrm_choose_random_shm_key(key);
ptr = TWG(shm);
continue;
}
}
}

shm = shm_get(key, NULL);
if (!shm) {
CloseHandle(shm_handle);
Expand Down Expand Up @@ -702,7 +735,7 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags)
{/*{{{*/
shm_pair *shm = shm_get(key, NULL);

if (!shm->segment) {
if (!shm || !shm->segment) {
return (void*)-1;
}

Expand All @@ -726,7 +759,7 @@ TSRM_API int shmdt(const void *shmaddr)
shm_pair *shm = shm_get(0, (void*)shmaddr);
int ret;

if (!shm->segment) {
if (!shm || !shm->segment) {
return -1;
}

Expand All @@ -746,7 +779,7 @@ TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf)
{/*{{{*/
shm_pair *shm = shm_get(key, NULL);

if (!shm->segment) {
if (!shm || !shm->segment) {
return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice.
dnl ----------------------------------------------------------------------------

AC_PREREQ([2.68])
AC_INIT([PHP],[8.1.27],[https://github.com/php/php-src/issues],[php],[https://www.php.net])
AC_INIT([PHP],[8.1.29],[https://github.com/php/php-src/issues],[php],[https://www.php.net])
AC_CONFIG_SRCDIR([main/php_version.h])
AC_CONFIG_AUX_DIR([build])
AC_PRESERVE_HELP_ORDER
Expand Down
5 changes: 5 additions & 0 deletions docs/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ php sync-source-code.php --action run


```

## 目录说明

pool :持久化目录,存放扩展、 PHP 、依赖库等文件,此目录下的文件不会被主动删除
var :运行时目录,临时存在一些文件,在完成配置或构建后将被主动清空删除
2 changes: 1 addition & 1 deletion ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ bool(false)
--- These ones should work ---
string(21) "http://test@127.0.0.1"
string(50) "http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]"
string(17) "http://test@[::1]"
string(17) "http://test@[::1]"
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ Warning: proc_open(): CreateProcess failed, error code: 2 in %s on line %d
--CLEAN--
<?php
@unlink(__DIR__ . '/ghsa-9fcc-425m-g385_001.bat');
?>
?>
Loading

0 comments on commit 4e05fd5

Please sign in to comment.