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

com.caucho.util.Exit Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2012 Caucho Technology -- all rights reserved
 *
 * This file is part of Resin(R) Open Source
 *
 * Each copy or derived work must preserve the copyright notice and this
 * notice unmodified.
 *
 * Resin Open Source is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Resin Open Source is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
 * of NON-INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Resin Open Source; if not, write to the
 *   Free SoftwareFoundation, Inc.
 *   59 Temple Place, Suite 330
 *   Boston, MA 02111-1307  USA
 *
 * @author Scott Ferguson
 */

package com.caucho.util;

import java.util.ArrayList;

/**
 * The exit class is used to automatically clean state.  For example,
 * Resin JavaScript will close open files when the script exits.
 *
 * Here's a sample use:
 * 
 *   boolean isExit = addExit();
 *   try {
 *     ...
 *   } finally {
 *     if (isExit)
 *       exit();
 *   }
 * 
* *

Objects register for the exit callback by calling * addExit(listener, object). * *

Exits are intrinsically tied to a thread. */ public class Exit { static private ThreadLocal _waiting = new ThreadLocal(); private Exit() {} /** * Registers the object and listener. The listener will be called when * the thread exits the scope. * *

If there is no protection scope, i.e. addExit() hasn't been called, * then this function does nothing. * * @param listener the exit handler * @param object the object which needs cleanup */ static public void addExit(ExitListener listener, Object object) { Queue queue = _waiting.get(); if (queue != null) queue.add(listener, object); } /** * Starts a protection scope. Only the outermost scope is important, so * protecting routines must check the return value to see if they are the * outermost scope. * * @return true if this is the outermost scope. */ static public boolean addExit() { Queue queue = _waiting.get(); if (queue == null) { queue = Queue.allocate(); _waiting.set(queue); return true; } else return false; } /** * Calls all registered listeners. */ static public void exit() { Queue queue = null; queue = _waiting.get(); _waiting.set(null); if (queue == null) return; int size = queue._listeners.size(); for (int i = 0; i < size; i++) { ExitListener listener = queue._listeners.get(i); Object object = queue._objects.get(i); if (listener != null) { try { listener.handleExit(object); } catch (Exception e) { } } } queue.free(); } private static class Queue { static Queue _freeList; Queue _next; ArrayList _listeners = new ArrayList(); ArrayList _objects = new ArrayList(); private Queue() { } void add(ExitListener listener, Object object) { _listeners.add(listener); _objects.add(object); } static Queue allocate() { if (_freeList == null) return new Queue(); Queue queue = _freeList; _freeList = _freeList._next; return queue; } void free() { _listeners.clear(); _objects.clear(); _next = _freeList; _freeList = this; } } }