/* {{{ proto array accelerator_get_scripts() Get the scripts which are accelerated by ZendAccelerator */ static zval* accelerator_get_scripts(TSRMLS_D) { uint i; zval *return_value,*persistent_script_report; zend_accel_hash_entry *cache_entry; struct tm *ta; struct timeval exec_time; struct timeval fetch_time; if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled) || accelerator_shm_read_lock(TSRMLS_C) != SUCCESS) { return 0; } MAKE_STD_ZVAL(return_value); array_init(return_value); for (i = 0; i<ZCSG(hash).max_num_entries; i++) { for (cache_entry = ZCSG(hash).hash_table[i]; cache_entry; cache_entry = cache_entry->next) { zend_persistent_script *script; char *str; size_t len; if (cache_entry->indirect) continue; script = (zend_persistent_script *)cache_entry->data; MAKE_STD_ZVAL(persistent_script_report); array_init(persistent_script_report); add_assoc_stringl(persistent_script_report, "full_path", script->full_path, script->full_path_len, 1); add_assoc_long(persistent_script_report, "hits", script->dynamic_members.hits); add_assoc_long(persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption); ta = localtime(&script->dynamic_members.last_used); str = asctime(ta); len = strlen(str); if (len > 0 && str[len - 1] == '\n') len--; add_assoc_stringl(persistent_script_report, "last_used", str, len, 1); add_assoc_long(persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used); if (ZCG(accel_directives).validate_timestamps) { add_assoc_long(persistent_script_report, "timestamp", (long)script->timestamp); } timerclear(&exec_time); timerclear(&fetch_time); zend_hash_update(return_value->value.ht, cache_entry->key, cache_entry->key_length, &persistent_script_report, sizeof(zval *), NULL); } } accelerator_shm_read_unlock(TSRMLS_C); return return_value; }
/* {{{ proto array accelerator_get_scripts() Get the scripts which are accelerated by ZendAccelerator */ static int accelerator_get_scripts(zval *return_value) { uint32_t i; zval persistent_script_report; zend_accel_hash_entry *cache_entry; struct tm *ta; struct timeval exec_time; struct timeval fetch_time; if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled) || accelerator_shm_read_lock() != SUCCESS) { return 0; } array_init(return_value); for (i = 0; i<ZCSG(hash).max_num_entries; i++) { for (cache_entry = ZCSG(hash).hash_table[i]; cache_entry; cache_entry = cache_entry->next) { zend_persistent_script *script; char *str; size_t len; if (cache_entry->indirect) continue; script = (zend_persistent_script *)cache_entry->data; array_init(&persistent_script_report); add_assoc_str(&persistent_script_report, "full_path", zend_string_dup(script->script.filename, 0)); add_assoc_long(&persistent_script_report, "hits", (zend_long)script->dynamic_members.hits); add_assoc_long(&persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption); ta = localtime(&script->dynamic_members.last_used); str = asctime(ta); len = strlen(str); if (len > 0 && str[len - 1] == '\n') len--; add_assoc_stringl(&persistent_script_report, "last_used", str, len); add_assoc_long(&persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used); if (ZCG(accel_directives).validate_timestamps) { add_assoc_long(&persistent_script_report, "timestamp", (zend_long)script->timestamp); } timerclear(&exec_time); timerclear(&fetch_time); zend_hash_str_update(Z_ARRVAL_P(return_value), cache_entry->key, cache_entry->key_length, &persistent_script_report); } } accelerator_shm_read_unlock(); return 1; }
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle) { zend_string *full_path = file_handle->opened_path; int fd; char *filename; zend_persistent_script *script; zend_file_cache_metainfo info; zend_accel_hash_entry *bucket; void *mem, *checkpoint, *buf; int cache_it = 1; if (!full_path) { return NULL; } filename = zend_file_cache_get_bin_file_path(full_path); fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { efree(filename); return NULL; } if (zend_file_cache_flock(fd, LOCK_SH) != 0) { close(fd); efree(filename); return NULL; } if (read(fd, &info, sizeof(info)) != sizeof(info)) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); efree(filename); return NULL; } /* verify header */ if (memcmp(info.magic, "OPCACHE", 8) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong header)\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); efree(filename); return NULL; } if (memcmp(info.system_id, ZCG(system_id), 32) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong \"system_id\")\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); efree(filename); return NULL; } /* verify timestamp */ if (ZCG(accel_directives).validate_timestamps && zend_get_file_handle_timestamp(file_handle, NULL) != info.timestamp) { if (zend_file_cache_flock(fd, LOCK_UN) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); } close(fd); unlink(filename); efree(filename); return NULL; } checkpoint = zend_arena_checkpoint(CG(arena)); #ifdef __SSE2__ /* Align to 64-byte boundary */ mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size + 64); mem = (void*)(((zend_uintptr_t)mem + 63L) & ~63L); #else mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size); #endif if (read(fd, mem, info.mem_size + info.str_size) != (ssize_t)(info.mem_size + info.str_size)) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename); zend_file_cache_flock(fd, LOCK_UN); close(fd); unlink(filename); zend_arena_release(&CG(arena), checkpoint); efree(filename); return NULL; } if (zend_file_cache_flock(fd, LOCK_UN) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); } close(fd); /* verify checksum */ if (ZCG(accel_directives).file_cache_consistency_checks && zend_adler32(ADLER32_INIT, mem, info.mem_size + info.str_size) != info.checksum) { zend_accel_error(ACCEL_LOG_WARNING, "corrupted file '%s'\n", filename); unlink(filename); zend_arena_release(&CG(arena), checkpoint); efree(filename); return NULL; } if (!ZCG(accel_directives).file_cache_only && !ZCSG(restart_in_progress) && accelerator_shm_read_lock() == SUCCESS) { /* exclusive lock */ zend_shared_alloc_lock(); /* Check if we still need to put the file into the cache (may be it was * already stored by another process. This final check is done under * exclusive lock) */ bucket = zend_accel_hash_find_entry(&ZCSG(hash), full_path); if (bucket) { script = (zend_persistent_script *)bucket->data; if (!script->corrupted) { zend_shared_alloc_unlock(); zend_arena_release(&CG(arena), checkpoint); efree(filename); return script; } } 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_if_necessary(ACCEL_RESTART_HASH); zend_shared_alloc_unlock(); goto use_process_mem; } #ifdef __SSE2__ /* Align to 64-byte boundary */ buf = zend_shared_alloc(info.mem_size + 64); buf = (void*)(((zend_uintptr_t)buf + 63L) & ~63L); #else buf = zend_shared_alloc(info.mem_size); #endif if (!buf) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); zend_shared_alloc_unlock(); goto use_process_mem; } memcpy(buf, mem, info.mem_size); } else { use_process_mem: buf = mem; cache_it = 0; } ZCG(mem) = ((char*)mem + info.mem_size); script = (zend_persistent_script*)((char*)buf + info.script_offset); script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */ zend_file_cache_unserialize(script, buf); script->corrupted = 0; if (cache_it) { script->dynamic_members.checksum = zend_accel_script_checksum(script); script->dynamic_members.last_used = ZCG(request_time); zend_accel_hash_update(&ZCSG(hash), ZSTR_VAL(script->script.filename), ZSTR_LEN(script->script.filename), 0, script); zend_shared_alloc_unlock(); zend_arena_release(&CG(arena), checkpoint); } efree(filename); return script; }