[Android] Fix a race condition within the MediaLibrary
Ludovic Fauvet
git at videolan.org
Fri May 17 17:11:01 CEST 2013
vlc-ports/android | branch: master | Ludovic Fauvet <etix at videolan.org> | Fri May 17 17:05:38 2013 +0200| [b58bc7bdf52790118c9eb0d9c7a6dc77c7f630ee] | committer: Ludovic Fauvet
Fix a race condition within the MediaLibrary
Concurrent read/write access to the item list can cause an
IndexOutOfBoundsException.
> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=b58bc7bdf52790118c9eb0d9c7a6dc77c7f630ee
---
vlc-android/src/org/videolan/vlc/MediaLibrary.java | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
index 8a40ccc..0bcdef2 100644
--- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java
+++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
@@ -29,6 +29,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Stack;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.videolan.libvlc.LibVLC;
import org.videolan.vlc.gui.MainActivity;
@@ -49,6 +51,7 @@ public class MediaLibrary {
private static MediaLibrary mInstance;
private final ArrayList<Media> mItemList;
private final ArrayList<Handler> mUpdateHandler;
+ private final ReadWriteLock mItemListLock;
private boolean isStopping = false;
private boolean mRestart = false;
private Context mRestartContext;
@@ -58,6 +61,7 @@ public class MediaLibrary {
mInstance = this;
mItemList = new ArrayList<Media>();
mUpdateHandler = new ArrayList<Handler>();
+ mItemListLock = new ReentrantReadWriteLock();
}
public void loadMediaItems(Context context, boolean restart) {
@@ -109,28 +113,33 @@ public class MediaLibrary {
public ArrayList<Media> getVideoItems() {
ArrayList<Media> videoItems = new ArrayList<Media>();
+ mItemListLock.readLock().lock();
for (int i = 0; i < mItemList.size(); i++) {
Media item = mItemList.get(i);
if (item != null && item.getType() == Media.TYPE_VIDEO) {
videoItems.add(item);
}
}
+ mItemListLock.readLock().unlock();
return videoItems;
}
public ArrayList<Media> getAudioItems() {
ArrayList<Media> audioItems = new ArrayList<Media>();
+ mItemListLock.readLock().lock();
for (int i = 0; i < mItemList.size(); i++) {
Media item = mItemList.get(i);
if (item.getType() == Media.TYPE_AUDIO) {
audioItems.add(item);
}
}
+ mItemListLock.readLock().unlock();
return audioItems;
}
public ArrayList<Media> getAudioItems(String name, String name2, int mode) {
ArrayList<Media> audioItems = new ArrayList<Media>();
+ mItemListLock.readLock().lock();
for (int i = 0; i < mItemList.size(); i++) {
Media item = mItemList.get(i);
if (item.getType() == Media.TYPE_AUDIO) {
@@ -154,6 +163,7 @@ public class MediaLibrary {
}
}
+ mItemListLock.readLock().unlock();
return audioItems;
}
@@ -162,12 +172,15 @@ public class MediaLibrary {
}
public Media getMediaItem(String location) {
+ mItemListLock.readLock().lock();
for (int i = 0; i < mItemList.size(); i++) {
Media item = mItemList.get(i);
if (item.getLocation().equals(location)) {
+ mItemListLock.readLock().unlock();
return item;
}
}
+ mItemListLock.readLock().unlock();
return null;
}
@@ -217,7 +230,9 @@ public class MediaLibrary {
HashSet<String> addedLocations = new HashSet<String>();
// clear all old items
+ mItemListLock.writeLock().lock();
mItemList.clear();
+ mItemListLock.writeLock().unlock();
MediaItemFilter mediaFileFilter = new MediaItemFilter();
@@ -286,13 +301,17 @@ public class MediaLibrary {
* user select an subfolder as well
*/
if (!addedLocations.contains(fileURI)) {
+ mItemListLock.writeLock().lock();
// get existing media item from database
mItemList.add(existingMedias.get(fileURI));
+ mItemListLock.writeLock().unlock();
addedLocations.add(fileURI);
}
} else {
+ mItemListLock.writeLock().lock();
// create new media item
mItemList.add(new Media(fileURI, true));
+ mItemListLock.writeLock().unlock();
}
if (isStopping) {
Log.d(TAG, "Stopping scan");
More information about the Android
mailing list