зеркало из https://github.com/mozilla/pjs.git
[not part of build] Added pending exception support, to deal with problem of not being able to enter monitors with a pending exception in the JNIEnv.
This commit is contained in:
Родитель
0b905e50bf
Коммит
cab988a630
|
@ -152,6 +152,7 @@ static void netscape_oji_JNIThread_run(JNIEnv* env, jobject self)
|
||||||
JavaMessage* msg = requests.getMessage();
|
JavaMessage* msg = requests.getMessage();
|
||||||
if (msg != NULL) {
|
if (msg != NULL) {
|
||||||
msg->execute(env);
|
msg->execute(env);
|
||||||
|
secureEnv->savePendingException(env);
|
||||||
replies.putMessage(msg);
|
replies.putMessage(msg);
|
||||||
replies.notify();
|
replies.notify();
|
||||||
} else {
|
} else {
|
||||||
|
@ -354,7 +355,7 @@ CSecureEnv::CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv)
|
||||||
: SupportsMixin(this, sInterfaces, kInterfaceCount),
|
: SupportsMixin(this, sInterfaces, kInterfaceCount),
|
||||||
mPlugin(plugin), mProxyEnv(proxyEnv), mJavaEnv(javaEnv),
|
mPlugin(plugin), mProxyEnv(proxyEnv), mJavaEnv(javaEnv),
|
||||||
mSession(plugin->getSession()), mThreadManager(plugin->getThreadManager()),
|
mSession(plugin->getSession()), mThreadManager(plugin->getThreadManager()),
|
||||||
mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL)
|
mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL), mPendingException(NULL)
|
||||||
{
|
{
|
||||||
// need to create the JNIThread for communicating with Java.
|
// need to create the JNIThread for communicating with Java.
|
||||||
if (mJavaEnv != NULL)
|
if (mJavaEnv != NULL)
|
||||||
|
@ -1451,16 +1452,18 @@ NS_IMETHODIMP CSecureEnv::ThrowNew(/*[in]*/ jclass clazz,
|
||||||
|
|
||||||
|
|
||||||
class ExceptionOccurredMessage : public JavaMessage {
|
class ExceptionOccurredMessage : public JavaMessage {
|
||||||
|
CSecureEnv* secureEnv;
|
||||||
jthrowable* result;
|
jthrowable* result;
|
||||||
public:
|
public:
|
||||||
ExceptionOccurredMessage(jthrowable* result)
|
ExceptionOccurredMessage(CSecureEnv* secureEnv, jthrowable* result)
|
||||||
{
|
{
|
||||||
|
this->secureEnv = secureEnv;
|
||||||
this->result = result;
|
this->result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void execute(JNIEnv* env)
|
virtual void execute(JNIEnv* env)
|
||||||
{
|
{
|
||||||
*result = env->ExceptionOccurred();
|
*result = secureEnv->getPendingException(env);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1469,8 +1472,8 @@ NS_IMETHODIMP CSecureEnv::ExceptionOccurred(/*[out]*/ jthrowable* result)
|
||||||
if (mJavaEnv == NULL || result == NULL)
|
if (mJavaEnv == NULL || result == NULL)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
#if PROXY_JNI_CALLS
|
#if PROXY_JNI_CALLS
|
||||||
ExceptionOccurredMessage msg(result);
|
ExceptionOccurredMessage msg(this, result);
|
||||||
sendMessageToJava(&msg);
|
sendMessageToJava(&msg);
|
||||||
#else
|
#else
|
||||||
*result = mJavaEnv->ExceptionOccurred();
|
*result = mJavaEnv->ExceptionOccurred();
|
||||||
|
@ -1497,14 +1500,20 @@ NS_IMETHODIMP CSecureEnv::ExceptionDescribe(void)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ExceptionClearMessage : public JavaMessage {
|
||||||
|
CSecureEnv* secureEnv;
|
||||||
|
public:
|
||||||
|
ExceptionClearMessage(CSecureEnv* secureEnv)
|
||||||
|
{
|
||||||
|
this->secureEnv = secureEnv;
|
||||||
|
}
|
||||||
|
virtual void execute(JNIEnv* env) { secureEnv->clearPendingException(env); }
|
||||||
|
};
|
||||||
|
|
||||||
NS_IMETHODIMP CSecureEnv::ExceptionClear(void)
|
NS_IMETHODIMP CSecureEnv::ExceptionClear(void)
|
||||||
{
|
{
|
||||||
#if PROXY_JNI_CALLS
|
#if PROXY_JNI_CALLS
|
||||||
class ExceptionClearMessage : public JavaMessage {
|
ExceptionClearMessage msg(this);
|
||||||
public:
|
|
||||||
virtual void execute(JNIEnv* env) { env->ExceptionClear(); }
|
|
||||||
} msg;
|
|
||||||
sendMessageToJava(&msg);
|
sendMessageToJava(&msg);
|
||||||
#else
|
#else
|
||||||
mJavaEnv->ExceptionClear();
|
mJavaEnv->ExceptionClear();
|
||||||
|
@ -2920,6 +2929,36 @@ void CSecureEnv::messageLoop(JNIEnv* env, JavaMessage* msg, JavaMessageQueue* se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSecureEnv::savePendingException(JNIEnv* env)
|
||||||
|
{
|
||||||
|
// first off, always restore the env to a known state.
|
||||||
|
jthrowable pendingException = env->ExceptionOccurred();
|
||||||
|
env->ExceptionClear();
|
||||||
|
|
||||||
|
if (mPendingException)
|
||||||
|
env->DeleteGlobalRef(mPendingException);
|
||||||
|
|
||||||
|
if (pendingException) {
|
||||||
|
mPendingException = (jthrowable) env->NewGlobalRef(pendingException);
|
||||||
|
env->DeleteLocalRef(pendingException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jthrowable CSecureEnv::getPendingException(JNIEnv* env)
|
||||||
|
{
|
||||||
|
if (mPendingException)
|
||||||
|
return (jthrowable) env->NewLocalRef(mPendingException);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSecureEnv::clearPendingException(JNIEnv* env)
|
||||||
|
{
|
||||||
|
if (mPendingException) {
|
||||||
|
env->DeleteGlobalRef(mPendingException);
|
||||||
|
mPendingException = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSecureEnv* GetSecureJNI(JNIEnv* env, jobject thread)
|
CSecureEnv* GetSecureJNI(JNIEnv* env, jobject thread)
|
||||||
{
|
{
|
||||||
CSecureEnv* secureJNI = NULL;
|
CSecureEnv* secureJNI = NULL;
|
||||||
|
|
|
@ -35,9 +35,9 @@
|
||||||
* ----- END LICENSE BLOCK ----- */
|
* ----- END LICENSE BLOCK ----- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CSecureEnv.h
|
CSecureEnv.h
|
||||||
|
|
||||||
Rewritten for use with MRJ plugin by Patrick C. Beard.
|
Rewritten for use with MRJ plugin by Patrick C. Beard.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CSecureJNI2_h___
|
#ifndef CSecureJNI2_h___
|
||||||
|
@ -61,7 +61,7 @@ class CSecureEnv : public nsISecureEnv, public nsIRunnable, private SupportsMixi
|
||||||
public:
|
public:
|
||||||
DECL_SUPPORTS_MIXIN
|
DECL_SUPPORTS_MIXIN
|
||||||
|
|
||||||
static NS_METHOD Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr);
|
static NS_METHOD Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// from nsISecureJNI2:
|
// from nsISecureJNI2:
|
||||||
|
@ -302,7 +302,7 @@ public:
|
||||||
/*[out]*/ jsize* result);
|
/*[out]*/ jsize* result);
|
||||||
|
|
||||||
NS_IMETHOD NewObjectArray(/*[in]*/ jsize len,
|
NS_IMETHOD NewObjectArray(/*[in]*/ jsize len,
|
||||||
/*[in]*/ jclass clazz,
|
/*[in]*/ jclass clazz,
|
||||||
/*[in]*/ jobject init,
|
/*[in]*/ jobject init,
|
||||||
/*[out]*/ jobjectArray* result);
|
/*[out]*/ jobjectArray* result);
|
||||||
|
|
||||||
|
@ -365,49 +365,55 @@ public:
|
||||||
CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv = NULL);
|
CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv = NULL);
|
||||||
virtual ~CSecureEnv(void);
|
virtual ~CSecureEnv(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the native run method, to connect the
|
* Called by the native run method, to connect the
|
||||||
* thread and the secure env.
|
* thread and the secure env.
|
||||||
*/
|
*/
|
||||||
void initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue);
|
void initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue);
|
||||||
|
|
||||||
jboolean isInitialized() { return mJavaQueue != NULL; }
|
jboolean isInitialized() { return mJavaQueue != NULL; }
|
||||||
|
|
||||||
void setProxyEnv(JNIEnv* proxyEnv) { mProxyEnv = proxyEnv; }
|
void setProxyEnv(JNIEnv* proxyEnv) { mProxyEnv = proxyEnv; }
|
||||||
JNIEnv* getProxyEnv() { return mProxyEnv; }
|
JNIEnv* getProxyEnv() { return mProxyEnv; }
|
||||||
|
|
||||||
void setJavaEnv(JNIEnv* javaEnv) { mJavaEnv = javaEnv; }
|
void setJavaEnv(JNIEnv* javaEnv) { mJavaEnv = javaEnv; }
|
||||||
JNIEnv* getJavaEnv() { return mJavaEnv; }
|
JNIEnv* getJavaEnv() { return mJavaEnv; }
|
||||||
|
|
||||||
MRJSession* getSession() { return mSession; }
|
MRJSession* getSession() { return mSession; }
|
||||||
nsIThreadManager* getThreadManager() { return mThreadManager; }
|
nsIThreadManager* getThreadManager() { return mThreadManager; }
|
||||||
|
|
||||||
void getMessageQueues(JavaMessageQueue*& javaQueue, JavaMessageQueue*& nativeQueue)
|
void getMessageQueues(JavaMessageQueue*& javaQueue, JavaMessageQueue*& nativeQueue)
|
||||||
{
|
{
|
||||||
javaQueue = mJavaQueue;
|
javaQueue = mJavaQueue;
|
||||||
nativeQueue = mNativeQueue;
|
nativeQueue = mNativeQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessageToJava(JavaMessage* msg);
|
void sendMessageToJava(JavaMessage* msg);
|
||||||
void sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting = false);
|
void sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting = false);
|
||||||
void messageLoop(JNIEnv* env, JavaMessage* msgToSend, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting = false);
|
void messageLoop(JNIEnv* env, JavaMessage* msgToSend, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting = false);
|
||||||
|
|
||||||
|
void savePendingException(JNIEnv* env);
|
||||||
|
jthrowable getPendingException(JNIEnv* env);
|
||||||
|
void clearPendingException(JNIEnv* env);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
MRJPlugin* mPlugin;
|
MRJPlugin* mPlugin;
|
||||||
JNIEnv* mProxyEnv;
|
JNIEnv* mProxyEnv;
|
||||||
MRJSession* mSession;
|
MRJSession* mSession;
|
||||||
nsIThreadManager* mThreadManager;
|
nsIThreadManager* mThreadManager;
|
||||||
|
|
||||||
JNIEnv* mJavaEnv;
|
JNIEnv* mJavaEnv;
|
||||||
jboolean* mIsRunning;
|
jboolean* mIsRunning;
|
||||||
JavaMessageQueue* mJavaQueue;
|
JavaMessageQueue* mJavaQueue;
|
||||||
JavaMessageQueue* mNativeQueue;
|
JavaMessageQueue* mNativeQueue;
|
||||||
|
|
||||||
|
jthrowable mPendingException;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// support for SupportsMixin.
|
// support for SupportsMixin.
|
||||||
static const InterfaceInfo sInterfaces[];
|
static const InterfaceInfo sInterfaces[];
|
||||||
static const UInt32 kInterfaceCount;
|
static const UInt32 kInterfaceCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче