/*
* Copyright 2007 Glencoe Software, Inc. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.services.sessions;
import java.util.List;
import ome.model.meta.Session;
import ome.services.sessions.state.SessionCache;
import ome.services.sessions.stats.SessionStats;
import ome.system.EventContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Extends {@link EventContext} to hold a {@link Session}. This is used by the
* {@link SessionManager} to store information in the {@link SessionCache}.
*
* @author Josh Moore, josh at glencoesoftware.com
* @since 3.0-Beta3
*/
public interface SessionContext extends EventContext {
Session getSession();
List<String> getUserRoles();
// Reference counting
/**
* The Share id is the only mutable bit in the {@link SessionContext}.
*/
void setShareId(Long shareId);
/**
* Return a {@link SessionStats} implementation for this session.
*/
SessionStats stats();
/**
* Returns the {@link Count} instance held by this context. This may be
* shared with other contexts, so that in critical phases as when the context
* is being copied, the reference count will be kept in sync.
*/
Count count();
/**
* Synchronized counter which can be passed between {@link SessionContext}
* instances as they are recreated.
*
* @see <a href="http://trac.openmicroscopy.org/ome/ticket/2804">ticket:2804</a>
*/
public class Count {
private final Logger log = LoggerFactory.getLogger(Count.class);
private final Object[] refLock = new Object[0];
private int ref;
private String uuid;
public Count(String uuid) {
this.uuid = uuid;
}
/**
* Return the current number of references which this session is aware of.
*/
public int get() {
synchronized (refLock) {
return ref;
}
}
/**
* Increment the current {@link #ref reference count} and return the
* new value atomically.
*/
public int increment() {
synchronized (refLock) {
if (ref < 0) {
ref = 1;
} else {
// This should never happen, but just in case
// some loop is incrementing indefinitely.
if (ref < Integer.MAX_VALUE) {
ref = ref + 1;
if (log.isDebugEnabled()) {
log.debug("+Reference count: " + uuid + "=" + ref);
}
} else {
log.warn("Reference count == MAX_VALUE");
}
}
return ref;
}
}
/**
* Decrement the current {@link #ref reference count} and return the
* new value atomically.
*/
public int decrement() {
synchronized (refLock) {
if (ref < 1) {
ref = 0;
} else {
ref = ref - 1;
log.info("-Reference count: " + uuid + "=" + ref);
}
return ref;
}
}
}
}