All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.couchbase.lite.internal.core.C4NativePeer Maven / Gradle / Ivy

//
// Copyright (c) 2020 Couchbase, Inc All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.couchbase.lite.internal.core;

import java.util.concurrent.atomic.AtomicLong;

import com.couchbase.lite.LiteCoreException;
import com.couchbase.lite.LogDomain;
import com.couchbase.lite.internal.CouchbaseLiteInternal;
import com.couchbase.lite.internal.support.Log;
import com.couchbase.lite.internal.utils.Fn;
import com.couchbase.lite.internal.utils.Preconditions;


/**
 * This approach doesn't actually solve the peer management problem.
 * It is still entirely possible that the peer whose handle is returned
 * by getPeer will be freed while the client is still using it.
 * 

* It also exposes the native handle because anybody can call `get`. */ public abstract class C4NativePeer extends AtomicLong { private static final String HANDLE_NAME = "peer handle"; private Exception cleared; protected C4NativePeer() {} protected C4NativePeer(long handle) { setPeerHandle(handle); } protected final void setPeer(long handle) { setPeerHandle(handle); } protected final long getPeerUnchecked() { return get(); } protected long getPeerAndClear() { if (CouchbaseLiteInternal.isDebugging()) { cleared = new Exception(); } return getAndSet(0L); } protected final long getPeer() { final long handle = get(); if (handle == 0) { logBadCall(); throw new IllegalStateException("Operation on closed native peer"); } return handle; } protected T withPeer(T def, Fn.Function fn) { final long handle = get(); if (handle == 0) { logBadCall(); return def; } return fn.apply(handle); } protected T withPeerThrows(T def, Fn.FunctionThrows fn) throws LiteCoreException { final long handle = get(); if (handle == 0) { logBadCall(); return def; } return fn.apply(handle); } private void setPeerHandle(long handle) { Preconditions.assertZero(getAndSet(Preconditions.assertNotZero(handle, HANDLE_NAME)), HANDLE_NAME); } private void logBadCall() { Log.w(LogDomain.DATABASE, "Operation on closed native peer", new Exception()); Log.w(LogDomain.DATABASE, "Closed at", cleared); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy