Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;

import org.forgerock.i18n.LocalizableException;
import org.forgerock.i18n.LocalizableMessage;
Expand Down Expand Up @@ -93,9 +92,14 @@ public abstract class BackendImpl<C extends PluggableBackendCfg> extends LocalBa
/** The root container to use for this backend. */
private RootContainer rootContainer;

// FIXME: this is broken. Replace with read-write lock.
/** A count of the total operation threads currently in the backend. */
private final AtomicInteger threadTotalCount = new AtomicInteger(0);
/**
* A count of the total operation threads currently in the backend. Bumped
* twice per operation by all worker threads, so it uses a striped counter
* to avoid contending on a single cache line; it is only read when waiting
* for the backend to become quiescent, which is why it is not a LongAdder —
* see {@link StripedCounter}.
*/
private final StripedCounter threadTotalCount = new StripedCounter();
/** The base DNs defined for this backend instance. */
private Set<DN> baseDNs;

Expand Down Expand Up @@ -146,14 +150,14 @@ private EntryContainer accessBegin(Operation operation, DN entryDN, ResultCode n
throw new DirectoryException(
noEntryContainerResultCode, ERR_BACKEND_ENTRY_DOESNT_EXIST.get(entryDN, getBackendID()));
}
threadTotalCount.getAndIncrement();
threadTotalCount.increment();
return ec;
}

/** End a Backend API method that accesses the EntryContainer. */
private void accessEnd()
{
threadTotalCount.getAndDecrement();
threadTotalCount.decrement();
}

/**
Expand All @@ -163,7 +167,7 @@ private void accessEnd()
*/
private void waitUntilQuiescent()
{
while (threadTotalCount.get() > 0)
while (threadTotalCount.sum() > 0)
{
// Still have threads accessing the storage so sleep a little
try
Expand Down Expand Up @@ -268,7 +272,7 @@ public void closeBackend()
}

// Make sure the thread counts are zero for next initialization.
threadTotalCount.set(0);
threadTotalCount.reset();

// Log an informational message.
logger.info(NOTE_BACKEND_OFFLINE, cfg.getBackendId());
Expand Down Expand Up @@ -356,7 +360,7 @@ public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
throw de;
}

container.sharedLock.lock();
container.beginSharedAccess();
try
{
return ConditionResult.valueOf(container.hasSubordinates(entryDN));
Expand All @@ -367,7 +371,7 @@ public ConditionResult hasSubordinates(DN entryDN) throws DirectoryException
}
finally
{
container.sharedLock.unlock();
container.endSharedAccess();
accessEnd();
}
}
Expand All @@ -378,7 +382,7 @@ public long getNumberOfEntriesInBaseDN(DN baseDN) throws DirectoryException
checkNotNull(baseDN, "baseDN must not be null");

final EntryContainer ec = accessBegin(null, baseDN);
ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
return ec.getNumberOfEntriesInBaseDN();
Expand All @@ -390,7 +394,7 @@ public long getNumberOfEntriesInBaseDN(DN baseDN) throws DirectoryException
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -417,7 +421,7 @@ public long getNumberOfChildren(DN parentDN) throws DirectoryException
throw de;
}

ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
return ec.getNumberOfChildren(parentDN);
Expand All @@ -428,7 +432,7 @@ public long getNumberOfChildren(DN parentDN) throws DirectoryException
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -437,7 +441,7 @@ public long getNumberOfChildren(DN parentDN) throws DirectoryException
public boolean entryExists(final DN entryDN) throws DirectoryException
{
EntryContainer ec = accessBegin(null, entryDN);
ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
return ec.entryExists(entryDN);
Expand All @@ -448,7 +452,7 @@ public boolean entryExists(final DN entryDN) throws DirectoryException
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -457,7 +461,7 @@ public boolean entryExists(final DN entryDN) throws DirectoryException
public Entry getEntry(DN entryDN) throws DirectoryException
{
EntryContainer ec = accessBegin(null, entryDN);
ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
return ec.getEntry(entryDN);
Expand All @@ -468,7 +472,7 @@ public Entry getEntry(DN entryDN) throws DirectoryException
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -478,7 +482,7 @@ public void addEntry(Entry entry, AddOperation addOperation) throws DirectoryExc
{
EntryContainer ec = accessBegin(addOperation, entry.getName());

ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
ec.addEntry(entry, addOperation);
Expand All @@ -489,7 +493,7 @@ public void addEntry(Entry entry, AddOperation addOperation) throws DirectoryExc
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -500,7 +504,7 @@ public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
{
EntryContainer ec = accessBegin(deleteOperation, entryDN);

ec.sharedLock.lock();
ec.beginSharedAccess();
try
{
ec.deleteEntry(entryDN, deleteOperation);
Expand All @@ -511,7 +515,7 @@ public void deleteEntry(DN entryDN, DeleteOperation deleteOperation)
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -522,7 +526,7 @@ public void replaceEntry(Entry oldEntry, Entry newEntry, ModifyOperation modifyO
{
EntryContainer ec = accessBegin(modifyOperation, newEntry.getName());

ec.sharedLock.lock();
ec.beginSharedAccess();

try
{
Expand All @@ -534,7 +538,7 @@ public void replaceEntry(Entry oldEntry, Entry newEntry, ModifyOperation modifyO
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand All @@ -554,7 +558,7 @@ public void renameEntry(DN currentDN, Entry entry, ModifyDNOperation modifyDNOpe
throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, WARN_FUNCTION_NOT_SUPPORTED.get());
}

currentContainer.sharedLock.lock();
currentContainer.beginSharedAccess();
try
{
currentContainer.renameEntry(currentDN, entry, modifyDNOperation);
Expand All @@ -565,7 +569,7 @@ public void renameEntry(DN currentDN, Entry entry, ModifyDNOperation modifyDNOpe
}
finally
{
currentContainer.sharedLock.unlock();
currentContainer.endSharedAccess();
accessEnd();
}
}
Expand All @@ -577,7 +581,7 @@ public void search(SearchOperation searchOperation) throws DirectoryException, C
// is concerned: report it as such instead of the UNDEFINED result code used internally.
EntryContainer ec = accessBegin(searchOperation, searchOperation.getBaseDN(), ResultCode.NO_SUCH_OBJECT);

ec.sharedLock.lock();
ec.beginSharedAccess();

try
{
Expand All @@ -589,7 +593,7 @@ public void search(SearchOperation searchOperation) throws DirectoryException, C
}
finally
{
ec.sharedLock.unlock();
ec.endSharedAccess();
accessEnd();
}
}
Expand Down
Loading
Loading