зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1343027 - 2. Add jni::Ref::Lock function; r=snorp
Add a Lock function to jni::Ref to lock the referenced object akin to the synchronized keyword in Java. It returns an AutoLock RAII object that automatically unlocks the object when going out of scope.
This commit is contained in:
Родитель
0d3d8e6fd1
Коммит
3a24d6364c
|
@ -79,6 +79,45 @@ protected:
|
|||
public:
|
||||
using JNIType = Type;
|
||||
|
||||
class AutoLock
|
||||
{
|
||||
friend class Ref<Cls, Type>;
|
||||
|
||||
JNIEnv* const mEnv;
|
||||
Type mInstance;
|
||||
|
||||
AutoLock(Type aInstance)
|
||||
: mEnv(FindEnv())
|
||||
, mInstance(mEnv->NewLocalRef(aInstance))
|
||||
{
|
||||
mEnv->MonitorEnter(mInstance);
|
||||
MOZ_CATCH_JNI_EXCEPTION(mEnv);
|
||||
}
|
||||
|
||||
public:
|
||||
AutoLock(AutoLock&& aOther)
|
||||
: mEnv(aOther.mEnv)
|
||||
, mInstance(aOther.mInstance)
|
||||
{
|
||||
aOther.mInstance = nullptr;
|
||||
}
|
||||
|
||||
~AutoLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if (mInstance) {
|
||||
mEnv->MonitorExit(mInstance);
|
||||
mEnv->DeleteLocalRef(mInstance);
|
||||
MOZ_CATCH_JNI_EXCEPTION(mEnv);
|
||||
mInstance = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Construct a Ref form a raw JNI reference.
|
||||
static Ref<Cls, Type> From(JNIType obj)
|
||||
{
|
||||
|
@ -117,6 +156,11 @@ public:
|
|||
return T::Ref::From(*this);
|
||||
}
|
||||
|
||||
AutoLock Lock() const
|
||||
{
|
||||
return AutoLock(mInstance);
|
||||
}
|
||||
|
||||
bool operator==(const Ref& other) const
|
||||
{
|
||||
// Treat two references of the same object as being the same.
|
||||
|
|
|
@ -784,12 +784,9 @@ nsWindow::AndroidView::GetSettings(JSContext* aCx, JS::MutableHandleValue aOut)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
JNIEnv* const env = jni::GetGeckoThreadEnv();
|
||||
env->MonitorEnter(mSettings.Get());
|
||||
nsresult rv = widget::EventDispatcher::UnboxBundle(aCx, mSettings, aOut);
|
||||
env->MonitorExit(mSettings.Get());
|
||||
|
||||
return rv;
|
||||
// Lock to prevent races with UI thread.
|
||||
auto lock = mSettings.Lock();
|
||||
return widget::EventDispatcher::UnboxBundle(aCx, mSettings, aOut);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче