assertion says had race condition; fix it

Use a set instead of a singleton so a late clear doesn't overwrite an
early set.
This commit is contained in:
Eric House 2019-01-16 11:31:54 -08:00
parent a93b1da6fa
commit 4c9ded77bf
3 changed files with 28 additions and 30 deletions

View file

@ -158,7 +158,7 @@ public class DelegateBase implements DlgClickNotify,
protected void onPause()
{
m_isVisible = false;
XWServiceHelper.setListener( null );
XWServiceHelper.clearListener( this );
m_dlgDelegate.onPausing();
}

View file

@ -26,6 +26,9 @@ import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
import org.eehouse.android.xw4.loc.LocUtils;
@ -58,8 +61,8 @@ public class MultiService {
private static final String ACTION_FETCH_DICT = "_afd";
private static final String FOR_MISSING_DICT = "_fmd";
// Shouldn't this be a Set?
private MultiEventListener m_li;
private Set<MultiEventListener> m_lis = Collections
.newSetFromMap(new ConcurrentHashMap<MultiEventListener, Boolean>());
// these do not currently pass between devices so they can change.
public enum MultiEvent { _INVALID,
@ -100,28 +103,25 @@ public class MultiService {
public void setListener( MultiEventListener li )
{
synchronized( this ) {
// If this is happening, the order of resume/pause isn't what we
// expect. Might need to keep a set of these instead of a
// singleton.
if ( BuildConfig.DEBUG ) {
if ( m_li == null && li == null ) {
Assert.fail();
} else if ( m_li != null && li != null ) {
Assert.fail();
}
}
m_li = li;
}
m_lis.add( li );
}
public void postEvent( MultiEvent event, Object ... args )
public void clearListener( MultiEventListener li )
{
synchronized( this ) {
if ( null != m_li ) {
m_li.eventOccurred( event, args );
}
Assert.assertTrue( m_lis.contains( li ) || ! BuildConfig.DEBUG );
m_lis.remove( li );
}
public int postEvent( MultiEvent event, Object ... args )
{
// don't just return size(): concurrency doesn't guarantee isn't
// changed
int count = 0;
for ( MultiEventListener listener : m_lis ) {
listener.eventOccurred( event, args );
++count;
}
return count;
}
public static Intent makeMissingDictIntent( Context context, NetLaunchInfo nli,

View file

@ -39,7 +39,7 @@ import java.util.Map;
abstract class XWServiceHelper {
private static final String TAG = XWServiceHelper.class.getSimpleName();
private Service mService;
private static MultiService s_srcMgr = null;
private static MultiService s_srcMgr = new MultiService();
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
@ -101,19 +101,17 @@ abstract class XWServiceHelper {
public final static void setListener( MultiService.MultiEventListener li )
{
if ( null == s_srcMgr ) {
// DbgUtils.logf( "XWService.setListener: registering %s",
// li.getClass().getName() );
s_srcMgr = new MultiService();
}
s_srcMgr.setListener( li );
}
public final static void clearListener( MultiService.MultiEventListener li )
{
s_srcMgr.clearListener( li );
}
protected void postEvent( MultiEvent event, Object ... args )
{
if ( null != s_srcMgr ) {
s_srcMgr.postEvent( event, args );
} else {
if ( 0 == s_srcMgr.postEvent( event, args ) ) {
Log.d( TAG, "postEvent(): dropping %s event",
event.toString() );
}