| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.internal.helper; |
| |
| import java.util.*; |
| |
| /** |
| * INTERNAL: |
| * <p> |
| * <b>Purpose</b>: Be used for deadlock avoidance through allowing detection and resolution. |
| * |
| * <p> |
| * <b>Responsibilities</b>: |
| * <ul> |
| * <li> Keep track of all deferred locks of each thread. |
| * <li> Keep track of all active locks of each thread.. |
| * <li> Maintain the depth of the each thread. |
| * </ul> |
| */ |
| public class DeferredLockManager { |
| protected Vector<ConcurrencyManager> deferredLocks; |
| protected Vector<ConcurrencyManager> activeLocks; |
| protected int threadDepth; |
| protected boolean isThreadComplete; |
| |
| public static boolean SHOULD_USE_DEFERRED_LOCKS = true; |
| |
| /** |
| * DeferredLockManager constructor comment. |
| */ |
| public DeferredLockManager() { |
| super(); |
| this.deferredLocks = new Vector<>(1); |
| this.activeLocks = new Vector<>(1); |
| this.threadDepth = 0; |
| this.isThreadComplete = false; |
| } |
| |
| /** |
| * add a concurrency manager as active locks to the DLM |
| */ |
| public void addActiveLock(Object manager) { |
| getActiveLocks().addElement((ConcurrencyManager) manager); |
| } |
| |
| /** |
| * add a concurrency manager as deferred locks to the DLM |
| */ |
| public void addDeferredLock(Object manager) { |
| getDeferredLocks().addElement((ConcurrencyManager) manager); |
| } |
| |
| /** |
| * decrement the depth of the thread |
| */ |
| public void decrementDepth() { |
| threadDepth--; |
| } |
| |
| /** |
| * Return a set of the active locks from the DLM |
| */ |
| public Vector<ConcurrencyManager> getActiveLocks() { |
| return activeLocks; |
| } |
| |
| /** |
| * Return a set of the deferred locks |
| */ |
| public Vector<ConcurrencyManager> getDeferredLocks() { |
| return deferredLocks; |
| } |
| |
| /** |
| * Return the depth of the thread associated with the DLM, being used to release the lock |
| */ |
| public int getThreadDepth() { |
| return threadDepth; |
| } |
| |
| /** |
| * Return if there are any deferred locks. |
| */ |
| public boolean hasDeferredLock() { |
| return !getDeferredLocks().isEmpty(); |
| } |
| |
| /** |
| * increment the depth of the thread |
| */ |
| public void incrementDepth() { |
| threadDepth++; |
| } |
| |
| /** |
| * Return if the thread is complete |
| */ |
| public boolean isThreadComplete() { |
| return isThreadComplete; |
| } |
| |
| /** |
| * Release the active lock on the DLM |
| */ |
| public void releaseActiveLocksOnThread() { |
| Vector<ConcurrencyManager> activeLocks = getActiveLocks(); |
| if (!activeLocks.isEmpty()) { |
| for (Enumeration<ConcurrencyManager> activeLocksEnum = activeLocks.elements(); |
| activeLocksEnum.hasMoreElements();) { |
| ConcurrencyManager manager = activeLocksEnum.nextElement(); |
| manager.release(); |
| } |
| } |
| setIsThreadComplete(true); |
| } |
| |
| /** |
| * set a set of the active locks to the DLM |
| */ |
| public void setActiveLocks(Vector<ConcurrencyManager> activeLocks) { |
| this.activeLocks = activeLocks; |
| } |
| |
| /** |
| * set a set of the deferred locks to the DLM |
| */ |
| public void setDeferredLocks(Vector<ConcurrencyManager> deferredLocks) { |
| this.deferredLocks = deferredLocks; |
| } |
| |
| /** |
| * set if the thread is complete in the given DLM |
| */ |
| public void setIsThreadComplete(boolean isThreadComplete) { |
| this.isThreadComplete = isThreadComplete; |
| } |
| } |