Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ext/opcache/ZendAccelerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ typedef struct _zend_accel_globals {
bool counted; /* the process uses shared memory */
bool enabled;
bool locked; /* thread obtained exclusive lock */
#ifdef ZTS
uint32_t unprotect_depth;
#endif
bool accelerator_enabled; /* accelerator enabled for current request */
bool pcre_reseted;
zend_accel_directives accel_directives;
Expand Down
44 changes: 37 additions & 7 deletions ext/opcache/zend_shared_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ static const char *g_shared_model;
/* pointer to globals allocated in SHM and shared across processes */
ZEND_EXT_API zend_smm_shared_globals *smm_shared_globals;

#ifdef ZTS
static MUTEX_T zts_protect_lock;
static uint32_t zts_unprotected_threads;
#endif

#ifndef ZEND_WIN32
#ifdef ZTS
static MUTEX_T zts_lock;
Expand Down Expand Up @@ -184,6 +189,11 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size)
int res = ALLOC_FAILURE;
int i;

#ifdef ZTS
zts_protect_lock = tsrm_mutex_alloc();
zts_unprotected_threads = 0;
#endif

/* shared_free must be valid before we call zend_shared_alloc()
* - make it temporarily point to a local variable
*/
Expand Down Expand Up @@ -338,6 +348,9 @@ void zend_shared_alloc_shutdown(void)
tsrm_mutex_free(zts_lock);
# endif
#endif
#ifdef ZTS
tsrm_mutex_free(zts_protect_lock);
#endif
}

static size_t zend_shared_alloc_get_largest_free_block(void)
Expand Down Expand Up @@ -625,25 +638,37 @@ const char *zend_accel_get_shared_model(void)

void zend_accel_shared_protect(bool protected)
{
#ifdef HAVE_MPROTECT
#if defined(HAVE_MPROTECT) || defined(ZEND_WIN32)
int i;

if (!smm_shared_globals) {
return;
}

#ifdef ZTS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please indent nested preprocessor directives:

Suggested change
#ifdef ZTS
# ifdef ZTS

/* Memory protection is process-wide, so overlapping writers must be tracked across threads. */
tsrm_mutex_lock(zts_protect_lock);
if (protected) {
if (ZCG(unprotect_depth) && --ZCG(unprotect_depth) == 0) {
ZEND_ASSERT(zts_unprotected_threads > 0);
zts_unprotected_threads--;
}
if (zts_unprotected_threads) {
tsrm_mutex_unlock(zts_protect_lock);
return;
}
} else if (ZCG(unprotect_depth)++ == 0) {
zts_unprotected_threads++;
}
#endif

#ifdef HAVE_MPROTECT
const int mode = protected ? PROT_READ : PROT_READ|PROT_WRITE;

for (i = 0; i < ZSMMG(shared_segments_count); i++) {
mprotect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->end, mode);
}
#elif defined(ZEND_WIN32)
int i;

if (!smm_shared_globals) {
return;
}

const int mode = protected ? PAGE_READONLY : PAGE_READWRITE;

for (i = 0; i < ZSMMG(shared_segments_count); i++) {
Expand All @@ -653,6 +678,11 @@ void zend_accel_shared_protect(bool protected)
}
}
#endif

#ifdef ZTS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

tsrm_mutex_unlock(zts_protect_lock);
#endif
#endif
}

bool zend_accel_in_shm(void *ptr)
Expand Down
Loading