зеркало из https://github.com/mozilla/gecko-dev.git
Added test for service manager.
This commit is contained in:
Родитель
50e8b8e476
Коммит
32f5a442c5
|
@ -0,0 +1,220 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* 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 "MyService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static NS_DEFINE_IID(kIMyServiceCID, NS_IMYSERVICE_CID);
|
||||
static NS_DEFINE_IID(kIMyServiceIID, NS_IMYSERVICE_IID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IMyService* myServ = NULL;
|
||||
|
||||
nsresult
|
||||
BeginTest(int testNumber, nsIShutdownListener* listener)
|
||||
{
|
||||
nsresult err;
|
||||
NS_ASSERTION(myServ == NULL, "myServ not reset");
|
||||
err = NSServiceManager::GetService(kIMyServiceCID, kIMyServiceIID,
|
||||
(nsISupports**)&myServ, listener);
|
||||
return err;
|
||||
}
|
||||
|
||||
nsresult
|
||||
EndTest(int testNumber, nsIShutdownListener* listener)
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
|
||||
if (myServ) {
|
||||
err = myServ->Doit();
|
||||
if (err != NS_OK) return err;
|
||||
|
||||
err = NSServiceManager::ReleaseService(kIMyServiceCID, myServ, listener);
|
||||
if (err != NS_OK) return err;
|
||||
myServ = NULL;
|
||||
}
|
||||
|
||||
printf("test %d succeeded\n", testNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SimpleTest(int testNumber)
|
||||
{
|
||||
// This test just gets a service, uses it and releases it.
|
||||
|
||||
nsresult err;
|
||||
err = BeginTest(testNumber, NULL);
|
||||
if (err != NS_OK) return err;
|
||||
err = EndTest(testNumber, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class HandleMyServiceShutdown : public nsIShutdownListener {
|
||||
public:
|
||||
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
|
||||
HandleMyServiceShutdown(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleMyServiceShutdown(void) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
|
||||
NS_IMPL_ISUPPORTS(HandleMyServiceShutdown, kIShutdownListenerIID);
|
||||
|
||||
nsresult
|
||||
HandleMyServiceShutdown::OnShutdown(const nsCID& cid, nsISupports* service)
|
||||
{
|
||||
if (cid.Equals(kIMyServiceCID)) {
|
||||
NS_ASSERTION(service == myServ, "wrong service!");
|
||||
nsrefcnt cnt = myServ->Release();
|
||||
myServ = NULL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AsyncShutdown(int testNumber)
|
||||
{
|
||||
nsresult err;
|
||||
|
||||
// If the AsyncShutdown was truly asynchronous and happened on another
|
||||
// thread, we'd have to protect all accesses to myServ throughout this
|
||||
// code with a monitor.
|
||||
|
||||
err = NSServiceManager::ShutdownService(kIMyServiceCID);
|
||||
if (err == NS_ERROR_SERVICE_IN_USE) {
|
||||
printf("async shutdown -- service still in use\n");
|
||||
return NS_OK;
|
||||
}
|
||||
if (err == NS_ERROR_SERVICE_NOT_FOUND) {
|
||||
printf("async shutdown -- service not found\n");
|
||||
return NS_OK;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AsyncShutdownTest(int testNumber)
|
||||
{
|
||||
// This test gets a service, but then gets an async request for
|
||||
// shutdown before it gets a chance to use it. This causes the myServ
|
||||
// variable to become NULL and EndTest to do nothing. The async request
|
||||
// will actually unload the DLL in this test.
|
||||
|
||||
nsresult err;
|
||||
HandleMyServiceShutdown* listener = new HandleMyServiceShutdown();
|
||||
listener->AddRef();
|
||||
|
||||
err = BeginTest(testNumber, listener);
|
||||
if (err != NS_OK) return err;
|
||||
err = AsyncShutdown(testNumber);
|
||||
if (err != NS_OK) return err;
|
||||
err = EndTest(testNumber, listener);
|
||||
|
||||
nsrefcnt cnt = listener->Release();
|
||||
NS_ASSERTION(cnt == 0, "failed to release listener");
|
||||
return err;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AsyncNoShutdownTest(int testNumber)
|
||||
{
|
||||
// This test gets a service, and also gets an async request for shutdown,
|
||||
// but the service doesn't get shut down because some other client (who's
|
||||
// not participating in the async shutdown game as he should) is
|
||||
// continuing to hang onto the service. This causes myServ variable to
|
||||
// get set to NULL, but the service doesn't get unloaded right away as
|
||||
// it should.
|
||||
|
||||
nsresult err;
|
||||
HandleMyServiceShutdown* listener = new HandleMyServiceShutdown();
|
||||
listener->AddRef();
|
||||
|
||||
err = BeginTest(testNumber, listener);
|
||||
if (err != NS_OK) return err;
|
||||
|
||||
// Create some other user of kIMyServiceCID, preventing it from
|
||||
// really going away:
|
||||
IMyService* otherClient;
|
||||
err = NSServiceManager::GetService(kIMyServiceCID, kIMyServiceIID,
|
||||
(nsISupports**)&otherClient);
|
||||
if (err != NS_OK) return err;
|
||||
|
||||
err = AsyncShutdown(testNumber);
|
||||
if (err != NS_OK) return err;
|
||||
err = EndTest(testNumber, listener);
|
||||
|
||||
// Finally, release the other client.
|
||||
err = NSServiceManager::ReleaseService(kIMyServiceCID, otherClient);
|
||||
if (err != NS_OK) return err;
|
||||
|
||||
nsrefcnt cnt = listener->Release();
|
||||
NS_ASSERTION(cnt == 0, "failed to release listener");
|
||||
return err;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
SetupFactories(void)
|
||||
{
|
||||
nsresult err;
|
||||
// seed the repository (hack)
|
||||
err = NSRepository::RegisterFactory(kIMyServiceCID, "MyService.dll",
|
||||
PR_TRUE, PR_FALSE);
|
||||
NS_ASSERTION(err == NS_OK, "failed to register my factory");
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
nsresult err;
|
||||
int testNumber = 0;
|
||||
|
||||
SetupFactories();
|
||||
|
||||
err = SimpleTest(++testNumber);
|
||||
if (err != NS_OK)
|
||||
goto error;
|
||||
|
||||
err = AsyncShutdownTest(++testNumber);
|
||||
if (err != NS_OK)
|
||||
goto error;
|
||||
|
||||
err = AsyncNoShutdownTest(++testNumber);
|
||||
if (err != NS_OK)
|
||||
goto error;
|
||||
|
||||
AsyncShutdown(++testNumber);
|
||||
|
||||
printf("there was great success\n");
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf("test %d failed\n", testNumber);
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -19,20 +19,21 @@ DEPTH=..\..
|
|||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
DIRS = dynamic windows
|
||||
DIRS = dynamic windows services
|
||||
|
||||
MAKE_OBJ_TYPE = EXE
|
||||
PROG1 = .\$(OBJDIR)\TestFactory.exe
|
||||
PROG2 = .\$(OBJDIR)\RegFactory.exe
|
||||
PROG3 = .\$(OBJDIR)\TestArray.exe
|
||||
PROG4 = .\$(OBJDIR)\TestID.exe
|
||||
PROGRAMS = $(PROG1) $(PROG2) $(PROG3) $(PROG4)
|
||||
PROG5 = .\$(OBJDIR)\TestServMgr.exe
|
||||
PROGRAMS = $(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5)
|
||||
|
||||
LCFLAGS=-DUSE_NSREG
|
||||
|
||||
REQUIRES=libreg
|
||||
|
||||
LINCS=-I..\src
|
||||
LINCS=-I..\src -Iservices
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
|
@ -69,5 +70,6 @@ clobber::
|
|||
$(PROG1): $(OBJDIR) TestFactory.cpp
|
||||
$(PROG2): $(OBJDIR) RegFactory.cpp
|
||||
$(PROG3): $(OBJDIR) TestArray.cpp
|
||||
$(PROG3): $(OBJDIR) TestID.cpp
|
||||
$(PROG4): $(OBJDIR) TestID.cpp
|
||||
$(PROG5): $(OBJDIR) TestServMgr.cpp
|
||||
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* 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 "MyService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <stdio.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class MyService : public IMyService {
|
||||
public:
|
||||
|
||||
NS_IMETHOD
|
||||
Doit(void);
|
||||
|
||||
MyService(nsISupports* outer);
|
||||
virtual ~MyService(void);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class MyServiceFactory : public nsIFactory {
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFactory methods:
|
||||
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult);
|
||||
|
||||
NS_IMETHOD LockFactory(PRBool aLock);
|
||||
|
||||
// MyService methods:
|
||||
|
||||
MyServiceFactory(void);
|
||||
virtual ~MyServiceFactory(void);
|
||||
|
||||
PRBool CanUnload(void) { return mOutstandingInstances == 0; }
|
||||
|
||||
friend MyService;
|
||||
|
||||
protected:
|
||||
PRBool mStarted;
|
||||
PRUint32 mOutstandingInstances;
|
||||
};
|
||||
|
||||
MyServiceFactory* gFact = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// MyService Implementation
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIMyServiceIID, NS_IMYSERVICE_IID);
|
||||
NS_IMPL_ISUPPORTS(MyService, kIMyServiceIID);
|
||||
|
||||
MyService::MyService(nsISupports* outer)
|
||||
{
|
||||
NS_INIT_REFCNT(outer);
|
||||
// incrementing this will keep our factory from getting unloaded
|
||||
gFact->mOutstandingInstances++;
|
||||
printf(" creating my service\n");
|
||||
}
|
||||
|
||||
MyService::~MyService(void)
|
||||
{
|
||||
// decrementing this will allow our factory to get unloaded
|
||||
--gFact->mOutstandingInstances;
|
||||
printf(" destroying my service\n");
|
||||
}
|
||||
|
||||
nsresult
|
||||
MyService::Doit(void)
|
||||
{
|
||||
printf(" invoking my service\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// MyServiceFactory Implementation
|
||||
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
NS_IMPL_ISUPPORTS(MyServiceFactory, kIFactoryIID);
|
||||
|
||||
MyServiceFactory::MyServiceFactory(void)
|
||||
: mStarted(PR_FALSE), mOutstandingInstances(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
printf("initializing my service factory\n");
|
||||
}
|
||||
|
||||
MyServiceFactory::~MyServiceFactory(void)
|
||||
{
|
||||
NS_ASSERTION(mOutstandingInstances == 0, "unloading factory when there are still instances");
|
||||
printf("finalizing my service factory\n");
|
||||
}
|
||||
|
||||
nsresult
|
||||
MyServiceFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
MyService* serv = new MyService(aOuter);
|
||||
if (serv == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return serv->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
MyServiceFactory::LockFactory(PRBool aLock)
|
||||
{
|
||||
mOutstandingInstances += aLock ? 1 : -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Points:
|
||||
|
||||
static NS_DEFINE_IID(kIMyServiceCID, NS_IMYSERVICE_CID);
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
{
|
||||
if (!aClass.Equals(kIMyServiceCID))
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
if (gFact == NULL) {
|
||||
printf("loading my service factory\n");
|
||||
gFact = new MyServiceFactory();
|
||||
if (gFact == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
gFact->AddRef(); // one for our global
|
||||
}
|
||||
gFact->AddRef(); // one for the client
|
||||
*aFactory = gFact;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT PRBool
|
||||
NSCanUnload(void)
|
||||
{
|
||||
if (gFact && gFact->CanUnload()) {
|
||||
nsrefcnt cnt = gFact->Release();
|
||||
NS_ASSERTION(cnt == 0, "can't release service factory");
|
||||
gFact = NULL;
|
||||
printf("unloading my service factory\n");
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MyService_h__
|
||||
#define MyService_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class IMyService : public nsISupports {
|
||||
public:
|
||||
|
||||
NS_IMETHOD
|
||||
Doit(void) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define NS_IMYSERVICE_IID \
|
||||
{ /* fedc3380-3648-11d2-8163-006008119d7a */ \
|
||||
0xfedc3380, \
|
||||
0x3648, \
|
||||
0x11d2, \
|
||||
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
#define NS_IMYSERVICE_CID \
|
||||
{ /* 34876550-364b-11d2-8163-006008119d7a */ \
|
||||
0x34876550, \
|
||||
0x364b, \
|
||||
0x11d2, \
|
||||
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
|
||||
}
|
||||
|
||||
#endif // MyService_h__
|
|
@ -0,0 +1,49 @@
|
|||
#!nmake
|
||||
#
|
||||
# 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.
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
DLL = $(OBJDIR)\MyService.dll
|
||||
|
||||
LINCS = -I.. -I../../src
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\xpcom32.lib \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\libplc21.lib
|
||||
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
|
||||
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
|
||||
!endif
|
||||
|
||||
CPPSRCS = \
|
||||
MyService.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\MyService.obj \
|
||||
$(NULL)
|
||||
|
||||
MODULE = xpcom
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) $(DLL) $(DIST)\bin
|
Загрузка…
Ссылка в новой задаче