/** @file Parser: compiled code cache. Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) Authors: Konstantin Morshnev */ #include "pa_code_cache.h" volatile const char * IDENT_PA_CODE_CACHE_C="$Id: pa_code_cache.C,v 1.1 2026/10/05 17:50:18 moko Exp $" IDENT_PA_CODE_CACHE_H; #ifdef CODE_CACHE Code_cache::Code_cache(const String& afile_spec): file_spec(afile_spec), file_no(0), fsize(0), fmtime(0) { time_t atime, ctime; file_stat(file_spec, fsize, atime, fmtime, ctime, false); } void Code_cache::add(Kind kind, const String* name, Method* method) { Action action={kind, name, method, Operation::Origin::create(0, 0, 0)}; actions+=action; } void Code_cache::add_use(const String* name, Operation::Origin origin) { Action action={USE, name, 0, origin}; actions+=action; } bool Code_cache::unchanged() { uint64_t size; time_t atime, mtime, ctime; return file_stat(file_spec, size, atime, mtime, ctime, false) && size==fsize && mtime==fmtime; } // filled while the httpd config runs, only read in the subsequent requests static HashString* code_cache=0; // file_list of the config run static Array* code_cache_files=0; static bool code_cache_recording=false; static bool code_cache_enabled=true; void Code_cache_manager::start() { code_cache=new HashString; code_cache_recording=true; } void Code_cache_manager::finish(Request& r) { code_cache_recording=false; if(code_cache_enabled) { code_cache_files=new Array; code_cache_files->append(r.file_list); } else code_cache=0; } void Code_cache_manager::set_enabled(bool aenabled) { if(code_cache_recording) code_cache_enabled=aenabled; } void Code_cache_manager::add_files(Array& file_list) { if(code_cache_files) // the request has only the pseudo files yet, the same as in the config run file_list.append(*code_cache_files, file_list.count()); } Code_cache* Code_cache_manager::get(const String& file_spec) { if(code_cache && !code_cache_recording) if(Code_cache* code=code_cache->get(file_spec)) if(code->unchanged()) return code; return 0; } Code_cache* Code_cache_manager::create(const String& file_spec) { // size and time are taken before reading return code_cache_recording ? new Code_cache(file_spec) : 0; } void Code_cache_manager::put(Code_cache& code) { code_cache->put(code.file_spec, &code); } #endif