use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class AbstractRegionEntry method getValueInVM.
@Override
public Object getValueInVM(RegionEntryContext context) {
ReferenceCountHelper.createReferenceCountOwner();
@Released Object v = _getValueRetain(context, true);
if (v == null) {
// should only be possible if disk entry
v = Token.NOT_AVAILABLE;
}
Object result = OffHeapHelper.copyAndReleaseIfNeeded(v);
ReferenceCountHelper.setReferenceCountOwner(null);
return result;
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class AbstractRegionEntry method processGatewayTag.
private boolean processGatewayTag(EntryEvent cacheEvent) {
// Gateway tags are installed in the server-side LocalRegion cache
// modification methods. They do not have version numbers or distributed
// member IDs. Instead they only have timestamps and distributed system IDs.
// If there is a resolver plug-in, invoke it. Otherwise we use the timestamps and
// distributed system IDs to determine whether to allow the event to proceed.
final boolean isDebugEnabled = logger.isDebugEnabled();
if (this.isRemoved() && !this.isTombstone()) {
// no conflict on a new entry
return true;
}
EntryEventImpl event = (EntryEventImpl) cacheEvent;
VersionTag tag = event.getVersionTag();
long stampTime = getVersionStamp().getVersionTimeStamp();
long tagTime = tag.getVersionTimeStamp();
int stampDsid = getVersionStamp().getDistributedSystemId();
int tagDsid = tag.getDistributedSystemId();
if (isDebugEnabled) {
logger.debug("processing gateway version information for {}. Stamp dsid={} time={} Tag dsid={} time={}", event.getKey(), stampDsid, stampTime, tagDsid, tagTime);
}
if (tagTime == VersionTag.ILLEGAL_VERSION_TIMESTAMP) {
// no timestamp received from other system - just apply it
return true;
}
if (tagDsid == stampDsid || stampDsid == -1) {
return true;
}
GatewayConflictResolver resolver = event.getRegion().getCache().getGatewayConflictResolver();
if (resolver != null) {
if (isDebugEnabled) {
logger.debug("invoking gateway conflict resolver");
}
final boolean[] disallow = new boolean[1];
final Object[] newValue = new Object[] { this };
GatewayConflictHelper helper = new GatewayConflictHelper() {
@Override
public void disallowEvent() {
disallow[0] = true;
}
@Override
public void changeEventValue(Object value) {
newValue[0] = value;
}
};
@Released TimestampedEntryEventImpl timestampedEvent = (TimestampedEntryEventImpl) event.getTimestampedEvent(tagDsid, stampDsid, tagTime, stampTime);
// gateway conflict resolvers will usually want to see the old value
if (!timestampedEvent.hasOldValue() && isRemoved()) {
// OFFHEAP: since isRemoved I think getValue will never be stored off heap in this case
timestampedEvent.setOldValue(getValue(timestampedEvent.getRegion()));
}
Throwable thr = null;
try {
resolver.onEvent(timestampedEvent, helper);
} catch (CancelException cancelled) {
throw cancelled;
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// now, so don't let this thread continue.
throw err;
} catch (Throwable t) {
// 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(LocalizedMessage.create(LocalizedStrings.LocalRegion_EXCEPTION_OCCURRED_IN_CONFLICTRESOLVER), t);
thr = t;
} finally {
timestampedEvent.release();
}
if (isDebugEnabled) {
logger.debug("done invoking resolver", thr);
}
if (thr == null) {
if (disallow[0]) {
if (isDebugEnabled) {
logger.debug("conflict resolver rejected the event for {}", event.getKey());
}
throw new ConcurrentCacheModificationException("WAN conflict resolver rejected the operation");
}
tag.setAllowedByResolver(true);
if (newValue[0] != this) {
if (isDebugEnabled) {
logger.debug("conflict resolver changed the value of the event for {}", event.getKey());
}
// the resolver changed the event value!
event.setNewValue(newValue[0]);
}
// if nothing was done then we allow the event
if (isDebugEnabled) {
logger.debug("change was allowed by conflict resolver: {}", tag);
}
return true;
}
}
if (isDebugEnabled) {
logger.debug("performing normal WAN conflict check");
}
if (tagTime > stampTime || tagTime == stampTime && tagDsid >= stampDsid) {
if (isDebugEnabled) {
logger.debug("allowing event");
}
return true;
}
if (isDebugEnabled) {
logger.debug("disallowing event for {}", event.getKey());
}
throw new ConcurrentCacheModificationException("conflicting WAN event detected");
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class LocalRegion method basicBridgeReplace.
// TODO: fromClient is always true
public Object basicBridgeReplace(final Object key, Object value, boolean isObject, Object callbackArg, final ClientProxyMembershipID client, boolean fromClient, EntryEventImpl clientEvent) throws TimeoutException, EntryExistsException, CacheWriterException {
EventID eventId = clientEvent.getEventId();
long startPut = CachePerfStats.getStatTime();
if (fromClient) {
// GatewayEventCallbackArgument to store the event id.
if (isGatewaySenderEnabled()) {
callbackArg = new GatewaySenderEventCallbackArgument(callbackArg);
}
}
@Released final EntryEventImpl event = EntryEventImpl.create(this, Operation.REPLACE, key, null, callbackArg, false, client.getDistributedMember(), true, eventId);
try {
event.setContext(client);
// Set the new value to the input byte[] if it isn't null
if (value != null) {
// in a CachedDeserializable; otherwise store it directly as a byte[]
if (isObject) {
// The value represents an object
event.setSerializedNewValue((byte[]) value);
} else {
// The value does not represent an object
event.setNewValue(value);
}
}
validateArguments(key, event.basicGetNewValue(), callbackArg);
// can overwrite an existing key
boolean ifNew = false;
// cannot create a new key
boolean ifOld = true;
boolean requireOldValue = true;
boolean succeeded = basicPut(event, ifNew, ifOld, null, requireOldValue);
getCachePerfStats().endPut(startPut, false);
this.stopper.checkCancelInProgress(null);
clientEvent.isConcurrencyConflict(event.isConcurrencyConflict());
if (succeeded) {
clientEvent.setVersionTag(event.getVersionTag());
// to fix bug 42968 call getRawOldValue instead of getOldValue
Object oldValue = event.getRawOldValueAsHeapObject();
if (oldValue == Token.NOT_AVAILABLE) {
oldValue = AbstractRegion.handleNotAvailable(oldValue);
}
if (oldValue == null) {
// EntryEventImpl.setOldValue translates INVALID to null
oldValue = Token.INVALID;
}
return oldValue;
} else {
return null;
}
} finally {
event.release();
}
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class LocalRegion method basicBridgeDestroy.
public void basicBridgeDestroy(Object key, Object callbackArg, ClientProxyMembershipID memberId, boolean fromClient, EntryEventImpl clientEvent) throws TimeoutException, EntryNotFoundException, CacheWriterException {
Object theCallbackArg = callbackArg;
if (fromClient) {
// GatewayEventCallbackArgument to store the event id.
if (isGatewaySenderEnabled()) {
theCallbackArg = new GatewaySenderEventCallbackArgument(theCallbackArg);
}
}
// Create an event and put the entry
@Released final EntryEventImpl event = EntryEventImpl.create(this, Operation.DESTROY, key, null, theCallbackArg, false, memberId.getDistributedMember(), true, clientEvent.getEventId());
try {
event.setContext(memberId);
// if this is a replayed or WAN operation we may already have a version tag
event.setVersionTag(clientEvent.getVersionTag());
try {
basicDestroy(event, true, null);
} catch (ConcurrentCacheModificationException ignore) {
// thrown by WAN conflicts
event.isConcurrencyConflict(true);
} finally {
clientEvent.setVersionTag(event.getVersionTag());
clientEvent.isConcurrencyConflict(event.isConcurrencyConflict());
clientEvent.setIsRedestroyedEntry(event.getIsRedestroyedEntry());
}
} finally {
event.release();
}
}
use of org.apache.geode.internal.offheap.annotations.Released in project geode by apache.
the class LocalRegion method localDestroy.
@Override
public void localDestroy(Object key, Object aCallbackArgument) throws EntryNotFoundException {
validateKey(key);
checkReadiness();
checkForNoAccess();
@Released EntryEventImpl event = EntryEventImpl.create(this, Operation.LOCAL_DESTROY, key, null, aCallbackArgument, false, getMyId());
if (generateEventID()) {
event.setNewEventId(this.cache.getDistributedSystem());
}
try {
// expectedOldValue
basicDestroy(event, false, null);
} catch (CacheWriterException e) {
// cache writer not called
throw new Error(LocalizedStrings.LocalRegion_CACHE_WRITER_SHOULD_NOT_HAVE_BEEN_CALLED_FOR_LOCALDESTROY.toLocalizedString(), e);
} catch (TimeoutException e) {
// no distributed lock
throw new Error(LocalizedStrings.LocalRegion_NO_DISTRIBUTED_LOCK_SHOULD_HAVE_BEEN_ATTEMPTED_FOR_LOCALDESTROY.toLocalizedString(), e);
} finally {
event.release();
}
}
Aggregations