Package org.apache.felix.useradmin.filestore

Source Code of org.apache.felix.useradmin.filestore.ResettableTimer

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package org.apache.felix.useradmin.filestore;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
* Provides a timer that can be reset.
*/
final class ResettableTimer {
    private final ScheduledExecutorService m_executor;
    private final Runnable m_task;
    private final long m_timeout;
    private final TimeUnit m_timeUnit;
    private final AtomicReference m_futureRef;
   
    /**
     * Creates a new {@link ResettableTimer} calling a given task when a given
     * timeout exceeds.
     *
     * @param task the task to execute upon timout, cannot be <code>null</code>;
     * @param timeout the timeout value, > 0;
     * @param unit the time unit of the timeout value, cannot be <code>null</code>.
     */
    public ResettableTimer(Runnable task, long timeout, TimeUnit unit) {
        this(new ScheduledThreadPoolExecutor(1), task, timeout, unit);
    }
   
    /**
     * Creates a new {@link ResettableTimer} calling a given task when a given
     * timeout exceeds.
     *
     * @param executor the executor to use to execute the task, cannot be <code>null</code>;
     * @param task the task to execute upon timout, cannot be <code>null</code>;
     * @param timeout the timeout value, > 0;
     * @param unit the time unit of the timeout value, cannot be <code>null</code>.
     */
    public ResettableTimer(ScheduledExecutorService executor, Runnable task, long timeout, TimeUnit unit) {
        if (executor == null) {
            throw new IllegalArgumentException("Executor cannot be null!");
        }
        if (task == null) {
            throw new IllegalArgumentException("Task cannot be null!");
        }
        if (timeout <= 0) {
            throw new IllegalArgumentException("Timeout cannot be negative!");
        }
        if (unit == null) {
            throw new IllegalArgumentException("TimeUnit cannot be null!");
        }
       
        m_executor = executor;
        m_task = task;
        m_timeout = timeout;
        m_timeUnit = unit;
       
        m_futureRef = new AtomicReference();
    }

    /**
     * Returns the state of this timer.
     *
     * @return <code>true</code> if this timer is shut down, <code>false</code> otherwise.
     */
    public boolean isShutDown() {
        return m_executor.isShutdown();
    }
   
    /**
     * Schedules the task for execution with the contained timeout. If a task
     * is already pending or running, it will be cancelled (not interrupted).
     * The new task will be scheduled to run in now + timeout.
     */
    public ScheduledFuture schedule() {
        ScheduledFuture currentTask = cancelCurrentTask();
        ScheduledFuture newTask = m_executor.schedule(m_task, m_timeout, m_timeUnit);
        m_futureRef.compareAndSet(currentTask, newTask);
        return newTask;
    }
   
    /**
     * Shuts down this timer, allowing any pending tasks to execute. After this
     * method is called, {@link #schedule()} may no longer be called.
     */
    public void shutDown() {
        m_executor.shutdown();
        try {
            m_executor.awaitTermination(2 * m_timeout, m_timeUnit);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * @return the current task, or <code>null</code> if no task is available.
     */
    private ScheduledFuture cancelCurrentTask() {
        ScheduledFuture currentTask = (ScheduledFuture) m_futureRef.get();
        if (currentTask != null) {
            // Doesn't matter for completed tasks...
            currentTask.cancel(false /* mayInterruptIfRunning */);
        }
        return currentTask;
    }
}
TOP

Related Classes of org.apache.felix.useradmin.filestore.ResettableTimer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.