Diff for /parser3/src/classes/op.C between versions 1.167 and 1.172

version 1.167, 2007/05/23 08:30:20 version 1.172, 2007/08/20 10:37:21
Line 243  static void _while(Request& r, MethodPar Line 243  static void _while(Request& r, MethodPar
         Temp_hash_value<const String::Body, void*>           Temp_hash_value<const String::Body, void*> 
                 cycle_data_setter(r.classes_conf, cycle_data_name, /*any not null flag*/&r);                  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& body_code=params.as_junction(1, "body must be code");
         Value* delim_maybe_code=params.count()>2?&params[2]:0;          Value* delim_maybe_code=params.count()>2?&params[2]:0;
   
Line 277  static void _while(Request& r, MethodPar Line 278  static void _while(Request& r, MethodPar
 }  }
   
 static void _use(Request& r, MethodParams& params) {  static void _use(Request& r, MethodParams& params) {
         Value& vfile=params.as_no_junction(0, "file name must not be code");          Value& vfile=params.as_no_junction(0, FILE_NAME_MUST_NOT_BE_CODE);
         r.use_file(r.main_class, vfile.as_string());          r.use_file(r.main_class, vfile.as_string());
 }  }
   
Line 610  const String* locked_process_and_cache_p Line 611  const String* locked_process_and_cache_p
   
         const String* result=file_write_action_under_lock(          const String* result=file_write_action_under_lock(
                 file_spec,                   file_spec, 
                 "cache_put", locked_process_and_cache_put_action, &info,                  "cache_put",
                   locked_process_and_cache_put_action,
                   &info,
                 false/*as_text*/,                  false/*as_text*/,
                 false/*do_append*/,                  false/*do_append*/,
                 false/*block*/,                  false/*block == don't wait till other thread release lock*/) ? info.processed_code: 0;
                 false/*fail on lock problem*/) ? info.processed_code: 0;  
         time_t now=time(0);          time_t now=time(0);
         if(scope.expires<=now)          if(scope.expires<=now)
                 cache_delete(file_spec);                  cache_delete(file_spec);
Line 705  static void _cache(Request& r, MethodPar Line 708  static void _cache(Request& r, MethodPar
                         "invalid number of parameters");                           "invalid number of parameters"); 
                   
         // file_spec, expires, body code          // file_spec, expires, body code
         const String& file_spec=r.absolute(params.as_string(0, "filespec must be string"));          const String& file_spec=as_file_spec(r, params, 0);
   
         Cache_scope scope={as_expires(r, params, 1, now), 0};          Cache_scope scope={as_expires(r, params, 1, now), 0};
   
Line 716  static void _cache(Request& r, MethodPar Line 719  static void _cache(Request& r, MethodPar
         if(params.count()>3)          if(params.count()>3)
                 catch_code=&params.as_junction(3, "catch_code must be code");                  catch_code=&params.as_junction(3, "catch_code must be code");
   
         if(scope.expires>now) { // valid 'expires' specified? try cached copy...          if(scope.expires>now) {
                 // hence we don't hope to have unary create/lockEX                  Cache_get_result cached=cache_get(r.charsets, file_spec, now);
                 // 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;  
                         }  
                         }  
   
                 // non-blocked lock; process; cache it                  if(cached.body) { // have cached copy
                 if(const String* processed_body=                  if(cached.expired) {
                         locked_process_and_cache_put(r, body_code, catch_code, scope, file_spec)) {                          scope.body_from_disk=cached.body; // storing for user to retrive it with ^cache[]
                         // write it out                   } else {
                         r.write_assign_lang(*processed_body);                          // and it's not expired yet write it out 
                         // happy with it                                  r.write_assign_lang(*cached.body);
                         return;                                  // happy with it
                 } else { // somebody writing result right now                                  return;
                         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,                  // no cached info or it's already expired
                         "locking problem");                  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 {           } else { 
                 // instructed not to cache; forget cached copy                  // instructed not to cache; forget cached copy
                 cache_delete(file_spec);                  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) {  static StringOrValue process_try_body_code(Request& r, Value* body_code) {

Removed from v.1.167  
changed lines
  Added in v.1.172


E-mail: