Restore preload state if it was already loaded in another process.

This commit is contained in:
Dmitry Stogov 2018-10-26 13:11:54 +03:00
parent 0fe9ea1c07
commit d7fbb4d402

View file

@ -3545,11 +3545,7 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
uint32_t memory_used; uint32_t memory_used;
uint32_t checkpoint; uint32_t checkpoint;
/* exclusive lock */
zend_shared_alloc_lock();
if (zend_accel_hash_is_full(&ZCSG(hash))) { if (zend_accel_hash_is_full(&ZCSG(hash))) {
zend_shared_alloc_unlock();
zend_accel_error(ACCEL_LOG_FATAL, "Not enough entries in hash table for preloading!"); zend_accel_error(ACCEL_LOG_FATAL, "Not enough entries in hash table for preloading!");
return NULL; return NULL;
} }
@ -3602,7 +3598,6 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
} }
#endif #endif
if (!ZCG(mem)) { if (!ZCG(mem)) {
zend_shared_alloc_unlock();
zend_accel_error(ACCEL_LOG_FATAL, "Not enough shared memory for preloading!"); zend_accel_error(ACCEL_LOG_FATAL, "Not enough shared memory for preloading!");
return NULL; return NULL;
} }
@ -3635,11 +3630,37 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
new_persistent_script->dynamic_members.memory_consumption = ZEND_ALIGNED_SIZE(new_persistent_script->size); new_persistent_script->dynamic_members.memory_consumption = ZEND_ALIGNED_SIZE(new_persistent_script->size);
zend_shared_alloc_unlock();
return new_persistent_script; return new_persistent_script;
} }
static void preload_load(void)
{
/* Load into process tables */
if (zend_hash_num_elements(&ZCSG(preload_script)->script.function_table)) {
Bucket *p = ZCSG(preload_script)->script.function_table.arData;
Bucket *end = p + ZCSG(preload_script)->script.function_table.nNumUsed;
for (; p != end; p++) {
_zend_hash_append_ptr_ex(EG(function_table), p->key, Z_PTR(p->val), 1);
}
}
if (zend_hash_num_elements(&ZCSG(preload_script)->script.class_table)) {
Bucket *p = ZCSG(preload_script)->script.class_table.arData;
Bucket *end = p + ZCSG(preload_script)->script.class_table.nNumUsed;
for (; p != end; p++) {
_zend_hash_append_ptr_ex(EG(class_table), p->key, Z_PTR(p->val), 1);
}
}
EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
EG(persistent_functions_count) = EG(function_table)->nNumUsed;
EG(persistent_classes_count) = EG(class_table)->nNumUsed;
CG(map_ptr_last) = ZCSG(map_ptr_last);
}
static int accel_preload(const char *config) static int accel_preload(const char *config)
{ {
zend_file_handle file_handle; zend_file_handle file_handle;
@ -3748,43 +3769,19 @@ static int accel_preload(const char *config)
ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0); ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0);
/* Load into system heap */ preload_load();
if (zend_hash_num_elements(&ZCSG(preload_script)->script.function_table)) {
Bucket *p = ZCSG(preload_script)->script.function_table.arData;
Bucket *end = p + ZCSG(preload_script)->script.function_table.nNumUsed;
for (; p != end; p++) {
_zend_hash_append_ptr_ex(EG(function_table), p->key, Z_PTR(p->val), 1);
}
}
if (zend_hash_num_elements(&ZCSG(preload_script)->script.class_table)) {
Bucket *p = ZCSG(preload_script)->script.class_table.arData;
Bucket *end = p + ZCSG(preload_script)->script.class_table.nNumUsed;
for (; p != end; p++) {
_zend_hash_append_ptr_ex(EG(class_table), p->key, Z_PTR(p->val), 1);
}
}
EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
EG(persistent_functions_count) = EG(function_table)->nNumUsed;
EG(persistent_classes_count) = EG(class_table)->nNumUsed;
/* Store individual scripts with unlinked classes */ /* Store individual scripts with unlinked classes */
HANDLE_BLOCK_INTERRUPTIONS(); HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT(); SHM_UNPROTECT();
i = 0; i = 0;
zend_shared_alloc_lock();
ZCSG(saved_scripts) = zend_shared_alloc((zend_hash_num_elements(preload_scripts) + 1) * sizeof(void*)); ZCSG(saved_scripts) = zend_shared_alloc((zend_hash_num_elements(preload_scripts) + 1) * sizeof(void*));
zend_shared_alloc_unlock();
ZEND_HASH_FOREACH_PTR(preload_scripts, script) { ZEND_HASH_FOREACH_PTR(preload_scripts, script) {
ZCSG(saved_scripts)[i++] = preload_script_in_shared_memory(script); ZCSG(saved_scripts)[i++] = preload_script_in_shared_memory(script);
} ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END();
ZCSG(saved_scripts)[i] = NULL; ZCSG(saved_scripts)[i] = NULL;
CG(map_ptr_last) = ZCSG(map_ptr_last);
zend_shared_alloc_save_state(); zend_shared_alloc_save_state();
accel_interned_strings_save_state(); accel_interned_strings_save_state();
@ -3826,6 +3823,17 @@ static int accel_finish_startup(void)
return SUCCESS; return SUCCESS;
} }
/* exclusive lock */
zend_shared_alloc_lock();
if (ZCSG(preload_script)) {
/* Preloading was done in another process */
preload_load();
preload_restart();
zend_shared_alloc_unlock();
return SUCCESS;
}
sapi_module.activate = NULL; sapi_module.activate = NULL;
sapi_module.deactivate = NULL; sapi_module.deactivate = NULL;
sapi_module.register_server_variables = NULL; sapi_module.register_server_variables = NULL;
@ -3877,6 +3885,8 @@ static int accel_finish_startup(void)
sapi_module.send_header = orig_send_header; sapi_module.send_header = orig_send_header;
sapi_module.getenv = orig_getenv; sapi_module.getenv = orig_getenv;
zend_shared_alloc_unlock();
sapi_activate(); sapi_activate();
return ret; return ret;