--- parser3/src/classes/op.C 2007/04/23 10:30:09 1.166 +++ parser3/src/classes/op.C 2007/06/09 16:22:08 1.170 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_OP_C="$Date: 2007/04/23 10:30:09 $"; +static const char * const IDENT_OP_C="$Date: 2007/06/09 16:22:08 $"; #include "classes.h" #include "pa_vmethod_frame.h" @@ -243,7 +243,8 @@ static void _while(Request& r, MethodPar Temp_hash_value cycle_data_setter(r.classes_conf, cycle_data_name, /*any not null flag*/&r); - Value& vcondition=params.as_junction(0, "condition must be expression"); + Value& vcondition=params.as_expression(0, "condition must be number, bool or expression"); + Value& body_code=params.as_junction(1, "body must be code"); Value* delim_maybe_code=params.count()>2?¶ms[2]:0; @@ -535,7 +536,7 @@ struct Data_string_serialized_prolog { #endif void cache_delete(const String& file_spec) { - file_delete(file_spec, false/*fail_on_read_problem*/); + file_delete(file_spec, false/*fail_on_problem*/); } #ifndef DOXYGEN @@ -547,7 +548,8 @@ public: struct Locked_process_and_cache_put_action_info { Request *r; Cache_scope *scope; - Value* body_code; Value* catch_code; + Value* body_code; + Value* catch_code; const String* processed_code; }; #endif @@ -566,7 +568,6 @@ static void locked_process_and_cache_put Locked_process_and_cache_put_action_info& info= *static_cast(context); - const String* body_from_disk=info.scope->body_from_disk; // body->process Try_catch_result result=try_catch(*info.r, @@ -610,11 +611,13 @@ const String* locked_process_and_cache_p const String* result=file_write_action_under_lock( file_spec, - "cache_put", locked_process_and_cache_put_action, &info, + "cache_put", + locked_process_and_cache_put_action, + &info, false/*as_text*/, false/*do_append*/, - false/*block*/, - false/*fail on lock problem*/) ? info.processed_code: 0; + false/*block == don't wait till other thread release lock*/) ? info.processed_code: 0; + time_t now=time(0); if(scope.expires<=now) cache_delete(file_spec); @@ -716,63 +719,41 @@ static void _cache(Request& r, MethodPar if(params.count()>3) catch_code=¶ms.as_junction(3, "catch_code must be code"); - if(scope.expires>now) { // valid 'expires' specified? try cached copy... - // hence we don't hope to have unary create/lockEX - // we need some plan to live in a life like that, so... - // worst races plan: - // A B - // open - // |open - // lockSH - // |nonblocking-lockEX fails - // unlockSH - // close, cache_get returns 0 - // open - // nonblocking-lockEX succeeds; process, write, close - // |retry1: open - // ... - // |lockSH succeeds; ... - - for(int retry=0; retry<2; retry++) { - Cache_get_result cached=cache_get(r.charsets, file_spec, now); - if(cached.body) { // have cached copy - if(cached.expired) - scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[] - else // and it's not expired yet - { - // write it out - r.write_assign_lang(*cached.body); - // happy with it - return; - } - } + if(scope.expires>now) { + Cache_get_result cached=cache_get(r.charsets, file_spec, now); - // non-blocked lock; process; cache it - if(const String* processed_body= - locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec)) { - // write it out - r.write_assign_lang(*processed_body); - // happy with it - return; - } else { // somebody writing result right now - pa_sleep(0, 500000); // waiting half a second - retry=0; // prolonging our wait, than could cache_get it, without processing body_code - } - } - throw Exception(0, - &file_spec, - "locking problem"); + if(cached.body) { // have cached copy + if(cached.expired) { + scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[] + } else { + // and it's not expired yet write it out + r.write_assign_lang(*cached.body); + // happy with it + return; + } + } + + // no cached info or it's already expired + try { + // try to process and store in file + const String* processed_body=locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec); + // write it out + r.write_assign_lang(*processed_body); + // happy with it + return; + } catch(...) { + // we fail during get exclusive lock + // nvm we just process it a bit later + } } else { // instructed not to cache; forget cached copy cache_delete(file_spec); - // process - const String& processed_body=r.process_to_string(body_code); - // write it out - r.write_assign_lang(processed_body); - // happy with it - return; } - // never reached + + // process without cacheing + const String& processed_body=r.process_to_string(body_code); + // write it out + r.write_assign_lang(processed_body); } static StringOrValue process_try_body_code(Request& r, Value* body_code) {