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 checkpoint;
/* exclusive lock */
zend_shared_alloc_lock();
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!");
return NULL;
}
@ -3602,7 +3598,6 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s
}
#endif
if (!ZCG(mem)) {
zend_shared_alloc_unlock();
zend_accel_error(ACCEL_LOG_FATAL, "Not enough shared memory for preloading!");
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);
zend_shared_alloc_unlock();
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)
{
zend_file_handle file_handle;
@ -3748,43 +3769,19 @@ static int accel_preload(const char *config)
ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0);
/* Load into system heap */
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;
preload_load();
/* Store individual scripts with unlinked classes */
HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT();
i = 0;
zend_shared_alloc_lock();
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) {
ZCSG(saved_scripts)[i++] = preload_script_in_shared_memory(script);
} ZEND_HASH_FOREACH_END();
ZCSG(saved_scripts)[i] = NULL;
CG(map_ptr_last) = ZCSG(map_ptr_last);
zend_shared_alloc_save_state();
accel_interned_strings_save_state();
@ -3826,6 +3823,17 @@ static int accel_finish_startup(void)
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.deactivate = 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.getenv = orig_getenv;
zend_shared_alloc_unlock();
sapi_activate();
return ret;