--- parser3/src/main/pa_stylesheet_manager.C 2001/11/05 10:42:59 1.3 +++ parser3/src/main/pa_stylesheet_manager.C 2026/04/25 13:38:46 1.38 @@ -1,17 +1,13 @@ /** @file Parser: sql driver manager implementation. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: pa_stylesheet_manager.C,v 1.3 2001/11/05 10:42:59 paf Exp $ + Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "pa_config_includes.h" #ifdef XML #include "pa_stylesheet_manager.h" -#include "pa_stylesheet_connection.h" -#include "ltdl.h" #include "pa_exception.h" #include "pa_common.h" #include "pa_threads.h" @@ -19,84 +15,60 @@ #include "pa_vhash.h" #include "pa_vtable.h" +volatile const char * IDENT_PA_STYLESHEET_MANAGER_C="$Id: pa_stylesheet_manager.C,v 1.38 2026/04/25 13:38:46 moko Exp $" IDENT_PA_STYLESHEET_MANAGER_H; + // globals -Stylesheet_manager *stylesheet_manager; +Stylesheet_manager* stylesheet_manager=0; // consts -const int EXPIRE_UNUSED_CONNECTION_SECONDS=5*60; -const int CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2; +const time_t EXPIRE_UNUSED_CONNECTION_SECONDS=5*60; +const time_t CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2; // helpers -static void expire_connection(Array::Item *value, void *info) { - Stylesheet_connection& connection=*static_cast(value); - time_t older_dies=reinterpret_cast(info); - +static void expire_connection(Stylesheet_connection& connection, time_t older_dies) { if(connection.connected() && connection.expired(older_dies)) connection.disconnect(); } -static void expire_connections(const Hash::Key& key, Hash::Val *value, void *info) { - Stack& stack=*static_cast(value); - for(int i=0; i<=stack.top_index(); i++) - expire_connection(stack.get(i), info); +static void expire_connections(Stylesheet_manager::connection_cache_type::key_type /*key*/, Stylesheet_manager::connection_cache_type::value_type stack, time_t older_dies) { + for(size_t i=0; itop_index(); i++) + expire_connection(*stack->get(i), older_dies); } -// Stylesheet_manager - -Stylesheet_manager::Stylesheet_manager(Pool& apool) : Pooled(apool), - connection_cache(apool), - prev_expiration_pass_time(0) { - - status_providers->put(*NEW String(pool(), "stylesheet"), this); -} -Stylesheet_manager::~Stylesheet_manager() { - connection_cache.for_each(expire_connections, - reinterpret_cast((time_t)0/*=in past=expire all*/)); +// Stylesheet_connection methods + +void Stylesheet_connection::close() { + stylesheet_manager->close_connection(ffile_spec, *this); } -Stylesheet_connection& Stylesheet_manager::get_connection(const String& request_file_spec) { - Pool& pool=request_file_spec.pool(); // request pool +// Stylesheet_manager methods - // first trying to get cached stylesheet - Stylesheet_connection *result=get_connection_from_cache(request_file_spec); - if(!result) { - // then just construct it - - // make global_file_spec C-string on global pool - const char *request_file_spec_cstr=request_file_spec.cstr(String::UL_FILE_SPEC); - char *global_file_spec_cstr=(char *)malloc(strlen(request_file_spec_cstr)+1); - strcpy(global_file_spec_cstr, request_file_spec_cstr); - // make global_file_spec string on global pool - String& global_file_spec=*new(this->pool()) String(this->pool(), global_file_spec_cstr); +Stylesheet_manager::Stylesheet_manager(): prev_expiration_pass_time(0) { +} - result=new(this->pool()) Stylesheet_connection(this->pool(), global_file_spec); - } - // associate with services[request] (deassociates at close) - result->set_services(&pool); - // return it - return *result; +Stylesheet_manager::~Stylesheet_manager() { + connection_cache.for_each(expire_connections, time(0)+(time_t)10/*=in future=expire all*/); } -void Stylesheet_manager::close_connection(const String& file_spec, - Stylesheet_connection& connection) { - // deassociate from services[request] - connection.set_services(0); - put_connection_to_cache(file_spec, connection); +Stylesheet_connection* Stylesheet_manager::get_connection(String::Body file_spec) { + Stylesheet_connection* result=get_connection_from_cache(file_spec); + return result ? result : new Stylesheet_connection(file_spec); } +void Stylesheet_manager::close_connection(String::Body file_spec, Stylesheet_connection& connection) { + put_connection_to_cache(file_spec, connection); +} // stylesheet cache /// @todo get rid of memory spending Stack [zeros deep inside got accumulated] -Stylesheet_connection *Stylesheet_manager::get_connection_from_cache(const String& file_spec) { +Stylesheet_connection* Stylesheet_manager::get_connection_from_cache(String::Body file_spec) { SYNCHRONIZED; - maybe_expire_connection_cache(); - - if(Stack *connections=static_cast(connection_cache.get(file_spec))) - while(connections->top_index()>=0) { // there are cached stylesheets to that 'file_spec' - Stylesheet_connection *result=static_cast(connections->pop()); + if(connection_cache_type::value_type connections=connection_cache.get(file_spec)) + while(!connections->is_empty()) { // there are cached stylesheets to that 'file_spec' + Stylesheet_connection* result=connections->pop(); if(result->connected()) // not expired? return result; } @@ -104,70 +76,58 @@ Stylesheet_connection *Stylesheet_manage return 0; } -void Stylesheet_manager::put_connection_to_cache(const String& file_spec, - Stylesheet_connection& connection) { +void Stylesheet_manager::put_connection_to_cache(String::Body file_spec, Stylesheet_connection& connection) { SYNCHRONIZED; - Stack *connections=static_cast(connection_cache.get(file_spec)); + connection_cache_type::value_type connections=connection_cache.get(file_spec); if(!connections) { // there are no cached stylesheets to that 'file_spec' yet? - connections=NEW Stack(pool()); // NOTE: never freed up! + connections=new connection_cache_value_type; connection_cache.put(file_spec, connections); } connections->push(&connection); } -void Stylesheet_manager::maybe_expire_connection_cache() { +void Stylesheet_manager::maybe_expire_cache() { time_t now=time(0); if(prev_expiration_pass_time(now-EXPIRE_UNUSED_CONNECTION_SECONDS)); + connection_cache.for_each(expire_connections, now-EXPIRE_UNUSED_CONNECTION_SECONDS); prev_expiration_pass_time=now; } } -static void add_connection_to_status_cache_table(Array::Item *value, void *info) { - Stylesheet_connection& connection=*static_cast(value); - Table& table=*static_cast(info); - +static void add_connection_to_status_cache_table(Stylesheet_connection& connection, Table* table) { if(connection.connected()) { - Pool& pool=table.pool(); - Array& row=*new(pool) Array(pool, 3); + ArrayString& row=*new ArrayString; - row+=&connection.file_spec(); - time_t time_stamp=connection.get_time_used(); - const char *unsafe_time_cstr=ctime(&time_stamp); - int time_buf_size=strlen(unsafe_time_cstr); - char *safe_time_buf=(char *)pool.malloc(time_buf_size); - memcpy(safe_time_buf, unsafe_time_cstr, time_buf_size); - row+=new(pool) String(pool, safe_time_buf, time_buf_size); + // file + row+=new String(connection.file_spec(), String::L_AS_IS); + // time + time_t time_used=connection.get_time_used(); + row+=new String(pa_strdup(ctime(&time_used))); - table+=&row; + *table+=&row; } } -static void add_connections_to_status_cache_table(const Hash::Key& key, Hash::Val *value, void *info) { - Stack& stack=*static_cast(value); - Array_iter iter(stack); - for(int countdown=stack.top_index(); countdown-->=0; ) - add_connection_to_status_cache_table(iter.next(), info); +static void add_connections_to_status_cache_table(Stylesheet_manager::connection_cache_type::key_type /*key*/, Stylesheet_manager::connection_cache_type::value_type stack, Table* table) { + for(Array_iterator i(*stack); i; ) + add_connection_to_status_cache_table(*i.next(), table); } -Value& Stylesheet_manager::get_status(Pool& pool, const String *source) { - VHash& result=*new(pool) VHash(pool); - +Value* Stylesheet_manager::get_status() { + VHash* result=new VHash; // cache { - Array& columns=*new(pool) Array(pool, 3); - columns+=new(pool) String(pool, "file"); - columns+=new(pool) String(pool, "time"); - Table& table=*new(pool) Table(pool, 0, &columns, connection_cache.size()); + ArrayString& columns=*new ArrayString; + columns+=new String("file"); + columns+=new String("time"); + Table& table=*new Table(&columns, connection_cache.count()); - connection_cache.for_each(add_connections_to_status_cache_table, &table); + connection_cache.for_each(add_connections_to_status_cache_table, &table); - result.hash(source).put(*new(pool) String(pool, "cache"), new(pool) VTable(pool, &table)); + result->get_hash()->put(*new String("cache"), new VTable(&table)); } - return result; }