Adding a few more functions to nsIEventQueue.
Moving proxy to use nsIEventQueue instead of PLEvents direct.
This commit is contained in:
Родитель
3ed7309dab
Коммит
981c6e2d15
|
@ -23,6 +23,7 @@
|
|||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
#include "nsIEventQueue.h"
|
||||
#include "plevent.h"
|
||||
#include "xptcall.h"
|
||||
|
||||
|
@ -34,6 +35,23 @@ typedef enum
|
|||
|
||||
} ProxyType;
|
||||
|
||||
// WARNING about PROXY_ASYNC:
|
||||
//
|
||||
// If the calling thread goes away, any function which accesses the calling stack
|
||||
// will blow up.
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// myFoo->bar(&x)
|
||||
//
|
||||
// ... thread goes away ...
|
||||
//
|
||||
// bar(PRInt32 *x)
|
||||
// {
|
||||
// *x = 0; <----- You will blow up here.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Using the ISupports interface just for addrefing.
|
||||
|
@ -65,12 +83,12 @@ class nsProxyObject : public nsISupports
|
|||
|
||||
|
||||
nsISupports* GetRealObject() const { return mRealObject; }
|
||||
PLEventQueue* GetQueue() const { return mDestQueue; }
|
||||
nsIEventQueue* GetQueue() const { return mDestQueue; }
|
||||
ProxyType GetProxyType() const { return mProxyType; }
|
||||
|
||||
private:
|
||||
|
||||
PLEventQueue *mDestQueue; /* destination queue */
|
||||
nsIEventQueue *mDestQueue; /* destination queue */
|
||||
nsISupports *mRealObject; /* the non-proxy object that this event is referring to */
|
||||
|
||||
PRBool mRealObjectOwned;
|
||||
|
|
|
@ -50,9 +50,9 @@ nsProxyObjectCallInfo::~nsProxyObjectCallInfo()
|
|||
}
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
NS_IMPL_ISUPPORTS(nsProxyObject, kISupportsIID)
|
||||
|
||||
static NS_DEFINE_IID(kIEventQIID, NS_IEVENTQUEUE_IID);
|
||||
|
||||
nsProxyObject::nsProxyObject()
|
||||
{
|
||||
|
@ -73,10 +73,20 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, nsISu
|
|||
|
||||
mRealObjectOwned = PR_FALSE;
|
||||
mRealObject = realObject;
|
||||
mDestQueue = destQueue;
|
||||
mProxyType = proxyType;
|
||||
|
||||
mRealObject->AddRef();
|
||||
|
||||
nsresult rv = nsComponentManager::CreateInstance(NS_EVENTQUEUE_PROGID,
|
||||
nsnull,
|
||||
kIEventQIID,
|
||||
(void **)&mDestQueue);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
mDestQueue->InitFromPLQueue(destQueue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,7 +96,6 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, const
|
|||
NS_ADDREF_THIS();
|
||||
|
||||
mRealObjectOwned = PR_TRUE;
|
||||
mDestQueue = destQueue;
|
||||
mProxyType = proxyType;
|
||||
|
||||
nsresult rv = nsComponentManager::CreateInstance(aClass,
|
||||
|
@ -99,13 +108,25 @@ nsProxyObject::nsProxyObject(PLEventQueue *destQueue, ProxyType proxyType, const
|
|||
mRealObjectOwned = PR_FALSE;
|
||||
mRealObject = nsnull;
|
||||
}
|
||||
|
||||
rv = nsComponentManager::CreateInstance(NS_EVENTQUEUE_PROGID,
|
||||
nsnull,
|
||||
kIEventQIID,
|
||||
(void **)&mDestQueue);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
mDestQueue->InitFromPLQueue(destQueue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nsProxyObject::~nsProxyObject()
|
||||
{
|
||||
PL_ENTER_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
PL_RevokeEvents(mDestQueue, this);
|
||||
|
||||
if (mDestQueue)
|
||||
mDestQueue->EnterMonitor();
|
||||
// Shit! mDestQueue->RevokeEvents(this);
|
||||
|
||||
if(mRealObject != nsnull)
|
||||
{
|
||||
if (!mRealObjectOwned)
|
||||
|
@ -114,7 +135,11 @@ nsProxyObject::~nsProxyObject()
|
|||
NS_RELEASE(mRealObject);
|
||||
}
|
||||
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
if (mDestQueue)
|
||||
mDestQueue->ExitMonitor();
|
||||
|
||||
if (mDestQueue != nsnull)
|
||||
NS_RELEASE(mDestQueue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -123,7 +148,13 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to
|
|||
nsXPTCVariant *params)
|
||||
{
|
||||
|
||||
PL_ENTER_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
if (mDestQueue == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (mRealObject == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mDestQueue->EnterMonitor();
|
||||
|
||||
NS_ASSERTION(mRealObject, "no native object");
|
||||
|
||||
|
@ -133,7 +164,7 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to
|
|||
|
||||
if (event == nsnull)
|
||||
{
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
mDestQueue->ExitMonitor();
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -147,27 +178,22 @@ nsProxyObject::Post( PRUint32 methodIndex, /* which method to
|
|||
|
||||
if (mProxyType == PROXY_SYNC)
|
||||
{
|
||||
PL_PostSynchronousEvent(mDestQueue, event);
|
||||
mDestQueue->PostSynchronousEvent(event, nsnull);
|
||||
|
||||
nsresult rv = info->GetResult();
|
||||
|
||||
delete info;
|
||||
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
|
||||
mDestQueue->ExitMonitor();
|
||||
return rv;
|
||||
|
||||
}
|
||||
else if (mProxyType == PROXY_ASYNC)
|
||||
{
|
||||
PL_PostEvent(mDestQueue, event);
|
||||
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
|
||||
mDestQueue->PostEvent(event);
|
||||
mDestQueue->ExitMonitor();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mDestQueue);
|
||||
mDestQueue->ExitMonitor();
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
}
|
||||
|
@ -191,12 +217,17 @@ void* EventHandler(PLEvent *self)
|
|||
{
|
||||
nsProxyObjectCallInfo *info = (nsProxyObjectCallInfo*)PL_GetEventOwner(self);
|
||||
nsProxyObject *proxyObject = info->GetProxyObject();
|
||||
PLEventQueue *eventQ = proxyObject->GetQueue();
|
||||
nsIEventQueue *eventQ = proxyObject->GetQueue();
|
||||
|
||||
if (info != nsnull)
|
||||
{
|
||||
|
||||
PL_ENTER_EVENT_QUEUE_MONITOR(eventQ);
|
||||
if (eventQ == nsnull || proxyObject == nsnull)
|
||||
{
|
||||
info->SetResult(NS_ERROR_OUT_OF_MEMORY) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eventQ->EnterMonitor();
|
||||
|
||||
// invoke the magic of xptc...
|
||||
nsresult rv = XPTC_InvokeByIndex( proxyObject->GetRealObject(),
|
||||
|
@ -206,7 +237,7 @@ void* EventHandler(PLEvent *self)
|
|||
|
||||
info->SetResult(rv);
|
||||
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(eventQ);
|
||||
eventQ->ExitMonitor();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -201,13 +201,19 @@ nsProxyEventClass::CallQueryInterfaceOnProxy(nsProxyEventObject* self, REFNSIID
|
|||
|
||||
if (rv == NS_OK)
|
||||
{
|
||||
nsProxyEventObject* proxyObj = nsProxyEventObject::GetNewOrUsedProxy(self->GetQueue(), PROXY_SYNC, aInstancePtr, aIID);
|
||||
if(proxyObj)
|
||||
PLEventQueue* aEventQueue;
|
||||
|
||||
self->GetQueue()->GetPLEventQueue(&aEventQueue);
|
||||
|
||||
if (aEventQueue != nsnull)
|
||||
{
|
||||
return proxyObj;
|
||||
}
|
||||
}
|
||||
|
||||
nsProxyEventObject* proxyObj = nsProxyEventObject::GetNewOrUsedProxy(aEventQueue, PROXY_SYNC, aInstancePtr, aIID);
|
||||
if(proxyObj)
|
||||
{
|
||||
return proxyObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "plevent.h"
|
||||
#include "xptcall.h" // defines nsXPTCVariant
|
||||
#include "nsIEventQueue.h"
|
||||
|
||||
#include "nsProxyEvent.h"
|
||||
#include "nsProxyObjectManager.h"
|
||||
|
@ -88,8 +89,9 @@ public:
|
|||
REFNSIID aIID);
|
||||
|
||||
|
||||
PLEventQueue* GetQueue() const { return mProxyObject->GetQueue(); }
|
||||
|
||||
nsIEventQueue* GetQueue() const { return mProxyObject->GetQueue(); }
|
||||
nsIEventQueue* GetPLQueue() const { return mProxyObject->GetQueue(); }
|
||||
|
||||
REFNSIID GetIID() const {return GetClass()->GetIID();}
|
||||
nsProxyEventClass* GetClass() const { return mClass; }
|
||||
|
||||
|
|
|
@ -262,9 +262,9 @@ void TestCase_TwoClassesOneInterface(void *arg)
|
|||
PR_ASSERT(foo);
|
||||
PR_ASSERT(foo2);
|
||||
|
||||
proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo, PROXY_ASYNC, (void**)&proxyObject);
|
||||
proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo, PROXY_SYNC, (void**)&proxyObject);
|
||||
|
||||
proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo2, PROXY_ASYNC, (void**)&proxyObject2);
|
||||
proxyObjectFactory->GetProxyObject(argsStruct->queue, nsITestXPCFoo::GetIID(), foo2, PROXY_SYNC, (void**)&proxyObject2);
|
||||
|
||||
if (proxyObject && proxyObject2)
|
||||
{
|
||||
|
@ -305,7 +305,7 @@ void TestCase_TwoClassesOneInterface(void *arg)
|
|||
NS_RELEASE(proxyObject2);
|
||||
}
|
||||
|
||||
PR_Sleep( PR_MillisecondsToInterval(10000) );
|
||||
// PR_Sleep( PR_MillisecondsToInterval(10000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters
|
||||
}
|
||||
|
||||
|
||||
|
@ -410,7 +410,7 @@ main(int argc, char **argv)
|
|||
0 );
|
||||
|
||||
|
||||
PR_Sleep(PR_MillisecondsToInterval(5000));
|
||||
PR_Sleep(PR_MillisecondsToInterval(1000));
|
||||
|
||||
PR_ASSERT(gEventQueue); // BAD BAD BAD. EVENT THREAD DID NOT CREATE QUEUE. This may be a timing issue, set the
|
||||
// sleep about longer, and try again.
|
||||
|
|
|
@ -70,6 +70,41 @@ nsEventQueueImpl::PostSynchronousEvent(PLEvent* aEvent, void** aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventQueueImpl::EnterMonitor()
|
||||
{
|
||||
PL_ENTER_EVENT_QUEUE_MONITOR(mEventQueue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventQueueImpl::ExitMonitor()
|
||||
{
|
||||
PL_EXIT_EVENT_QUEUE_MONITOR(mEventQueue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventQueueImpl::RevokeEvents(void* owner)
|
||||
{
|
||||
PL_RevokeEvents(mEventQueue, owner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventQueueImpl::GetPLEventQueue(PLEventQueue** aEventQueue)
|
||||
{
|
||||
*aEventQueue = mEventQueue;
|
||||
|
||||
if (mEventQueue == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventQueueImpl::ProcessPendingEvents()
|
||||
{
|
||||
|
|
|
@ -25,30 +25,36 @@ static NS_DEFINE_IID(kIEventQueueIID, NS_IEVENTQUEUE_IID);
|
|||
class nsEventQueueImpl : public nsIEventQueue
|
||||
{
|
||||
public:
|
||||
nsEventQueueImpl();
|
||||
virtual ~nsEventQueueImpl();
|
||||
nsEventQueueImpl();
|
||||
virtual ~nsEventQueueImpl();
|
||||
|
||||
// nsISupports interface...
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEventQueue interface...
|
||||
NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent);
|
||||
NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult);
|
||||
|
||||
NS_IMETHOD ProcessPendingEvents();
|
||||
NS_IMETHOD ProcessPendingEvents();
|
||||
NS_IMETHOD EventLoop();
|
||||
|
||||
NS_IMETHOD EventAvailable(PRBool& aResult);
|
||||
NS_IMETHOD EventAvailable(PRBool& aResult);
|
||||
NS_IMETHOD GetEvent(PLEvent** aResult);
|
||||
|
||||
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD();
|
||||
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD();
|
||||
|
||||
NS_IMETHOD Init();
|
||||
NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue);
|
||||
|
||||
NS_IMETHOD EnterMonitor();
|
||||
NS_IMETHOD ExitMonitor();
|
||||
|
||||
NS_IMETHOD RevokeEvents(void* owner);
|
||||
|
||||
NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue);
|
||||
|
||||
// Helpers
|
||||
static NS_METHOD
|
||||
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
|
||||
|
||||
static const nsCID& CID() { static nsCID cid = NS_EVENTQUEUE_CID; return cid; }
|
||||
|
||||
|
|
|
@ -40,19 +40,25 @@ class nsIEventQueue : public nsISupports
|
|||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IEVENTQUEUE_IID; return iid;}
|
||||
|
||||
NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent) = 0;
|
||||
NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult) = 0;
|
||||
NS_IMETHOD_(PRStatus) PostEvent(PLEvent* aEvent) = 0;
|
||||
NS_IMETHOD PostSynchronousEvent(PLEvent* aEvent, void** aResult) = 0;
|
||||
|
||||
NS_IMETHOD ProcessPendingEvents() = 0;
|
||||
NS_IMETHOD EventLoop() = 0;
|
||||
NS_IMETHOD ProcessPendingEvents() = 0;
|
||||
NS_IMETHOD EventLoop() = 0;
|
||||
|
||||
NS_IMETHOD EventAvailable(PRBool& aResult) = 0;
|
||||
NS_IMETHOD GetEvent(PLEvent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD() = 0;
|
||||
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD() = 0;
|
||||
|
||||
NS_IMETHOD Init() = 0;
|
||||
NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue) = 0;
|
||||
|
||||
NS_IMETHOD EnterMonitor() = 0;
|
||||
NS_IMETHOD ExitMonitor() = 0;
|
||||
|
||||
NS_IMETHOD RevokeEvents(void* owner) = 0;
|
||||
NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIEventQueue_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче