Adding a few more functions to nsIEventQueue.

Moving proxy to use nsIEventQueue instead of PLEvents direct.
This commit is contained in:
dougt%netscape.com 1999-05-29 22:50:25 +00:00
Родитель 3ed7309dab
Коммит 981c6e2d15
8 изменённых файлов: 154 добавлений и 50 удалений

Просмотреть файл

@ -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___ */