synchronize read and write of files, fixing a race condition between

BoardActivity shutdown (save) and GamesList refresh (open) that
resulted in zero-length byte array being passed into the jni.  It's
now possible for the list to win the race and display old data, so a
better solution would be to check-out the file in such a way that the
list couldn't read it until it was update, but at least now we won't
crash.
This commit is contained in:
Andy2 2010-07-30 17:40:46 -07:00
parent d07d90761f
commit 13596f8538
2 changed files with 18 additions and 29 deletions

View file

@ -62,13 +62,13 @@ public class GameListAdapter extends XWListAdapter {
public Object getItem( int position )
{
String path = GameUtils.gamesList(m_context)[position];
final String path = GameUtils.gamesList(m_context)[position];
View layout = m_viewsCache.get( path );
if ( null == layout ) {
Utils.logf( "creating new list elem for %s", path );
layout = m_factory.inflate( m_layoutId, null );
byte[] stream = open( path );
byte[] stream = GameUtils.savedGame( m_context, path );
if ( null != stream ) {
CurGameInfo gi = new CurGameInfo( m_context );
XwJNI.gi_from_stream( gi, stream );
@ -103,24 +103,6 @@ public class GameListAdapter extends XWListAdapter {
return (View)getItem( position );
}
private byte[] open( String file )
{
byte[] stream = null;
try {
FileInputStream in = m_context.openFileInput( file );
int len = in.available();
stream = new byte[len];
in.read( stream, 0, len );
in.close();
} catch ( java.io.FileNotFoundException ex ) {
Utils.logf( "got FileNotFoundException: " + ex.toString() );
} catch ( java.io.IOException ex ) {
Utils.logf( "got IOException: " + ex.toString() );
}
return stream;
}
public void inval( String key )
{
m_viewsCache.remove( key );

View file

@ -31,15 +31,19 @@ import org.eehouse.android.xw4.jni.*;
public class GameUtils {
private static Object s_syncObj = new Object();
public static byte[] savedGame( Context context, String path )
{
byte[] stream = null;
try {
synchronized( s_syncObj ) {
FileInputStream in = context.openFileInput( path );
int len = in.available();
stream = new byte[len];
in.read( stream, 0, len );
in.close();
}
} catch ( java.io.FileNotFoundException fnf ) {
Utils.logf( fnf.toString() );
stream = null;
@ -109,6 +113,7 @@ public class GameUtils {
public static void deleteGame( Context context, String path )
{
// does this need to be synchronized?
context.deleteFile( path );
DBUtils.saveSummary( path, null );
}
@ -147,10 +152,12 @@ public class GameUtils {
public static void saveGame( Context context, byte[] bytes, String path )
{
try {
FileOutputStream out = context.openFileOutput( path,
Context.MODE_PRIVATE );
synchronized( s_syncObj ) {
FileOutputStream out =
context.openFileOutput( path, Context.MODE_PRIVATE );
out.write( bytes );
out.close();
}
} catch ( java.io.IOException ex ) {
Utils.logf( "got IOException: " + ex.toString() );
}