Added test for service manager.

This commit is contained in:
warren%netscape.com 1998-08-29 01:51:44 +00:00
Родитель 50e8b8e476
Коммит 32f5a442c5
5 изменённых файлов: 491 добавлений и 4 удалений

220
xpcom/tests/TestServMgr.cpp Normal file
Просмотреть файл

@ -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