summaryrefslogtreecommitdiffstats
path: root/media/jni
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-08-03 15:17:55 -0400
committerMike Lockwood <lockwood@android.com>2010-08-03 15:35:38 -0400
commit23ee42f904ad6ba4e3d3d569ffd49f4f7d174e1e (patch)
treed0a1faef3eadc83e3c8f92b22ae3584db3a585d6 /media/jni
parentd4b502017416113ce50112787ab9fcae39649806 (diff)
downloadframeworks_base-23ee42f904ad6ba4e3d3d569ffd49f4f7d174e1e.zip
frameworks_base-23ee42f904ad6ba4e3d3d569ffd49f4f7d174e1e.tar.gz
frameworks_base-23ee42f904ad6ba4e3d3d569ffd49f4f7d174e1e.tar.bz2
MTP: Fix some thread safety issues in MTP server start/stop sequence.
Change-Id: Ied1cddc6220fa7394e8de99df9bc37a1208b04ff Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'media/jni')
-rw-r--r--media/jni/android_media_MtpServer.cpp94
1 files changed, 56 insertions, 38 deletions
diff --git a/media/jni/android_media_MtpServer.cpp b/media/jni/android_media_MtpServer.cpp
index eddad57..1ef2c58 100644
--- a/media/jni/android_media_MtpServer.cpp
+++ b/media/jni/android_media_MtpServer.cpp
@@ -36,6 +36,7 @@ using namespace android;
// ----------------------------------------------------------------------------
static jfieldID field_context;
+static Mutex sMutex;
// in android_media_MtpDatabase.cpp
extern MtpDatabase* getMtpDatabase(JNIEnv *env, jobject database);
@@ -53,63 +54,80 @@ class MtpThread : public Thread {
private:
MtpDatabase* mDatabase;
MtpServer* mServer;
- String8 mStoragePath;
- bool mDone;
- Mutex mMutex;
+ String8 mStoragePath;
+ bool mDone;
+ jobject mJavaServer;
public:
- MtpThread(MtpDatabase* database, const char* storagePath)
- : mDatabase(database), mServer(NULL), mStoragePath(storagePath), mDone(false)
+ MtpThread(MtpDatabase* database, const char* storagePath, jobject javaServer)
+ : mDatabase(database),
+ mServer(NULL),
+ mStoragePath(storagePath),
+ mDone(false),
+ mJavaServer(javaServer)
{
}
virtual bool threadLoop() {
- int fd = open("/dev/mtp_usb", O_RDWR);
- printf("open returned %d\n", fd);
- if (fd < 0) {
- LOGE("could not open MTP driver\n");
- return false;
+ while (1) {
+ int fd = open("/dev/mtp_usb", O_RDWR);
+ printf("open returned %d\n", fd);
+ if (fd < 0) {
+ LOGE("could not open MTP driver\n");
+ break;
+ }
+
+ sMutex.lock();
+ mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
+ mServer->addStorage(mStoragePath);
+ sMutex.unlock();
+
+ LOGD("MtpThread mServer->run");
+ mServer->run();
+ close(fd);
+
+ sMutex.lock();
+ delete mServer;
+ mServer = NULL;
+ if (mDone)
+ goto done;
+ sMutex.unlock();
+ // wait a bit before retrying
+ sleep(1);
}
- mMutex.lock();
- mServer = new MtpServer(fd, mDatabase, AID_SDCARD_RW, 0664, 0775);
- mServer->addStorage(mStoragePath);
- mMutex.unlock();
-
- LOGD("MtpThread mServer->run");
- mServer->run();
- close(fd);
-
- mMutex.lock();
- delete mServer;
- mServer = NULL;
- mMutex.unlock();
-
- bool done = mDone;
- if (done)
- delete this;
- LOGD("threadLoop returning %s", (done ? "false" : "true"));
- return !done;
+ sMutex.lock();
+done:
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->SetIntField(mJavaServer, field_context, 0);
+ env->DeleteGlobalRef(mJavaServer);
+ sMutex.unlock();
+
+ LOGD("threadLoop returning");
+ return false;
}
- void setDone() { mDone = true; }
+ void setDone() {
+ LOGD("setDone");
+ mDone = true;
+ }
void sendObjectAdded(MtpObjectHandle handle) {
- mMutex.lock();
+ sMutex.lock();
if (mServer)
mServer->sendObjectAdded(handle);
else
LOGE("sendObjectAdded called while disconnected\n");
- mMutex.unlock();
+ sMutex.unlock();
}
void sendObjectRemoved(MtpObjectHandle handle) {
- mMutex.lock();
+ sMutex.lock();
if (mServer)
mServer->sendObjectRemoved(handle);
else
LOGE("sendObjectRemoved called while disconnected\n");
- mMutex.unlock();
+ sMutex.unlock();
}
};
@@ -124,7 +142,7 @@ android_media_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, j
MtpDatabase* database = getMtpDatabase(env, javaDatabase);
const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL);
- MtpThread* thread = new MtpThread(database, storagePathStr);
+ MtpThread* thread = new MtpThread(database, storagePathStr, env->NewGlobalRef(thiz));
env->SetIntField(thiz, field_context, (int)thread);
env->ReleaseStringUTFChars(storagePath, storagePathStr);
@@ -153,11 +171,11 @@ android_media_MtpServer_stop(JNIEnv *env, jobject thiz)
{
#ifdef HAVE_ANDROID_OS
LOGD("stop\n");
+ sMutex.lock();
MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
- if (thread) {
+ if (thread)
thread->setDone();
- env->SetIntField(thiz, field_context, 0);
- }
+ sMutex.unlock();
#endif
}