in the process of adding support for a protocol helper component which is responsible for dealing with modal requests from the network protocol handlers (which may be on different threads...)

This commit is contained in:
rpotts%netscape.com 1999-03-11 11:39:34 +00:00
Родитель 6c860be42e
Коммит 24d90e1d5d
2 изменённых файлов: 332 добавлений и 2 удалений

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

@ -18,17 +18,41 @@
*/
#include "nsIFactory.h"
#include "nscore.h"
#include "nsIComponentManager.h"
#include "nsAppShellCIDs.h"
#include "nsICmdLineService.h"
/* extern the factory entry points... */
nsresult NS_NewAppShellServiceFactory(nsIFactory** aFactory);
#if 0
nsresult NS_NewDefaultProtocolHelperFactory(nsIFactory** aResult);
#endif
static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
static NS_DEFINE_IID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
static NS_DEFINE_IID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
static NS_DEFINE_IID(kProtocolHelperCID, NS_PROTOCOL_HELPER_CID);
extern "C" NS_EXPORT nsresult
NSRegisterSelf(nsISupports* serviceMgr, const char *path)
{
nsComponentManager::RegisterComponent(kAppShellServiceCID, NULL, NULL, path, PR_TRUE, PR_TRUE);
nsComponentManager::RegisterComponent(kCmdLineServiceCID, NULL, NULL, path, PR_TRUE, PR_TRUE);
nsComponentManager::RegisterComponent(kProtocolHelperCID, NULL, NULL, path, PR_TRUE, PR_TRUE);
return NS_OK;
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(nsISupports* serviceMgr, const char *path)
{
nsComponentManager::UnregisterFactory(kAppShellServiceCID, path);
nsComponentManager::UnregisterFactory(kCmdLineServiceCID, path);
nsComponentManager::UnregisterFactory(kProtocolHelperCID, path);
return NS_OK;
}
#if defined(XP_MAC) && defined(MAC_STATIC)
extern "C" NS_APPSHELL nsresult
NSGetFactory_APPSHELL_DLL(nsISupports* serviceMgr,
@ -57,6 +81,12 @@ NSGetFactory(nsISupports* serviceMgr,
else if (aClass.Equals(kCmdLineServiceCID)) {
rv = NS_NewCmdLineServiceFactory(aFactory);
}
#if 0
else if (aClass.Equals(kProtocolHelperCID)) {
rv = NS_NewDefaultProtocolHelperFactory(aFactory);
}
#endif
return rv;
}

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

@ -0,0 +1,300 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIBlockingNotification.h"
#include "nsIURL.h"
#include "nsIEventQueueService.h"
#include "nsIServiceManager.h"
#include "nsXPComFactory.h"
#include "nsXPComCIID.h"
// Class IDs...
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
// Interface IDs...
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
static NS_DEFINE_IID(kIBlockingNotificationObserverIID,
NS_IBLOCKINGNOTIFICATION_OBSERVER_IID);
// Forward declarations...
class nsDefaultProtocolHelper;
/*-------------------- Notification Event Class ----------------------------*/
struct NotificationEvent : public PLEvent
{
NotificationEvent(nsDefaultProtocolHelper *aSelf,
nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRInt32 aCode,
nsISupports *aExtraInfo);
~NotificationEvent();
PRStatus Fire(PLEventQueue* aEventQ);
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
nsDefaultProtocolHelper *mSelf;
nsIBlockingNotification *mCaller;
nsIURL *mUrl;
PRInt32 mCode;
nsISupports *mExtraInfo;
};
/*----------------------------- nsDefaultProtocolHelper ---------------------*/
class nsDefaultProtocolHelper : public nsIBlockingNotificationObserver
{
public:
nsDefaultProtocolHelper();
/* nsISupports interface... */
NS_DECL_ISUPPORTS
/* nsIBlockingNotificationObserver interface... */
NS_IMETHOD Notify(nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRThread *aThread,
PRInt32 aCode,
nsISupports *aExtraInfo);
NS_IMETHOD CancelNotify(nsIURL *aUrl);
/* class methods... */
nsresult HandleNotification(nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRInt32 aCode,
nsISupports *aExtraInfo);
protected:
virtual ~nsDefaultProtocolHelper();
private:
nsIEventQueueService *mEventQService;
};
nsDefaultProtocolHelper::nsDefaultProtocolHelper()
{
NS_INIT_REFCNT();
/*
* Cache the EventQueue service...
*
* Ignore failure since there is nothing that can be done...
* Instead, all of the code that uses mEventQService *must*
* check that it was initialized...
*/
(void) nsServiceManager::GetService(kEventQueueServiceCID,
kIEventQueueServiceIID,
(nsISupports **)&mEventQService);
}
nsDefaultProtocolHelper::~nsDefaultProtocolHelper()
{
if (mEventQService) {
nsServiceManager::ReleaseService(kEventQueueServiceCID, mEventQService);
mEventQService = nsnull;
}
}
/*
* Implementations of nsISupports interface methods...
*/
NS_IMPL_ADDREF(nsDefaultProtocolHelper);
NS_IMPL_RELEASE(nsDefaultProtocolHelper);
NS_IMPL_QUERY_INTERFACE(nsDefaultProtocolHelper, kIBlockingNotificationObserverIID);
/*
* Implementations of nsIBlockingNotificationObserver interface methods...
*/
NS_IMETHODIMP
nsDefaultProtocolHelper::Notify(nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRThread *aThread,
PRInt32 aCode,
nsISupports *aExtraInfo)
{
nsresult rv;
NotificationEvent *ev;
/*
* Initialize the return code to indicate that the notification was not
* processed synchronously...
*/
rv = NS_NOTIFY_BLOCKED;
/*
* If no thread switch is necessary, then handle the notification
* immediately...
*/
if (PR_GetCurrentThread() == aThread) {
rv = HandleNotification(aCaller, aUrl, aCode, aExtraInfo);
}
else {
/*
* Post a message to the appropriate thread event queue to
* handle the notification...
*/
PLEventQueue *evQ = nsnull;
/* locate the event queue for the thread... */
if (mEventQService) {
mEventQService->GetThreadEventQueue(aThread, &evQ);
}
/* Create and dispatch the notification event... */
if (evQ) {
ev = new NotificationEvent(this, aCaller, aUrl, aCode, aExtraInfo);
if (ev) {
PRStatus status;
/* dispatch the event into the appropriate event queue... */
status = ev->Fire(evQ);
if (PR_SUCCESS != status) {
/* If the event was not dispatched, then clean up... */
NotificationEvent::DestroyPLEvent(ev);
rv = NS_ERROR_FAILURE;
}
}
else {
/* allocation of the Notification event failed... */
rv = NS_ERROR_OUT_OF_MEMORY;
}
} else {
/* No event queue was found! */
NS_ASSERTION(0, "No Event Queue is available!");
rv = NS_ERROR_FAILURE;
}
}
return rv;
}
NS_IMETHODIMP
nsDefaultProtocolHelper::CancelNotify(nsIURL *aUrl)
{
/* XXX: does not support interrupting a notification yet... */
return NS_ERROR_FAILURE;
}
nsresult nsDefaultProtocolHelper::HandleNotification(nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRInt32 aCode,
nsISupports *aExtraInfo)
{
return NS_NOTIFY_BLOCKED;
}
/*-------------------- Notification Event Class ----------------------------*/
NotificationEvent::NotificationEvent(nsDefaultProtocolHelper *aSelf,
nsIBlockingNotification *aCaller,
nsIURL *aUrl,
PRInt32 aCode,
nsISupports *aExtraInfo)
{
mSelf = aSelf;
mCaller = aCaller;
mUrl = aUrl;
mCode = aCode;
mExtraInfo = aExtraInfo;
NS_IF_ADDREF(mSelf);
NS_IF_ADDREF(mCaller);
NS_IF_ADDREF(mUrl);
NS_IF_ADDREF(mExtraInfo);
}
NotificationEvent::~NotificationEvent()
{
NS_IF_RELEASE(mSelf);
NS_IF_RELEASE(mCaller);
NS_IF_RELEASE(mUrl);
NS_IF_RELEASE(mExtraInfo);
}
void PR_CALLBACK NotificationEvent::HandlePLEvent(PLEvent* aEvent)
{
NotificationEvent *ev = (NotificationEvent*)aEvent;
(void)ev->mSelf->HandleNotification(ev->mCaller, ev->mUrl, ev->mCode,
ev->mExtraInfo);
}
void PR_CALLBACK NotificationEvent::DestroyPLEvent(PLEvent* aEvent)
{
NotificationEvent *ev = (NotificationEvent*)aEvent;
delete ev;
}
PRStatus NotificationEvent::Fire(PLEventQueue* aEventQ)
{
PRStatus status;
PL_InitEvent(this, nsnull,
(PLHandleEventProc) NotificationEvent::HandlePLEvent,
(PLDestroyEventProc) NotificationEvent::DestroyPLEvent);
status = PL_PostEvent(aEventQ, this);
return status;
}
//----------------------------------------------------------------------
// Entry point to create nsAppShellService factory instances...
NS_DEF_FACTORY(DefaultProtocolHelper,nsDefaultProtocolHelper)
nsresult NS_NewDefaultProtocolHelperFactory(nsIFactory** aResult)
{
nsresult rv = NS_OK;
nsIFactory* inst;
inst = new nsDefaultProtocolHelperFactory;
if (nsnull == inst) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
else {
NS_ADDREF(inst);
}
*aResult = inst;
return rv;
}