use of org.apache.geode.internal.util.concurrent.FutureResult in project geode by apache.
the class DLockService method becomeLockGrantor.
/**
* @param predecessor non-null if a predecessor asked us to take over for him
*/
void becomeLockGrantor(InternalDistributedMember predecessor) {
Assert.assertTrue(predecessor == null);
boolean ownLockGrantorFutureResult = false;
FutureResult lockGrantorFutureResultRef = null;
final boolean isDebugEnabled_DLS = logger.isTraceEnabled(LogMarker.DLS);
LockGrantorId myLockGrantorId = null;
try {
// terminate loop if this thread gets control of lockGrantorFutureResult
while (!ownLockGrantorFutureResult) {
Assert.assertHoldsLock(this.destroyLock, false);
synchronized (this.lockGrantorIdLock) {
if (isCurrentlyOrIsMakingLockGrantor()) {
return;
} else if (this.lockGrantorFutureResult != null) {
// need to wait for other thread controlling lockGrantorFutureResult
lockGrantorFutureResultRef = this.lockGrantorFutureResult;
} else {
// this thread is in control and will procede to become grantor
// create new lockGrantorFutureResult for other threads to block on
ownLockGrantorFutureResult = true;
lockGrantorFutureResultRef = new FutureResult(this.dm.getCancelCriterion());
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "[becomeLockGrantor] creating lockGrantorFutureResult");
}
this.lockGrantorFutureResult = lockGrantorFutureResultRef;
}
}
if (!ownLockGrantorFutureResult) {
waitForLockGrantorFutureResult(lockGrantorFutureResultRef, 0, TimeUnit.MILLISECONDS);
continue;
}
}
// this thread is now in charge of the lockGrantorFutureResult future
getStats().incBecomeGrantorRequests();
// create the new grantor instance in non-ready state...
long tempGrantorVersion = -1;
LockGrantorId tempLockGrantorId = new LockGrantorId(this.dm, this.dm.getId(), tempGrantorVersion, getSerialNumber());
DLockGrantor myGrantor = DLockGrantor.createGrantor(this, tempGrantorVersion);
try {
synchronized (this.lockGrantorIdLock) {
Assert.assertTrue(setLockGrantorId(tempLockGrantorId, myGrantor));
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "become set lockGrantorId to {} for service {}", this.lockGrantorId, this.serviceName);
}
InternalDistributedMember elder = getElderId();
Assert.assertTrue(elder != null);
// NOTE: elder currently returns GrantorInfo for the previous grantor
// CONSIDER: add elderCommunicatedWith to GrantorInfo
GrantorInfo gi = becomeGrantor(predecessor);
boolean needsRecovery = gi.needsRecovery();
long myGrantorVersion = gi.getVersionId() + 1;
myGrantor.setVersionId(myGrantorVersion);
myLockGrantorId = new LockGrantorId(this.dm, this.dm.getId(), myGrantorVersion, getSerialNumber());
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "[becomeLockGrantor] Calling makeLocalGrantor");
}
if (!makeLocalGrantor(elder, needsRecovery, myLockGrantorId, myGrantor)) {
return;
}
} finally {
Assert.assertTrue(myGrantor == null || !myGrantor.isInitializing() || this.dm.getCancelCriterion().isCancelInProgress() || isDestroyed(), "BecomeLockGrantor failed and left grantor non-ready");
}
} finally {
synchronized (this.lockGrantorIdLock) {
if (ownLockGrantorFutureResult) {
// this thread is doing the real work and must finish the future
Assert.assertTrue(this.lockGrantorFutureResult == lockGrantorFutureResultRef);
boolean getLockGrantorIdFailed = myLockGrantorId == null;
if (getLockGrantorIdFailed) {
// failed so cancel lockGrantorFutureResult
// interrupt waiting threads
lockGrantorFutureResultRef.cancel(true);
} else {
// don't succeed if shutting
this.dm.getCancelCriterion().checkCancelInProgress(null);
// down
// succeeded so set lockGrantorFutureResult
lockGrantorFutureResultRef.set(myLockGrantorId);
}
// null out the reference so it is free for next usage
this.lockGrantorFutureResult = null;
}
}
}
}
use of org.apache.geode.internal.util.concurrent.FutureResult in project geode by apache.
the class DLockService method notLockGrantorId.
/**
* nulls out grantor to force call to elder
*
* @param timeToWait how long to wait for a new grantor. -1 don't wait, 0 no time limit
* @param timeUnit the unit of measure of timeToWait
*/
private void notLockGrantorId(LockGrantorId notLockGrantorId, long timeToWait, final TimeUnit timeUnit) {
if (notLockGrantorId.isLocal(getSerialNumber())) {
if (logger.isTraceEnabled(LogMarker.DLS)) {
logger.trace(LogMarker.DLS, "notLockGrantorId {} returning early because notGrantor {} was equal to the local dm {}", this.serviceName, notLockGrantorId, this.dm.getId());
}
// Let the local destroy or processing of transfer do the clear
return;
}
boolean ownLockGrantorFutureResult = false;
FutureResult lockGrantorFutureResultRef = null;
long statStart = -1;
LockGrantorId currentLockGrantorId = null;
try {
Assert.assertHoldsLock(this.destroyLock, false);
synchronized (this.lockGrantorIdLock) {
currentLockGrantorId = this.lockGrantorId;
if (this.lockGrantorFutureResult != null) {
// some other thread is talking to elder
lockGrantorFutureResultRef = this.lockGrantorFutureResult;
} else if (!notLockGrantorId.sameAs(currentLockGrantorId)) {
return;
} else {
// this thread needs to talk to elder
ownLockGrantorFutureResult = true;
lockGrantorFutureResultRef = new FutureResult(this.dm.getCancelCriterion());
this.lockGrantorFutureResult = lockGrantorFutureResultRef;
}
}
statStart = getStats().startGrantorWait();
if (!ownLockGrantorFutureResult) {
if (timeToWait >= 0) {
waitForLockGrantorFutureResult(lockGrantorFutureResultRef, timeToWait, timeUnit);
}
return;
}
InternalDistributedMember elder = getElderId();
Assert.assertTrue(elder != null);
LockGrantorId elderLockGrantorId = null;
GrantorInfo gi = peekGrantor();
if (gi.getId() != null) {
elderLockGrantorId = new LockGrantorId(this.dm, gi.getId(), gi.getVersionId(), gi.getSerialNumber());
}
if (notLockGrantorId.sameAs(elderLockGrantorId)) {
// elder says that notLockGrantorId is still the grantor...
sleep(NOT_GRANTOR_SLEEP);
return;
} else {
// elder says another member is the grantor
nullLockGrantorId(notLockGrantorId);
if (logger.isTraceEnabled(LogMarker.DLS)) {
logger.trace(LogMarker.DLS, "notLockGrantorId cleared lockGrantorId for service {}", this.serviceName);
}
}
} finally {
synchronized (this.lockGrantorIdLock) {
if (statStart > -1) {
getStats().endGrantorWait(statStart, false);
}
if (ownLockGrantorFutureResult) {
// this thread is doing the real work and must finish the future
Assert.assertTrue(this.lockGrantorFutureResult == lockGrantorFutureResultRef);
// cancel lockGrantorFutureResult
lockGrantorFutureResultRef.cancel(false);
// null out the reference so it is free for next usage
this.lockGrantorFutureResult = null;
}
}
}
// finally block for lockGrantorFutureResult
}
use of org.apache.geode.internal.util.concurrent.FutureResult in project geode by apache.
the class LocalRegion method nonTxnFindObject.
/**
* optimized to only allow one thread to do a search/load, other threads wait on a future
*
* @param isCreate true if call found no entry; false if updating an existing entry
* @param localValue the value retrieved from the region for this object.
* @param disableCopyOnRead if true then do not make a copy
* @param preferCD true if the preferred result form is CachedDeserializable
* @param clientEvent the client event, if any
* @param returnTombstones whether to return tombstones
*/
@Retained
Object nonTxnFindObject(KeyInfo keyInfo, boolean isCreate, boolean generateCallbacks, Object localValue, boolean disableCopyOnRead, boolean preferCD, ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent, boolean returnTombstones) throws TimeoutException, CacheLoaderException {
@Retained Object result = null;
FutureResult thisFuture = new FutureResult(this.stopper);
Future otherFuture = (Future) this.getFutures.putIfAbsent(keyInfo.getKey(), thisFuture);
// only one thread can get their future into the map for this key at a time
if (otherFuture != null) {
try {
Object[] valueAndVersion = (Object[]) otherFuture.get();
if (valueAndVersion != null) {
result = valueAndVersion[0];
if (clientEvent != null) {
clientEvent.setVersionTag((VersionTag) valueAndVersion[1]);
}
if (!preferCD && result instanceof CachedDeserializable) {
CachedDeserializable cd = (CachedDeserializable) result;
// fix for bug 43023
if (!disableCopyOnRead && isCopyOnRead()) {
result = cd.getDeserializedWritableCopy(null, null);
} else {
result = cd.getDeserializedForReading();
}
} else if (!disableCopyOnRead) {
result = conditionalCopy(result);
}
// what was a miss is now a hit
if (isCreate) {
RegionEntry regionEntry = basicGetEntry(keyInfo.getKey());
updateStatsForGet(regionEntry, true);
}
return result;
}
// if value == null, try our own search/load
} catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
// TODO check a CancelCriterion here?
return null;
} catch (ExecutionException e) {
// NOTE: this was creating InternalGemFireError and initCause with itself
throw new InternalGemFireError(LocalizedStrings.LocalRegion_UNEXPECTED_EXCEPTION.toLocalizedString(), e);
}
}
// condition where the future was just removed by another thread
try {
boolean partitioned = this.getDataPolicy().withPartitioning();
if (!partitioned) {
localValue = getDeserializedValue(null, keyInfo, isCreate, disableCopyOnRead, preferCD, clientEvent, false, false);
// stats have now been updated
if (localValue != null && !Token.isInvalid(localValue)) {
result = localValue;
return result;
}
isCreate = localValue == null;
result = findObjectInSystem(keyInfo, isCreate, null, generateCallbacks, localValue, disableCopyOnRead, preferCD, requestingClient, clientEvent, returnTombstones);
} else {
// For PRs we don't want to deserialize the value and we can't use findObjectInSystem
// because it can invoke code that is transactional.
result = getSharedDataView().findObject(keyInfo, this, isCreate, generateCallbacks, localValue, disableCopyOnRead, preferCD, requestingClient, clientEvent, returnTombstones);
}
if (result == null && localValue != null) {
if (localValue != Token.TOMBSTONE || returnTombstones) {
result = localValue;
}
}
// findObjectInSystem does not call conditionalCopy
} finally {
if (result != null) {
VersionTag tag = clientEvent == null ? null : clientEvent.getVersionTag();
thisFuture.set(new Object[] { result, tag });
} else {
thisFuture.set(null);
}
this.getFutures.remove(keyInfo.getKey());
}
if (!disableCopyOnRead) {
result = conditionalCopy(result);
}
return result;
}
use of org.apache.geode.internal.util.concurrent.FutureResult in project geode by apache.
the class AdminDistributedSystemImpl method initializeCacheServers.
/**
* Creates <code>CacheServer</code> instances for every cache server entry in the
* {@link org.apache.geode.admin.DistributedSystemConfig}
*/
private void initializeCacheServers() {
CacheServerConfig[] cacheServerConfigs = this.config.getCacheServerConfigs();
for (int i = 0; i < cacheServerConfigs.length; i++) {
try {
CacheServerConfig conf = cacheServerConfigs[i];
CacheServerConfigImpl copy = new CacheServerConfigImpl(conf);
this.cacheServerSet.add(new FutureResult(createCacheServer(copy)));
} catch (java.lang.Exception e) {
logger.warn(e.getMessage(), e);
continue;
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (java.lang.Error e) {
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
logger.error(e.getMessage(), e);
continue;
}
}
}
use of org.apache.geode.internal.util.concurrent.FutureResult in project geode by apache.
the class DLockService method getLockGrantorId.
/**
* Returns id of the current lock grantor for this service. If necessary, a request will be sent
* to the elder to fetch this information.
*/
public LockGrantorId getLockGrantorId() {
final boolean isDebugEnabled_DLS = logger.isTraceEnabled(LogMarker.DLS);
boolean ownLockGrantorFutureResult = false;
FutureResult lockGrantorFutureResultRef = null;
long statStart = -1;
LockGrantorId theLockGrantorId = null;
while (theLockGrantorId == null) {
ownLockGrantorFutureResult = false;
try {
Assert.assertHoldsLock(this.destroyLock, false);
synchronized (this.lockGrantorIdLock) {
if (this.lockGrantorFutureResult != null) {
lockGrantorFutureResultRef = this.lockGrantorFutureResult;
} else if (this.lockGrantorId != null) {
return this.lockGrantorId;
} else {
ownLockGrantorFutureResult = true;
lockGrantorFutureResultRef = new FutureResult(this.dm.getCancelCriterion());
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "[getLockGrantorId] creating lockGrantorFutureResult");
}
this.lockGrantorFutureResult = lockGrantorFutureResultRef;
}
}
statStart = getStats().startGrantorWait();
if (!ownLockGrantorFutureResult) {
LockGrantorId lockGrantorIdRef = waitForLockGrantorFutureResult(lockGrantorFutureResultRef, 0, TimeUnit.MILLISECONDS);
if (lockGrantorIdRef != null) {
return lockGrantorIdRef;
} else {
continue;
}
}
InternalDistributedMember elder = getElderId();
Assert.assertTrue(elder != null);
GrantorInfo gi = getGrantorRequest();
theLockGrantorId = new LockGrantorId(this.dm, gi.getId(), gi.getVersionId(), gi.getSerialNumber());
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "[getLockGrantorId] elder says grantor is {}", theLockGrantorId);
}
// elder tells us to be the grantor...
if (theLockGrantorId.isLocal(getSerialNumber())) {
boolean needsRecovery = gi.needsRecovery();
if (!needsRecovery) {
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS, "[getLockGrantorId] needsRecovery is false");
}
synchronized (this.lockGrantorIdLock) {
// either no previous grantor or grantor is newer
Assert.assertTrue(this.lockGrantorId == null || this.lockGrantorId.isNewerThan(theLockGrantorId) || this.lockGrantorId.sameAs(theLockGrantorId), this.lockGrantorId + " should be null or newer than or same as " + theLockGrantorId);
}
}
if (!createLocalGrantor(elder, needsRecovery, theLockGrantorId)) {
theLockGrantorId = this.lockGrantorId;
}
} else // elder says another member is the grantor
{
synchronized (this.lockGrantorIdLock) {
if (!setLockGrantorId(theLockGrantorId)) {
theLockGrantorId = this.lockGrantorId;
}
}
}
} finally {
synchronized (this.lockGrantorIdLock) {
boolean getLockGrantorIdFailed = theLockGrantorId == null;
if (statStart > -1) {
getStats().endGrantorWait(statStart, getLockGrantorIdFailed);
}
if (ownLockGrantorFutureResult) {
// this thread is doing the real work and must finish the future
Assert.assertTrue(this.lockGrantorFutureResult == lockGrantorFutureResultRef);
if (getLockGrantorIdFailed) {
// failed so cancel lockGrantorFutureResult
lockGrantorFutureResultRef.cancel(false);
} else {
// succeeded so set lockGrantorFutureResult
lockGrantorFutureResultRef.set(theLockGrantorId);
}
// null out the reference so it is free for next usage
this.lockGrantorFutureResult = null;
}
}
}
// finally block for lockGrantorFutureResult
}
// while theLockGrantorId == null
return theLockGrantorId;
}
Aggregations