@Override
  public void copy(
      final int offset, final MemoryChunk other, final int otherOffset, final int count) {
    Preconditions.checkNotNull(other);

    // This implementation acquires locks on this and other objects and then delegates to
    // doCopy which does actual copy. In order to avoid deadlocks we have to establish some linear
    // order on all NativeMemoryChunks and acquire locks according to this order. Fortunately
    // we can use the unique ids for that purpose. So we have to address 3 cases:

    // Case 1: other memory chunk == this memory chunk
    if (other.getUniqueId() == getUniqueId()) {
      // we do not allow copying to the same address
      // lets log warning and not copy
      Log.w(
          TAG,
          "Copying from NativeMemoryChunk "
              + Integer.toHexString(System.identityHashCode(this))
              + " to NativeMemoryChunk "
              + Integer.toHexString(System.identityHashCode(other))
              + " which share the same address "
              + Long.toHexString(mNativePtr));
      Preconditions.checkArgument(false);
    }

    // Case 2: other memory chunk < this memory chunk
    if (other.getUniqueId() < getUniqueId()) {
      synchronized (other) {
        synchronized (this) {
          doCopy(offset, other, otherOffset, count);
        }
      }
      return;
    }

    // Case 3: other memory chunk > this memory chunk
    synchronized (this) {
      synchronized (other) {
        doCopy(offset, other, otherOffset, count);
      }
    }
  }
flag indicating if this object was closed @GuardedBy("this")
memory-types/nativememory/src/main/java/com/facebook/imagepipeline/memory/NativeMemoryChunk.java