}
}
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC)
+{
+ if ((((double) ZSMMG(wasted_shared_memory)) / ZCG(accel_directives).memory_consumption) >= ZCG(accel_directives).max_wasted_percentage) {
+ zend_accel_schedule_restart(reason TSRMLS_CC);
+ }
+}
+
/* O+ tracks changes of "include_path" directive. It stores all the requested
* values in ZCG(include_paths) shared hash table, current value in
* ZCG(include_path)/ZCG(include_path_len) and one letter "path key" in
key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
ZCG(include_path_key) = key + ZCG(include_path_len) + 1;
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
- }
- }
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
+ }
zend_shared_alloc_unlock(TSRMLS_C);
SHM_PROTECT();
return FAILURE;
}
-static void zend_accel_schedule_restart_if_necessary(TSRMLS_D)
-{
- if ((((double) ZSMMG(wasted_shared_memory)) / ZCG(accel_directives).memory_consumption) >= ZCG(accel_directives).max_wasted_percentage) {
- ZSMMG(memory_exhausted) = 1;
- zend_accel_schedule_restart(ACCEL_RESTART_WASTED TSRMLS_CC);
- }
-}
-
static inline int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC)
{
if (ZCG(accel_directives).revalidate_freq &&
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
include_path = ZCG(include_path_key);
include_path_len = 1;
- }
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
}
zend_shared_alloc_unlock(TSRMLS_C);
if (zend_accel_hash_is_full(&ZCSG(hash))) {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1;
- zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC);
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
} else {
char *new_key = zend_shared_alloc(key_length + 1);
if (new_key) {
memcpy(new_key, key, key_length + 1);
zend_accel_hash_update(&ZCSG(hash), new_key, key_length + 1, 1, bucket);
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
}
}
}
if (zend_accel_hash_is_full(&ZCSG(hash))) {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1;
- zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC);
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
zend_shared_alloc_unlock(TSRMLS_C);
return new_persistent_script;
}
/* Allocate shared memory */
ZCG(mem) = zend_shared_alloc(memory_used);
if (!ZCG(mem)) {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
zend_shared_alloc_unlock(TSRMLS_C);
return new_persistent_script;
}
if (!zend_accel_hash_update(&ZCSG(hash), key, key_length + 1, 1, bucket)) {
zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
ZSMMG(memory_exhausted) = 1;
- zend_accel_schedule_restart(ACCEL_RESTART_HASH TSRMLS_CC);
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
}
}
persistent_script->corrupted = 1;
persistent_script->timestamp = 0;
ZSMMG(wasted_shared_memory) += persistent_script->dynamic_members.memory_consumption;
- zend_accel_schedule_restart_if_necessary(TSRMLS_C);
+ if (ZSMMG(memory_exhausted)) {
+ zend_accel_restart_reason reason =
+ zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+ zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+ }
}
zend_shared_alloc_unlock(TSRMLS_C);
persistent_script = NULL;
persistent_script->corrupted = 1;
persistent_script->timestamp = 0;
ZSMMG(wasted_shared_memory) += persistent_script->dynamic_members.memory_consumption;
- zend_accel_schedule_restart_if_necessary(TSRMLS_C);
+ if (ZSMMG(memory_exhausted)) {
+ zend_accel_restart_reason reason =
+ zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+ zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+ }
}
zend_shared_alloc_unlock(TSRMLS_C);
persistent_script = NULL;
case ACCEL_RESTART_OOM:
ZCSG(oom_restarts)++;
break;
- case ACCEL_RESTART_WASTED:
- ZCSG(wasted_restarts)++;
- break;
case ACCEL_RESTART_HASH:
ZCSG(hash_restarts)++;
break;
zend_reset_cache_vars(TSRMLS_C);
ZCSG(oom_restarts) = 0;
- ZCSG(wasted_restarts) = 0;
ZCSG(hash_restarts) = 0;
ZCSG(manual_restarts) = 0;
key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
ZCG(include_path_key) = key + ZCG(include_path_len) + 1;
zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
}
zend_shared_alloc_unlock(TSRMLS_C);
}
typedef enum _zend_accel_restart_reason {
ACCEL_RESTART_OOM, /* restart because of out of memory */
- ACCEL_RESTART_WASTED, /* restart because of wasted memory */
ACCEL_RESTART_HASH, /* restart because of hash overflow */
ACCEL_RESTART_USER /* restart sheduled by opcache_reset() */
} zend_accel_restart_reason;
unsigned long misses;
unsigned long blacklist_misses;
unsigned long oom_restarts; /* number of restarts because of out of memory */
- unsigned long wasted_restarts; /* number of restarts because of wasted memory */
unsigned long hash_restarts; /* number of restarts because of hash overflow */
unsigned long manual_restarts; /* number of restarts sheduled by opcache_reset() */
zend_accel_hash hash; /* hash table for cached scripts */
extern char *zps_api_failure_reason;
void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC);
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC);
int accelerator_shm_read_lock(TSRMLS_D);
void accelerator_shm_read_unlock(TSRMLS_D);
php_info_print_table_row(2, "Max keys", buf);
snprintf(buf, sizeof(buf), "%ld", ZCSG(oom_restarts));
php_info_print_table_row(2, "OOM restarts", buf);
- snprintf(buf, sizeof(buf), "%ld", ZCSG(wasted_restarts));
- php_info_print_table_row(2, "Wasted memory restarts", buf);
snprintf(buf, sizeof(buf), "%ld", ZCSG(hash_restarts));
php_info_print_table_row(2, "Hash keys restarts", buf);
snprintf(buf, sizeof(buf), "%ld", ZCSG(manual_restarts));
add_assoc_long(statistics, "start_time", ZCSG(start_time));
add_assoc_long(statistics, "last_restart_time", ZCSG(last_restart_time));
add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts));
- add_assoc_long(statistics, "wasted_restarts", ZCSG(wasted_restarts));
add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts));
add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts));
add_assoc_long(statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
/* move shared_segments and shared_free to shared memory */
ZCG(locked) = 1; /* no need to perform a real lock at this point */
p_tmp_shared_globals = (zend_smm_shared_globals *) zend_shared_alloc(sizeof(zend_smm_shared_globals));
+ if (!p_tmp_shared_globals) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
tmp_shared_segments = zend_shared_alloc(shared_segments_array_size + ZSMMG(shared_segments_count) * sizeof(void *));
+ if (!tmp_shared_segments) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
+
copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], ZSMMG(shared_segments_count), S_H(segment_type_size)());
*p_tmp_shared_globals = tmp_shared_globals;
ZSMMG(shared_segments) = tmp_shared_segments;
ZSMMG(shared_memory_state).positions = (int *)zend_shared_alloc(sizeof(int) * ZSMMG(shared_segments_count));
+ if (!ZSMMG(shared_memory_state).positions) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
+
ZCG(locked) = 0;
return res;
zend_accel_error(ACCEL_LOG_WARNING, "Not enough free shared space to allocate %ld bytes (%ld bytes free)", (long)size, (long)ZSMMG(shared_free)); \
if (zend_shared_alloc_get_largest_free_block() < MIN_FREE_MEMORY) { \
ZSMMG(memory_exhausted) = 1; \
- zend_accel_schedule_restart(ACCEL_RESTART_OOM TSRMLS_CC); \
} \
} while (0)