All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sunlabs.brazil.sunlabs.LockTemplate Maven / Gradle / Ivy

The newest version!
/*
 * LockTemplate.java
 *
 * Brazil project web application toolkit,
 * export version: 2.3 
 * Copyright (c) 2006 Sun Microsystems, Inc.
 *
 * Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License Version 
 * 1.0 (the "License"). You may not use this file except in compliance with 
 * the License. A copy of the License is included as the file "license.terms",
 * and also available at http://www.sun.com/
 * 
 * The Original Code is from:
 *    Brazil project web application toolkit release 2.3.
 * The Initial Developer of the Original Code is: suhler.
 * Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s): suhler.
 *
 * Version:  1.1
 * Created by suhler on 06/08/07
 * Last modified by suhler on 06/08/07 16:24:29
 *
 * Version Histories:
 *
 * 1.2 06/08/07-16:24:30 (Codemgr)
 *   SunPro Code Manager data about conflicts, renames, etc...
 *   Name history : 1 0 sunlabs/LockTemplate.java
 *
 * 1.1 06/08/07-16:24:29 (suhler)
 *   date and time created 06/08/07 16:24:29 by suhler
 *
 */

package sunlabs.brazil.sunlabs;

import sunlabs.brazil.template.RewriteContext;
import sunlabs.brazil.template.Template;
import sunlabs.brazil.server.Server;
import java.util.Hashtable;

/**
 * Template to lock a resource.
 * <lock name=xxx> ... </lock>
 * Claim exclusive access to the lock named "xxx".
 * Locks are used to serialize access to sections of markup, thus
 * insuring the integrity of data structures.  Traditionally, this was
 * done by managing sessions: since only one template may be active per
 * session, forcing all access to serialized regions into the same session
 * has the desired effect.  However, since sessions are typically managed on
 * a per URL basis, each serialized piece of markup needs to be in its own
 * URL, and a pair of SimpleSessionHandler/UrlMapperHandler needs to be
 * configured for each named serialized region.
 * 

* Only one lock may be held at a time. The current lock (if any) is * automatically released at the end of the template. Care should * be taken not to acquire a lock then invoke a blocking operation * (such as with the QueueTemplate) or deadlock may occur. *

* Example: *

 * <lock name="server">
 *   <set namespace="server" name=.....>
 *   ...
 *   <set namespace="server" name=.....>
 * </lock>
 * 
* This insures that no other session may access the code protected * by the "server" lock, either from this or any other template. * * @author Stephen Uhler * @version @(#)LockTemplate.java 1.1 */ public class LockTemplate extends Template { /** * Acquire a lock, preventing any other session from accessing * the same locked section of markup. */ public void tag_lock(RewriteContext hr) { debug(hr); hr.killToken(); String name = hr.get("name"); if (name == null) { debug(hr, "Missing name attribute"); return; } boolean waited = Lock.getLock(name, hr.request); debug(hr,"waited=" + waited); } /** * Release the previosly named lock. */ public void tag_slash_lock(RewriteContext hr) { debug(hr); hr.killToken(); Lock.unlock(hr.request); } /* * Make sure my lock (if any) is released. */ public boolean done(RewriteContext hr) { Lock.unlock(hr.request); return super.done(hr); } } /** * Manage a lock on an object. */ class Lock { /* * Global table of locks. Each lock has 2 entries, one keyed on the * string name and one keyed on the object holding * the lock. */ static Hashtable locks = new Hashtable(); // global table of locks String name; // name of the lock Object owner; // object to syncronize on private Lock(String name, Object owner) { this.name = name; // string name for the lock this.owner = owner; // the object to lock } /** * Wait for the lock holder to notify us. */ void dowait() { synchronized (owner) { try { owner.wait(); } catch (InterruptedException e) { System.out.println("wait interrupted: " + this); } } } /** * Get a lock, waiting if already un use. * Release any locks I already own first. * @param name The name for this lock * @param me The (Request) object to lock */ static boolean getLock(String name, Object me) { boolean haveWaited = false; unlock(me); Lock lock; synchronized (locks) { lock = (Lock) locks.get(name); if (lock == null) { lock = new Lock(name, me); locks.put(name, lock); locks.put(me, lock); return haveWaited; } } synchronized (lock) { while(lock.owner != null) { lock.dowait(); haveWaited = true; } lock.owner=me; locks.put(name, lock); locks.put(me, lock); } return haveWaited; } /** * Return my lock (if any) */ public static void unlock(Object me) { Object gone = null; synchronized (locks) { Lock lock = (Lock) locks.get(me); if (lock != null) { locks.remove(me); locks.remove(lock.name); gone = lock.owner; lock.owner=null; } } if (gone != null) { synchronized (gone) { gone.notifyAll(); } } } public String toString() { return "lock(" + name + "," + owner + ")"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy