Annotation of parser3/src/main/pa_xslt_stylesheet_manager.C, revision 1.4
1.1 parser 1: /** @file
2: Parser: sql driver manager implementation.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.4 ! parser 5: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
1.1 parser 6:
1.4 ! parser 7: $Id: $
1.1 parser 8: */
1.3 parser 9: #include "pa_config_includes.h"
10: #ifdef XML
1.1 parser 11:
12: #include "pa_xslt_stylesheet_manager.h"
13: #include "pa_stylesheet_connection.h"
14: #include "ltdl.h"
15: #include "pa_exception.h"
16: #include "pa_common.h"
17: #include "pa_threads.h"
18:
19: // globals
20:
21: XSLT_Stylesheet_manager *XSLT_stylesheet_manager;
22:
23: // consts
24:
1.2 parser 25: const int EXPIRE_UNUSED_CONNECTION_SECONDS=5*60;
1.1 parser 26: const int CHECK_EXPIRED_CONNECTION_SECONDS=EXPIRE_UNUSED_CONNECTION_SECONDS*2;
27:
28:
29: // XSLT_Stylesheet_manager
30:
31: Stylesheet_connection& XSLT_Stylesheet_manager::get_connection(const String& request_file_spec) {
32: Pool& pool=request_file_spec.pool(); // request pool
33:
34: // first trying to get cached stylesheet
35: Stylesheet_connection *result=get_connection_from_cache(request_file_spec);
36: if(!result) {
37: // then just construct it
38:
39: // make global_file_spec C-string on global pool
40: const char *request_file_spec_cstr=request_file_spec.cstr(String::UL_FILE_SPEC);
41: char *global_file_spec_cstr=(char *)malloc(strlen(request_file_spec_cstr)+1);
42: strcpy(global_file_spec_cstr, request_file_spec_cstr);
43: // make global_file_spec string on global pool
44: String& global_file_spec=*new(this->pool()) String(this->pool(), global_file_spec_cstr);
45:
46: result=new(this->pool()) Stylesheet_connection(this->pool(), global_file_spec);
47: }
48: // associate with services[request] (deassociates at close)
49: result->set_services(&pool);
50: // return it
51: return *result;
52: }
53:
54: void XSLT_Stylesheet_manager::close_connection(const String& file_spec,
55: Stylesheet_connection& connection) {
56: // deassociate from services[request]
57: connection.set_services(0);
58: put_connection_to_cache(file_spec, connection);
59: }
60:
61:
62: // stylesheet cache
63: /// @todo get rid of memory spending Stack [zeros deep inside got accumulated]
64: Stylesheet_connection *XSLT_Stylesheet_manager::get_connection_from_cache(const String& file_spec) {
65: SYNCHRONIZED;
66:
67: maybe_expire_connection_cache();
68:
69: if(Stack *connections=static_cast<Stack *>(connection_cache.get(file_spec)))
70: while(connections->top_index()>=0) { // there are cached stylesheets to that 'file_spec'
71: Stylesheet_connection *result=static_cast<Stylesheet_connection *>(connections->pop());
72: if(result->connected()) // not expired?
73: return result;
74: }
75:
76: return 0;
77: }
78:
79: void XSLT_Stylesheet_manager::put_connection_to_cache(const String& file_spec,
80: Stylesheet_connection& connection) {
81: SYNCHRONIZED;
82:
83: Stack *connections=static_cast<Stack *>(connection_cache.get(file_spec));
84: if(!connections) { // there are no cached stylesheets to that 'file_spec' yet?
85: connections=NEW Stack(pool()); // NOTE: never freed up!
86: connection_cache.put(file_spec, connections);
87: }
88: connections->push(&connection);
89: }
90:
91: static void expire_connection(Array::Item *value, void *info) {
92: Stylesheet_connection& connection=*static_cast<Stylesheet_connection *>(value);
93: time_t older_dies=reinterpret_cast<time_t>(info);
94:
95: if(connection.connected() && connection.expired(older_dies))
96: connection.disconnect();
97: }
98: static void expire_connections(const Hash::Key& key, Hash::Val *value, void *info) {
99: Stack& stack=*static_cast<Stack *>(value);
100: for(int i=0; i<=stack.top_index(); i++)
101: expire_connection(stack.get(i), info);
102: }
103: void XSLT_Stylesheet_manager::maybe_expire_connection_cache() {
104: time_t now=time(0);
105:
106: if(prev_expiration_pass_time<now-CHECK_EXPIRED_CONNECTION_SECONDS) {
107: connection_cache.for_each(expire_connections,
108: reinterpret_cast<void *>(now-EXPIRE_UNUSED_CONNECTION_SECONDS));
109:
110: prev_expiration_pass_time=now;
111: }
112: }
1.3 parser 113: #endif
E-mail: