You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2006/09/17 23:26:56 UTC
svn commit: r447148 -
/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
Author: jukka
Date: Sun Sep 17 14:26:55 2006
New Revision: 447148
URL: http://svn.apache.org/viewvc?view=rev&rev=447148
Log:
JCR-446: Use a read-write lock to prevent logins during shutdown (and vice versa)
Modified:
jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?view=diff&rev=447148&r1=447147&r2=447148
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Sun Sep 17 14:26:55 2006
@@ -19,6 +19,8 @@
import EDU.oswego.cs.dl.util.concurrent.Mutex;
import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
+
import org.apache.commons.collections.map.ReferenceMap;
import org.apache.jackrabbit.api.JackrabbitRepository;
import org.apache.jackrabbit.core.config.FileSystemConfig;
@@ -182,6 +184,17 @@
private FileLock repLock;
/**
+ * Shutdown lock for guaranteeing that no new sessions are started during
+ * repository shutdown and that a repository shutdown is not initiated
+ * during a login. Each session login acquires a read lock while the
+ * repository shutdown requires a write lock. This guarantees that there
+ * can be multiple concurrent logins when the repository is not shutting
+ * down, but that only a single shutdown and no concurrent logins can
+ * happen simultaneously.
+ */
+ private final ReadWriteLock shutdownLock = new WriterPreferenceReadWriteLock();
+
+ /**
* private constructor
*
* @param repConfig
@@ -847,16 +860,34 @@
}
//-------------------------------------------------< JackrabbitRepository >
+
/**
- * Shuts down this repository.
+ * Shuts down this repository. The shutdown is guarded by a shutdown lock
+ * that prevents any new sessions from being started simultaneously.
*/
- public synchronized void shutdown() {
- // check status of this instance
- if (disposed) {
- // there's nothing to do here because the repository has already been shut down
- return;
+ public void shutdown() {
+ try {
+ shutdownLock.writeLock().acquire();
+ } catch (InterruptedException e) {
+ // TODO: Should this be a checked exception?
+ throw new RuntimeException("Shutdown lock could not be acquired", e);
}
+ try {
+ // check status of this instance
+ if (!disposed) {
+ doShutdown();
+ }
+ } finally {
+ shutdownLock.writeLock().release();
+ }
+ }
+
+ /**
+ * Private method that performs the actual shutdown after the shutdown
+ * lock has been acquired by the {@link #shutdown()} method.
+ */
+ private synchronized void doShutdown() {
log.info("Shutting down repository...");
// close active user sessions
@@ -1071,18 +1102,24 @@
*/
public Session login(Credentials credentials, String workspaceName)
throws LoginException, NoSuchWorkspaceException, RepositoryException {
- // check sanity of this instance
- sanityCheck();
-
- if (workspaceName == null) {
- workspaceName = repConfig.getDefaultWorkspaceName();
+ try {
+ shutdownLock.readLock().acquire();
+ } catch (InterruptedException e) {
+ throw new RepositoryException("Login lock could not be acquired", e);
}
- // check if workspace exists (will throw NoSuchWorkspaceException if not)
- getWorkspaceInfo(workspaceName);
+ try {
+ // check sanity of this instance
+ sanityCheck();
- if (credentials == null) {
- try {
+ if (workspaceName == null) {
+ workspaceName = repConfig.getDefaultWorkspaceName();
+ }
+
+ // check if workspace exists (will throw NoSuchWorkspaceException if not)
+ getWorkspaceInfo(workspaceName);
+
+ if (credentials == null) {
// null credentials, obtain the identity of the already-authenticated
// subject from access control context
AccessControlContext acc = AccessController.getContext();
@@ -1090,18 +1127,9 @@
if (subject != null) {
return createSession(subject, workspaceName);
}
- } catch (SecurityException se) {
- throw new LoginException(
- "Unable to access authentication information", se);
- } catch (AccessDeniedException ade) {
- // authenticated subject is not authorized for the specified workspace
- throw new LoginException("Workspace access denied", ade);
}
- }
-
- // login either using JAAS or our own LoginModule
- AuthContext authCtx;
- try {
+ // login either using JAAS or our own LoginModule
+ AuthContext authCtx;
LoginModuleConfig lmc = repConfig.getLoginModuleConfig();
if (lmc == null) {
authCtx = new AuthContext.JAAS(repConfig.getAppName(), credentials);
@@ -1110,16 +1138,19 @@
lmc.getLoginModule(), lmc.getParameters(), credentials);
}
authCtx.login();
- } catch (javax.security.auth.login.LoginException le) {
- throw new LoginException(le.getMessage(), le);
- }
- // create session
- try {
+ // create session
return createSession(authCtx, workspaceName);
+ } catch (SecurityException se) {
+ throw new LoginException(
+ "Unable to access authentication information", se);
+ } catch (javax.security.auth.login.LoginException le) {
+ throw new LoginException(le.getMessage(), le);
} catch (AccessDeniedException ade) {
// authenticated subject is not authorized for the specified workspace
- throw new LoginException(ade.getMessage());
+ throw new LoginException("Workspace access denied", ade);
+ } finally {
+ shutdownLock.readLock().release();
}
}