Roxen.git / server / base_server / configuration.pike

version» Context lines:

Roxen.git/server/base_server/configuration.pike:1:   // This file is part of Roxen WebServer.   // Copyright © 1996 - 2001, Roxen IS.   //      // @appears Configuration   //! A site's main configuration    - constant cvs_version = "$Id: configuration.pike,v 1.574 2004/05/14 16:36:01 grubba Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.575 2004/05/14 18:09:05 grubba Exp $";   #include <module.h>   #include <module_constants.h>   #include <roxen.h>   #include <request_trace.h>   #include <timers.h>      #define CATCH(P,X) do{mixed e;if(e=catch{X;})report_error("While "+P+"\n"+describe_backtrace(e));}while(0)      // --- Locale defines ---   //<locale-token project="roxen_start"> LOC_S </locale-token>
Roxen.git/server/base_server/configuration.pike:1404:    else    if (check_above && (lock_info & 1))    // Convert LOCK_*_AT to LOCK_*_BELOW.    lock_info &= ~1;    if (lock_info > state) state = lock_info;    if (state == LOCK_EXCL_AT) return LOCK_EXCL_AT; // Doesn't get any worse.    }    return state;   }    + static multiset(DAVLock) active_locks = (<>); +    //! Unlock the lock represented by @[lock] on @[path].   //!   //! @returns   //! Returns a result-mapping on error, and @expr{0@} (zero) on success.   mapping(string:mixed) unlock_file(string path, DAVLock lock, RequestID id)   {    // Canonicalize path.    if (!has_suffix(path, "/")) path+="/";       foreach(location_module_cache||location_modules(),
Roxen.git/server/base_server/configuration.pike:1432:    if (ret) return ret;    } else if (lock->recursive && has_prefix(loc, path)) {    // loc == path + ignored.    mapping(string:mixed) ret =    function_object(func)->unlock_file("/", lock, id);       // FIXME: Semantics for partial unlocking?    if (ret) return ret;    }    } +  active_locks[lock] = 0;    // destruct(lock);    return 0;   }    -  + //! Force expiration of any locks that have timed out. + int expire_locks(RequestID id) + { +  int t = time(1); +  int min_time = 0x7fffffff; +  foreach(active_locks; DAVLock lock;) { +  if (lock->expiry_time) { +  if (lock->expiry_time < t) { +  unlock_file(lock->path, lock, id); +  } else if (lock->expiry_time < min_time) { +  min_time = lock->expiry_time; +  } +  } +  } +  return min_time - t; + } +  + static void expire_lock_loop() + { +  int t = expire_locks(0); // NOTE: Called with RequestID 0! +  +  if (sizeof(active_locks)) { +  // Expire locks at least once every hour. +  if (t < 3600) { +  roxen.background_run(t, expire_lock_loop); +  } else { +  roxen.background_run(3600, expire_lock_loop); +  } +  } + } +  + //! Refresh a lock. + //! + //! Update the expiry time for the lock. + void refresh_lock(DAVLock lock) + { +  if (lock->expiry_delta) { +  lock->expiry_time = lock->expiry_delta + time(1); +  } + } +    //! Attempt to lock @[path].   //!   //! @param path   //! Path to lock.   //!   //! @param locktype   //! Type of lock (currently only @expr{"DAV:write"@} is defined).   //!   //! @param lockscope   //! Scope of lock either @expr{"DAV:exclusive"@} or
Roxen.git/server/base_server/configuration.pike:1504:    // path == loc + subpath.    subpath = path[sizeof(loc)..];    } else if (recursive && has_prefix(loc, path)) {    // loc == path + ignored.    subpath = "/";    } else {    // Does not apply to this location module.    continue;    }    -  mapping(string:mixed)|DAVLock new_lock = +  mapping(string:mixed) lock_error =    function_object(func)->lock_file(subpath, lock, id); -  if (mappingp(new_lock)) { +  if (lock_error) {    // Failure. Unlock the new lock.    foreach(location_module_cache||location_modules(),    [string loc2, function func2])    {    if (has_prefix(path, loc2)) {    // path == loc2 + subpath.    mapping(string:mixed) ret =    function_object(func2)->unlock_file(path[sizeof(loc2)..],    lock, id);    } else if (recursive && has_prefix(loc2, path)) {    // loc2 == path + ignored.    mapping(string:mixed) ret =    function_object(func2)->unlock_file("/", lock, id);    }    if (func == func2) break;    }    // destruct(lock); -  return new_lock; +  return lock_error;    }    }    -  // FIXME: Timeout handling? +  if (expiry_delta) { +  // Lock with timeout. +  // FIXME: Race-conditions. +  if (!sizeof(active_locks)) { +  // Start the lock expiration loop. +  active_locks[lock] = 1; +  expire_lock_loop(); +  } else { +  active_locks[lock] = 1; +  } +  }       // Success.    return lock;   }      mapping|int(-1..0) low_get_file(RequestID id, int|void no_magic)   //! The function that actually tries to find the data requested. All   //! modules except last and filter type modules are mapped, in order,   //! and the first one that returns a suitable response is used. If   //! `no_magic' is set to one, the internal magic roxen images and the