mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-18 22:26:30 +01:00
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:
parent
d07d90761f
commit
13596f8538
2 changed files with 18 additions and 29 deletions
|
@ -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 );
|
||||
|
|
|
@ -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 {
|
||||
FileInputStream in = context.openFileInput( path );
|
||||
int len = in.available();
|
||||
stream = new byte[len];
|
||||
in.read( stream, 0, len );
|
||||
in.close();
|
||||
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 );
|
||||
out.write( bytes );
|
||||
out.close();
|
||||
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() );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue