humble-video-noarch/src/main/java/io/humble/ferry/JNIMemoryManager.java
final boolean addReference(final JNIReference ref)
  {
    /* Implementation note: This method is extremely
     * hot, and so I've unrolled the lock and unlock
     * methods from above.  Take care if you change
     * them to change the unrolled versions here.
     * 
     */
    // First try to grab the non blocking lock
    boolean gotNonblockingLock = false;
    gotNonblockingLock = mSpinLock.compareAndSet(false, true);
    if (gotNonblockingLock)
    {
      final int slot = mNextAvailableReferenceSlot++;
      if (slot < mMaxValidReference)
      {
        mValidReferences[slot] = ref;
        // unlock the non-blocking lock, and progress to a full lock.
        final boolean result = mSpinLock.compareAndSet(true, false);
        assert result : "Should never be unlocked here";
        return true;
      }
      // try the big lock without blocking
      if (!mLock.tryLock()) {
        // we couldn't get the big lock, so release the spin lock
        // and try getting the bit lock while blocking
        gotNonblockingLock = false;
        mSpinLock.compareAndSet(true, false);
      }
    }
    // The above code needs to make sure that we never
    // have gotNonblockingLock set, unless we have both
    // the spin lock and the big lock.
    if (!gotNonblockingLock){
      mLock.lock();
      while(!mSpinLock.compareAndSet(false, true))
        ; // grab the spin lock
    }
    try {
      int slot = mNextAvailableReferenceSlot++;
      if (slot >= mMaxValidReference)
      {
        sweepAndCollect();
        slot = mNextAvailableReferenceSlot++;
      }
      mValidReferences[slot] = ref;
    } finally {
      final boolean result = mSpinLock.compareAndSet(true, false);
      assert result : "Should never ever be unlocked here";
      mLock.unlock();
    }
    return true;
  }
final boolean addReference(final JNIReference ref)
  {
    /* Implementation note: This method is extremely
     * hot, and so I've unrolled the lock and unlock
     * methods from above.  Take care if you change
     * them to change the unrolled versions here.
     * 
     */
    // First try to grab the non blocking lock
    boolean gotNonblockingLock = false;
    gotNonblockingLock = mSpinLock.compareAndSet(false, true);
    if (gotNonblockingLock)
    {
      final int slot = mNextAvailableReferenceSlot++;
      if (slot < mMaxValidReference)
      {
        mValidReferences[slot] = ref;
        // unlock the non-blocking lock, and progress to a full lock.
        final boolean result = mSpinLock.compareAndSet(true, false);
        assert result : "Should never be unlocked here";
        return true;
      }
      // try the big lock without blocking
      if (!mLock.tryLock()) {
        // we couldn't get the big lock, so release the spin lock
        // and try getting the bit lock while blocking
        gotNonblockingLock = false;
        mSpinLock.compareAndSet(true, false);
      }
    }
    // The above code needs to make sure that we never
    // have gotNonblockingLock set, unless we have both
    // the spin lock and the big lock.
    if (!gotNonblockingLock){
      mLock.lock();
      while(!mSpinLock.compareAndSet(false, true))
        ; // grab the spin lock
    }
    try {
      int slot = mNextAvailableReferenceSlot++;
      if (slot >= mMaxValidReference)
      {
        sweepAndCollect();
        slot = mNextAvailableReferenceSlot++;
      }
      mValidReferences[slot] = ref;
    } finally {
      final boolean result = mSpinLock.compareAndSet(true, false);
      assert result : "Should never ever be unlocked here";
      mLock.unlock();
    }
    return true;
  }
Add a reference to the set of references we'll collect.

@param ref The reference to collect.
@return true if already in list; false otherwise.