diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 6cc3c5c4190a..a3a3e5e85b5c 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -46,6 +46,7 @@ #include "zend_accelerator_util_funcs.h" #include "zend_accelerator_hash.h" #include "zend_file_cache.h" +#include "zend_atomic.h" #include "ext/pcre/php_pcre.h" #include "ext/standard/md5.h" #include "ext/hash/php_hash.h" @@ -143,6 +144,12 @@ static void preload_restart(void); # define INCREMENT(v) InterlockedIncrement64(&ZCSG(v)) # define DECREMENT(v) InterlockedDecrement64(&ZCSG(v)) # define LOCKVAL(v) (ZCSG(v)) +#elif defined(__wasi__) +static uint32_t accel_wasi_mem_usage = 0; +static uint32_t accel_wasi_restart_in = 0; +# define INCREMENT(v) __atomic_add_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) +# define DECREMENT(v) __atomic_sub_fetch(&accel_wasi_##v, 1, __ATOMIC_SEQ_CST) +# define LOCKVAL(v) __atomic_load_n(&accel_wasi_##v, __ATOMIC_SEQ_CST) #endif #define ZCG_KEY_LEN (MAXPATHLEN * 8) @@ -266,7 +273,7 @@ static ZEND_INI_MH(accel_include_path_on_modify) static inline void accel_restart_enter(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) INCREMENT(restart_in); #elif !defined(__wasi__) struct flock restart_in_progress; @@ -285,7 +292,7 @@ static inline void accel_restart_enter(void) static inline void accel_restart_leave(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) ZCSG(restart_in_progress) = false; DECREMENT(restart_in); #elif !defined(__wasi__) @@ -306,7 +313,7 @@ static inline void accel_restart_leave(void) static inline int accel_restart_is_active(void) { if (ZCSG(restart_in_progress)) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) return LOCKVAL(restart_in) != 0; #elif !defined(__wasi__) struct flock restart_check; @@ -334,7 +341,7 @@ static inline int accel_restart_is_active(void) /* Creates a read lock for SHM access */ static inline zend_result accel_activate_add(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) SHM_UNPROTECT(); INCREMENT(mem_usage); SHM_PROTECT(); @@ -357,7 +364,7 @@ static inline zend_result accel_activate_add(void) /* Releases a lock for SHM access */ static inline void accel_deactivate_sub(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) if (ZCG(counted)) { SHM_UNPROTECT(); DECREMENT(mem_usage); @@ -380,7 +387,7 @@ static inline void accel_deactivate_sub(void) static inline void accel_unlock_all(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) accel_deactivate_sub(); #elif !defined(__wasi__) if (lock_file == -1) { @@ -892,7 +899,7 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) static inline bool accel_is_inactive(void) { -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) || defined(__wasi__) /* on Windows, we don't need kill_all_lockers() because SAPIs that work on Windows don't manage child processes (and we can't do anything about hanging threads anyway); therefore @@ -2922,6 +2929,10 @@ static zend_result zend_accel_init_shm(void) ZCSG(start_time) = zend_accel_get_time(); ZCSG(last_restart_time) = 0; ZCSG(restart_in_progress) = false; +#ifdef __wasi__ + __atomic_store_n(&accel_wasi_mem_usage, 0, __ATOMIC_SEQ_CST); + __atomic_store_n(&accel_wasi_restart_in, 0, __ATOMIC_SEQ_CST); +#endif for (i = 0; i < -HT_MIN_MASK; i++) { ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX; diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index edcaf689ab7f..011c6a4f7d39 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -96,9 +96,15 @@ static int zend_file_cache_flock(int fd, int op) #elif defined(HAVE_FLOCK) # define zend_file_cache_flock flock #else -# define LOCK_SH 0 -# define LOCK_EX 1 -# define LOCK_UN 2 +# ifndef LOCK_SH +# define LOCK_SH 0 +# endif +# ifndef LOCK_EX +# define LOCK_EX 1 +# endif +# ifndef LOCK_UN +# define LOCK_UN 2 +# endif static int zend_file_cache_flock(int fd, int type) { return 0; diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 4d97081fb053..c20033b4c5c5 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -29,6 +29,7 @@ #include #include "ZendAccelerator.h" #include "zend_shared_alloc.h" +#include "zend_atomic.h" #ifdef HAVE_UNISTD_H # include #endif @@ -63,6 +64,14 @@ int lock_file = -1; static char lockfile_name[MAXPATHLEN]; #endif +#ifdef __wasi__ +# ifdef ZTS +static MUTEX_T zend_shared_alloc_wasi_mutex; +# else +static zend_atomic_bool zend_shared_alloc_wasi_lock; +# endif +#endif + static const zend_shared_memory_handler_entry handler_table[] = { #ifdef USE_MMAP { "mmap", &zend_alloc_mmap_handlers }, @@ -181,12 +190,18 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size) smm_shared_globals = &tmp_shared_globals; ZSMMG(shared_free) = requested_size - reserved_size; /* goes to tmp_shared_globals.shared_free */ -#ifndef __wasi__ #ifndef ZEND_WIN32 +#ifdef __wasi__ +#ifdef ZTS + zend_shared_alloc_wasi_mutex = tsrm_mutex_alloc(); +#else + ZEND_ATOMIC_BOOL_INIT(&zend_shared_alloc_wasi_lock, false); +#endif +#else zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path); +#endif #else zend_shared_alloc_create_lock(); -#endif #endif if (ZCG(accel_directives).memory_model && ZCG(accel_directives).memory_model[0]) { @@ -325,10 +340,17 @@ void zend_shared_alloc_shutdown(void) ZSMMG(shared_segments) = NULL; g_shared_alloc_handler = NULL; #ifndef ZEND_WIN32 - close(lock_file); + if (lock_file >= 0) { + close(lock_file); + lock_file = -1; + } # ifdef ZTS +# ifdef __wasi__ + tsrm_mutex_free(zend_shared_alloc_wasi_mutex); +# else tsrm_mutex_free(zts_lock); +# endif # endif #endif } @@ -481,7 +503,14 @@ void zend_shared_alloc_lock(void) #ifdef ZEND_WIN32 zend_shared_alloc_lock_win32(); -#elif !defined(__wasi__) +#elif defined(__wasi__) +#ifdef ZTS + tsrm_mutex_lock(zend_shared_alloc_wasi_mutex); +#else + while (zend_atomic_bool_exchange_ex(&zend_shared_alloc_wasi_lock, true)) { + } +#endif +#else struct flock mem_write_lock; mem_write_lock.l_type = F_WRLCK; @@ -531,7 +560,13 @@ void zend_shared_alloc_unlock(void) #ifdef ZEND_WIN32 zend_shared_alloc_unlock_win32(); -#elif !defined(__wasi__) +#elif defined(__wasi__) +#ifdef ZTS + tsrm_mutex_unlock(zend_shared_alloc_wasi_mutex); +#else + zend_atomic_bool_store_ex(&zend_shared_alloc_wasi_lock, false); +#endif +#else if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) { zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno); }