diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 56422a721fdb..5eeb212ec09e 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -385,6 +385,23 @@ ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj); ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj); #endif +#if defined(HAVE_C11_ATOMICS) +# define ZEND_ATOMIC_FENCE_RELEASE() __c11_atomic_thread_fence(__ATOMIC_RELEASE) +# define ZEND_ATOMIC_FENCE_ACQUIRE() __c11_atomic_thread_fence(__ATOMIC_ACQUIRE) +#elif defined(HAVE_GNUC_ATOMICS) +# define ZEND_ATOMIC_FENCE_RELEASE() __atomic_thread_fence(__ATOMIC_RELEASE) +# define ZEND_ATOMIC_FENCE_ACQUIRE() __atomic_thread_fence(__ATOMIC_ACQUIRE) +#elif defined(HAVE_SYNC_ATOMICS) +# define ZEND_ATOMIC_FENCE_RELEASE() __sync_synchronize() +# define ZEND_ATOMIC_FENCE_ACQUIRE() __sync_synchronize() +#elif defined(ZEND_WIN32) +# define ZEND_ATOMIC_FENCE_RELEASE() MemoryBarrier() +# define ZEND_ATOMIC_FENCE_ACQUIRE() MemoryBarrier() +#else +# define ZEND_ATOMIC_FENCE_RELEASE() ((void)0) +# define ZEND_ATOMIC_FENCE_ACQUIRE() ((void)0) +#endif + END_EXTERN_C() #endif diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 221cc55d9f6d..cf54454afbb7 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2302,6 +2302,10 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, bool needs_autoload; zend_inheritance_cache_entry *entry = ce->inheritance_cache; + if (entry) { + ZEND_ATOMIC_FENCE_ACQUIRE(); + } + while (entry) { entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); if (entry) { @@ -2458,12 +2462,13 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, entry->num_warnings = EG(num_errors); entry->warnings = zend_persist_warnings(EG(num_errors), EG(errors)); entry->next = proto->inheritance_cache; - proto->inheritance_cache = entry; EG(num_errors) = 0; EG(errors) = NULL; ZCSG(map_ptr_last) = CG(map_ptr_last); + ZEND_ATOMIC_FENCE_RELEASE(); + proto->inheritance_cache = entry; zend_shared_alloc_destroy_xlat_table();