assert refcount never climbs after reaching 0

Looking for a common but not-yet-reproducible situation where the
gamelock gets stuck preventing a game from being opened, usually related
to a move arriving. One thing that looked wrong is it seemed possible to
have the refcount drop to 0 then get increased again, causing somebody
to thing he has a lock when it's actually unlocked. So assert to try to
catch that case (and synchronize to make it much harder.)
This commit is contained in:
Eric House 2019-05-29 15:51:09 -07:00
parent b50bc145af
commit ce26696a37
2 changed files with 19 additions and 8 deletions

View file

@ -40,6 +40,14 @@ public class Assert {
} }
} }
// NR: non-release
public static void assertTrueNR( boolean val )
{
if ( BuildConfig.DEBUG || !BuildConfig.IS_TAGGED_BUILD ) {
assertTrue( val );
}
}
public static void assertNotNull( Object val ) public static void assertNotNull( Object val )
{ {
assertTrue( val != null ); assertTrue( val != null );

View file

@ -23,12 +23,10 @@ package org.eehouse.android.xw4;
import android.os.Handler; import android.os.Handler;
import java.io.Serializable; import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.Formatter; import java.util.Formatter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
@ -59,7 +57,7 @@ public class GameLock implements AutoCloseable, Serializable {
// private static final long ASSERT_TIME = 2000; // private static final long ASSERT_TIME = 2000;
private static final long THROW_TIME = 1000; private static final long THROW_TIME = 1000;
private long m_rowid; private long m_rowid;
private AtomicInteger m_lockCount = new AtomicInteger(1); private int[] m_lockCount = {1};
private static class Owner { private static class Owner {
Thread mThread; Thread mThread;
@ -324,16 +322,21 @@ public class GameLock implements AutoCloseable, Serializable {
public void release() public void release()
{ {
int count = m_lockCount.decrementAndGet(); synchronized ( m_lockCount ) {
if ( count == 0 ) { int count = --m_lockCount[0];
getFor( m_rowid ).unlock(); if ( count == 0 ) {
getFor( m_rowid ).unlock();
}
} }
} }
public GameLock retain() public GameLock retain()
{ {
int count = m_lockCount.incrementAndGet(); synchronized ( m_lockCount ) {
return this; int count = m_lockCount[0]++;
Assert.assertTrueNR( count > 0 );
return this;
}
} }
@Override @Override