|
|
| version 1.16.2.1, 2003/01/31 12:34:38 | version 1.16.2.6, 2003/03/06 15:32:37 |
|---|---|
| Line 20 static const char* IDENT_STYLESHEET_MANA | Line 20 static const char* IDENT_STYLESHEET_MANA |
| // globals | // globals |
| Stylesheet_manager *stylesheet_manager; | Stylesheet_manager stylesheet_manager; |
| // consts | // consts |
| const int EXPIRE_UNUSED_CONNECTION_SECONDS=5*60; | const time_t SECOND=1; |
| 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 | // helpers |
| static void expire_connection(Array::Item *value, void *info) { | static void expire_connection(Stylesheet_connection& connection, time_t older_dies) { |
| Stylesheet_connection& connection=*static_cast<Stylesheet_connection *>(value); | |
| time_t older_dies=reinterpret_cast<time_t>(info); | |
| if(connection.connected() && connection.expired(older_dies)) | if(connection.connected() && connection.expired(older_dies)) |
| connection.disconnect(); | connection.disconnect(); |
| } | } |
| static void expire_connections(const Hash::Key& key, Hash::Val *value, void *info) { | static void expire_connections( |
| Stack& stack=*static_cast<Stack *>(value); | Stylesheet_manager::connection_cache_type::key_type /*key*/, |
| for(int i=0; i<=stack.top_index(); i++) | Stylesheet_manager::connection_cache_type::value_type stack, |
| expire_connection(stack.get(i), info); | time_t older_dies) { |
| for(int i=0; i<=stack->top_index(); i++) | |
| expire_connection(*stack->get(i), older_dies); | |
| } | } |
| // Stylesheet_manager | // Stylesheet_manager |
| Stylesheet_manager::Stylesheet_manager(Pool& apool) : Cache_manager(apool), | Stylesheet_manager::Stylesheet_manager(): prev_expiration_pass_time(0) {} |
| connection_cache(apool), | |
| prev_expiration_pass_time(0) { | |
| } | |
| Stylesheet_manager::~Stylesheet_manager() { | Stylesheet_manager::~Stylesheet_manager() { |
| connection_cache.for_each(expire_connections, | connection_cache.for_each(expire_connections, time(0)+SECOND/*=in future=expire all*/); |
| reinterpret_cast<void *>(time(0)+1/*=in future=expire all*/)); | |
| } | } |
| Stylesheet_connection_ptr Stylesheet_manager::get_connection(const String& request_file_spec) { | Stylesheet_connectionPtr Stylesheet_manager::get_connection(StringPtr file_spec) { |
| Pool& pool=request_file_spec.pool(); // request pool | Stylesheet_connectionPtr result=get_connection_from_cache(file_spec); |
| if(!result) | |
| // first trying to get cached stylesheet | result=Stylesheet_connectionPtr(new Stylesheet_connection(file_spec)); |
| Stylesheet_connection *connection=get_connection_from_cache(request_file_spec); | return result; |
| if(!connection) { | |
| // 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); | |
| connection=new(this->pool()) Stylesheet_connection(this->pool(), global_file_spec); | |
| } | |
| // associate with services[request] (deassociates at close) | |
| connection->set_services(&pool); | |
| // return autoclosing object for it | |
| return Stylesheet_connection_ptr(connection); | |
| } | } |
| void Stylesheet_manager::close_connection(const String& file_spec, | void Stylesheet_manager::close_connection(StringPtr file_spec, |
| Stylesheet_connection& connection) { | Stylesheet_connection& connection) { |
| // deassociate from services[request] | put_connection_to_cache(file_spec, Stylesheet_connectionPtr(&connection)); |
| connection.set_services(0); | |
| put_connection_to_cache(file_spec, connection); | |
| } | } |
| // stylesheet cache | // stylesheet cache |
| /// @todo get rid of memory spending Stack [zeros deep inside got accumulated] | /// @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_connectionPtr Stylesheet_manager::get_connection_from_cache(StringPtr file_spec) { |
| SYNCHRONIZED; | SYNCHRONIZED; |
| if(Stack *connections=static_cast<Stack *>(connection_cache.get(file_spec))) | if(connection_cache_type::value_type connections=connection_cache.get(file_spec)) |
| while(connections->top_index()>=0) { // there are cached stylesheets to that 'file_spec' | while(connections->top_index()>=0) { // there are cached stylesheets to that 'file_spec' |
| Stylesheet_connection *result=static_cast<Stylesheet_connection *>(connections->pop()); | Stylesheet_connectionPtr result=connections->pop(); |
| if(result->connected()) // not expired? | if(result->connected()) // not expired? |
| return result; | return result; |
| } | } |
| return 0; | return Stylesheet_connectionPtr(0); |
| } | } |
| void Stylesheet_manager::put_connection_to_cache(const String& file_spec, | void Stylesheet_manager::put_connection_to_cache(StringPtr file_spec, |
| Stylesheet_connection& connection) { | Stylesheet_connectionPtr connection) { |
| SYNCHRONIZED; | SYNCHRONIZED; |
| Stack *connections=static_cast<Stack *>(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? | if(!connections) { // there are no cached stylesheets to that 'file_spec' yet? |
| connections=NEW Stack(pool()); // NOTE: never freed up! | connections=connection_cache_type::value_type(new connection_cache_type::value_type::element_type); |
| connection_cache.put(file_spec, connections); | connection_cache.put(file_spec, connections); |
| } | } |
| connections->push(&connection); | connections->push(connection); |
| } | } |
| void Stylesheet_manager::maybe_expire_cache() { | void Stylesheet_manager::maybe_expire_cache() { |
| time_t now=time(0); | time_t now=time(0); |
| if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) { | if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) { |
| connection_cache.for_each(expire_connections, | connection_cache.for_each(expire_connections, now-EXPIRE_UNUSED_CONNECTION_SECONDS); |
| reinterpret_cast<void *>(now-EXPIRE_UNUSED_CONNECTION_SECONDS)); | |
| prev_expiration_pass_time=now; | prev_expiration_pass_time=now; |
| } | } |
| } | } |
| /* | |
| static void add_connection_to_status_cache_table(Array::Item *value, void *info) { | static void add_connection_to_status_cache_table(Array::Item *value, void *info) { |
| Stylesheet_connection& connection=*static_cast<Stylesheet_connection *>(value); | Stylesheet_connection& connection=*static_cast<Stylesheet_connection *>(value); |
| Table& table=*static_cast<Table *>(info); | Table& table=*static_cast<Table *>(info); |
| Line 134 static void add_connection_to_status_cac | Line 110 static void add_connection_to_status_cac |
| row+=&connection.file_spec(); | row+=&connection.file_spec(); |
| // time | // time |
| time_t time_stamp=connection.get_time_used(); | time_t time_stamp=connection.get_time_used(); |
| const char* unsafe_time_cstr=ctime(&time_stamp); | row+=new(pool) String(pool, pool.copy(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); | |
| table+=&row; | table+=&row; |
| } | } |
| Line 149 static void add_connections_to_status_ca | Line 121 static void add_connections_to_status_ca |
| for(int countdown=stack.top_index(); countdown-->=0; ) | for(int countdown=stack.top_index(); countdown-->=0; ) |
| add_connection_to_status_cache_table(iter.next(), info); | add_connection_to_status_cache_table(iter.next(), info); |
| } | } |
| Value& Stylesheet_manager::get_status(Pool& pool, const String *source) { | */ |
| VHash& result=*new(pool) VHash(pool); | ValuePtr Stylesheet_manager::get_status(Pool& pool, StringPtr source) { |
| VHashPtr result(new VHash); | |
| /* | |
| // cache | // cache |
| { | { |
| Array& columns=*new(pool) Array(pool); | Array& columns=*new(pool) Array(pool); |
| Line 163 Value& Stylesheet_manager::get_status(Po | Line 136 Value& Stylesheet_manager::get_status(Po |
| result.hash(source).put(*new(pool) String(pool, "cache"), new(pool) VTable(pool, &table)); | result.hash(source).put(*new(pool) String(pool, "cache"), new(pool) VTable(pool, &table)); |
| } | } |
| */ | |
| return result; | return result; |
| } | } |