fix bug 15820,memory leak in ImageManagerImpl by converting it to a service on gtk, windows and mac.r=dp

This commit is contained in:
neeti%netscape.com 1999-11-24 03:41:48 +00:00
parent afa5a36c6c
commit cd72e89586
10 changed files with 121 additions and 43 deletions

View File

@ -71,4 +71,9 @@
{ 0x199c7040, 0xcab0, 0x11d2, \
{ 0xa8, 0x49, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
#define NS_IMAGEMANAGER_CID \
{ 0x140d2dd1, 0x96f4, 0x11d3, \
{ 0x8a, 0xf3, 0x0, 0x10, 0x5a, 0x1b, 0x88, 0x60 } }
#endif

View File

@ -20,6 +20,7 @@
* Contributor(s):
*/
#include "nsIServiceManager.h"
#include "nsIImageGroup.h"
#include "nsIImageManager.h"
#include "nsIImageObserver.h"
@ -34,9 +35,10 @@
#include "nsIDeviceContext.h"
#include "nsIStreamListener.h"
#include "nsILoadGroup.h"
#include "nsGfxCIID.h"
static NS_DEFINE_IID(kIImageGroupIID, NS_IIMAGEGROUP_IID);
static NS_DEFINE_IID(kImageManagerCID, NS_IMAGEMANAGER_CID);
class ImageGroupImpl : public nsIImageGroup
{
@ -328,22 +330,26 @@ extern "C" NS_GFX_(nsresult)
NS_NewImageGroup(nsIImageGroup **aInstancePtrResult)
{
nsresult result;
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIImageManager *manager;
if ((result = NS_NewImageManager(&manager)) != NS_OK) {
return result;
nsCOMPtr<nsIImageManager> manager;
manager = do_GetService(kImageManagerCID, &result);
if (NS_FAILED(result)) {
/* This is just to provide backwards compatibility, until the ImageManagerImpl
can be converted to a service on all platforms. Once, we done the conversion
on all platforms, we should be removing the call to NS_NewImageManager(...)
*/
if ((result = NS_NewImageManager(getter_AddRefs(manager))) != NS_OK) {
return result;
}
}
nsIImageGroup *group = new ImageGroupImpl(manager);
if (group == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_RELEASE(manager);
return group->QueryInterface(kIImageGroupIID, (void **) aInstancePtrResult);
}

View File

@ -49,7 +49,8 @@ private:
};
// The singleton image manager
// XXX make this a service
// This a service on XP_PC , mac and gtk. Need to convert
// it to a service on all the remaining platforms.
static ImageManagerImpl* gImageManager;
ImageManagerImpl::ImageManagerImpl()
@ -64,6 +65,7 @@ ImageManagerImpl::~ImageManagerImpl()
{
IL_Shutdown();
NS_RELEASE(mSS);
gImageManager = nsnull;
}
NS_IMPL_ISUPPORTS1(ImageManagerImpl, nsIImageManager);
@ -108,8 +110,6 @@ NS_NewImageManager(nsIImageManager **aInstancePtrResult)
}
if (nsnull == gImageManager) {
gImageManager = new ImageManagerImpl();
//neeti
NS_IF_ADDREF(gImageManager);
}
if (nsnull == gImageManager) {
return NS_ERROR_OUT_OF_MEMORY;
@ -117,8 +117,12 @@ NS_NewImageManager(nsIImageManager **aInstancePtrResult)
return gImageManager->QueryInterface(kIImageManagerIID,
(void **)aInstancePtrResult);
}
/* This is going to be obsolete, once ImageManagerImpl becomes a service on all platforms */
extern "C" NS_GFX_(void)
NS_FreeImageManager()
{
/*Do not release it on platforms on which ImageManagerImpl is a service.
Need to remove this method, once ImageManagerImpl is converted to a service on all platforms.*/
NS_IF_RELEASE(gImageManager);
}

View File

@ -33,6 +33,7 @@
#include "nsDeviceContextSpecWin.h"
#include "nsDeviceContextSpecFactoryW.h"
#include "nsScriptableRegion.h"
#include "nsIImageManager.h"
static NS_DEFINE_IID(kCFontMetrics, NS_FONT_METRICS_CID);
static NS_DEFINE_IID(kCFontEnumerator, NS_FONT_ENUMERATOR_CID);
@ -44,6 +45,7 @@ static NS_DEFINE_IID(kCRegion, NS_REGION_CID);
static NS_DEFINE_IID(kCDeviceContextSpec, NS_DEVICE_CONTEXT_SPEC_CID);
static NS_DEFINE_IID(kCDeviceContextSpecFactory, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
static NS_DEFINE_IID(kCDrawingSurface, NS_DRAWING_SURFACE_CID);
static NS_DEFINE_IID(kImageManagerImpl, NS_IMAGEMANAGER_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
@ -129,7 +131,8 @@ NS_IMPL_RELEASE(nsGfxFactoryWin);
nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
{
nsresult res;
if (aResult == NULL) {
return NS_ERROR_NULL_POINTER;
}
@ -137,6 +140,7 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
*aResult = NULL;
nsISupports *inst = nsnull;
PRBool already_addreffed = PR_FALSE;
if (mClassID.Equals(kCFontMetrics)) {
nsFontMetricsWin* fm;
@ -201,6 +205,15 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
inst = (nsISupports *)scriptableRgn;
}
}
else if (mClassID.Equals(kImageManagerImpl)) {
nsCOMPtr<nsIImageManager> iManager;
res = NS_NewImageManager(getter_AddRefs(iManager));
already_addreffed = PR_TRUE;
if (NS_SUCCEEDED(res))
{
res = iManager->QueryInterface(NS_GET_IID(nsISupports), (void**)&inst);
}
}
else if (mClassID.Equals(kCFontEnumerator)) {
nsFontEnumeratorWin* fe;
NS_NEWXPCOM(fe, nsFontEnumeratorWin);
@ -212,9 +225,10 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(inst); // Stabilize
if (already_addreffed == PR_FALSE)
NS_ADDREF(inst); // Stabilize
nsresult res = inst->QueryInterface(aIID, aResult);
res = inst->QueryInterface(aIID, aResult);
NS_RELEASE(inst); // Destabilize and avoid leaks. Avoid calling delete <interface pointer>

View File

@ -44,6 +44,7 @@
#include "nsWidgetsCID.h"
#include "nsITextWidget.h"
#include "nsIBlender.h"
#include "nsIServiceManager.h"
// widget interface
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
@ -55,11 +56,13 @@ static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
static NS_DEFINE_IID(kCWindowIID, NS_WINDOW_CID);
static NS_DEFINE_IID(kCChildWindowIID, NS_CHILD_CID);
static NS_DEFINE_IID(kCScrollbarIID, NS_VERTSCROLLBAR_CID);
static NS_DEFINE_IID(kImageManagerCID, NS_IMAGEMANAGER_CID);
static char* class1Name = "ImageTest";
static HINSTANCE gInstance;
static nsIImageManager *gImageManager = nsnull;
static nsCOMPtr<nsIImageManager> gImageManager;
static nsIImageGroup *gImageGroup = nsnull;
static nsIImageRequest *gImageReq = nsnull;
static HWND gHwnd;
@ -1060,11 +1063,15 @@ PRUint32 size;
case WM_CREATE:
// Initialize image library
if (NS_NewImageManager(&gImageManager) != NS_OK||gImageManager->Init() != NS_OK)
{
::MessageBox(NULL, "Can't initialize the image library",class1Name, MB_OK);
}
gImageManager->SetCacheSize(1024*1024);
{ nsresult result;
gImageManager = do_GetService(kImageManagerCID, &result);
if ((NS_FAILED(result)) || gImageManager->Init() != NS_OK)
{
::MessageBox(NULL, "Can't initialize the image library",class1Name, MB_OK);
}
else
gImageManager->SetCacheSize(1024*1024);
}
break;
case WM_DESTROY:
MyInterrupt();
@ -1075,10 +1082,7 @@ PRUint32 size;
{
NS_RELEASE(gImageGroup);
}
if (gImageManager != nsnull)
{
NS_RELEASE(gImageManager);
}
gImageManager = nsnull;
if (gBlendImage)
{
NS_RELEASE(gBlendImage);
@ -1174,6 +1178,8 @@ WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, int nCmdShow
nsComponentManager::RegisterComponent(kCFontMetricsIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kCImageIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kCBlenderIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kCTextFieldCID, NULL, NULL, WIDGET_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kImageManagerCID, "Image Manager", "component://netscape/gfx/imagemanager", GFXWIN_DLL, PR_FALSE, PR_FALSE);
if (!prevInstance) {
WNDCLASS wndClass;

View File

@ -40,7 +40,9 @@
#include "nsRect.h"
#include "nsWidgetsCID.h"
#include "nsGfxCIID.h"
#include "nsIDeviceContext.h"
#include "nsIServiceManager.h"
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
@ -48,11 +50,12 @@ static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
static NS_DEFINE_IID(kCWindowIID, NS_WINDOW_CID);
static NS_DEFINE_IID(kCChildWindowIID, NS_CHILD_CID);
static NS_DEFINE_IID(kCScrollbarIID, NS_VERTSCROLLBAR_CID);
static NS_DEFINE_IID(kImageManagerCID, NS_IMAGEMANAGER_CID);
static char* class1Name = "ImageTest";
static HINSTANCE gInstance, gPrevInstance;
static nsIImageManager *gImageManager = nsnull;
static nsCOMPtr<nsIImageManager> gImageManager;
static nsIImageGroup *gImageGroup = nsnull;
static nsIImageRequest *gImageReq = nsnull;
static HWND gHwnd;
@ -300,12 +303,15 @@ WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
case WM_CREATE:
// Initialize image library
if (NS_NewImageManager(&gImageManager) != NS_OK ||
gImageManager->Init() != NS_OK) {
::MessageBox(NULL, "Can't initialize the image library",
class1Name, MB_OK);
}
gImageManager->SetCacheSize(1024*1024);
{ nsresult result;
gImageManager = do_GetService(kImageManagerCID, &result);
if ((NS_FAILED(result)) || gImageManager->Init() != NS_OK)
{
::MessageBox(NULL, "Can't initialize the image library",class1Name, MB_OK);
}
else
gImageManager->SetCacheSize(1024*1024);
}
break;
case WM_DESTROY:
@ -314,9 +320,7 @@ WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
if (gImageGroup != nsnull) {
NS_RELEASE(gImageGroup);
}
if (gImageManager != nsnull) {
NS_RELEASE(gImageManager);
}
gImageManager = nsnull;
PostQuitMessage(0);
break;
@ -375,6 +379,7 @@ WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, int nCmdShow
nsComponentManager::RegisterComponent(kCDeviceContextIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kCFontMetricsIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponent(kCImageIID, NULL, NULL, GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kImageManagerCID, "Image Manager", "component://netscape/gfx/imagemanager", GFXWIN_DLL, PR_FALSE, PR_FALSE);
if (!prevInstance) {
WNDCLASS wndClass;

View File

@ -145,7 +145,7 @@ static NS_DEFINE_CID(kCScriptableRegionCID, NS_SCRIPTABLE_REGION_CID);
static NS_DEFINE_CID(kCBlenderCID, NS_BLENDER_CID);
static NS_DEFINE_CID(kCDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID);
static NS_DEFINE_CID(kCDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID);
static NS_DEFINE_CID(kImageManagerCID, NS_IMAGEMANAGER_CID);
// VIEW
static NS_DEFINE_IID(kCViewManagerCID, NS_VIEW_MANAGER_CID);
@ -335,6 +335,7 @@ NS_SetupRegistry()
nsComponentManager::RegisterComponentLib(kCBlenderCID, "Blender", "component://netscape/gfx/blender", GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kCDeviceContextSpecCID, "Device Context Spec", "component://netscape/gfx/devicecontextspec", GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kCDeviceContextSpecFactoryCID, "Device Context Spec Factory", "component://netscape/gfx/devicecontextspecfactory", GFXWIN_DLL, PR_FALSE, PR_FALSE);
nsComponentManager::RegisterComponentLib(kImageManagerCID, "Image Manager", "component://netscape/gfx/imagemanager", GFXWIN_DLL, PR_FALSE, PR_FALSE);
// VIEW
nsComponentManager::RegisterComponentLib(kCViewManagerCID, NULL, NULL, VIEW_DLL, PR_FALSE, PR_FALSE);

View File

@ -166,9 +166,7 @@ int main(int argc, char **argv)
gTheApp->Run();
delete gTheApp;
NS_FreeImageManager();
// Shutdown XPCOM
// Shutdown XPCOM
rv = NS_ShutdownXPCOM(nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");

View File

@ -24,6 +24,10 @@
#include "nsBrowserWindow.h"
#include "nsMotifMenu.h"
#include "nsIImageManager.h"
#include "nsIServiceManager.h"
#include "nsGfxCIID.h"
static NS_DEFINE_IID(kImageManagerCID, NS_IMAGEMANAGER_CID);
static nsNativeViewerApp* gTheApp;
@ -99,9 +103,24 @@ nsNativeBrowserWindow::DispatchMenuItem(PRInt32 aID)
int main(int argc, char **argv)
{
nsresult result;
// Hack to get il_ss set so it doesn't fail in xpcompat.c
nsIImageManager *manager;
NS_NewImageManager(&manager);
nsCOMPtr<nsIImageManager> manager;
manager = do_GetService(kImageManagerCID, &result);
if (NS_FAILED(result)) {
/* This is just to provide backwards compatibility, until the ImageManagerImpl
can be converted to a service on all platforms. Once, we havedone the conversion
on all platforms, we should be removing the call to NS_NewImageManager(...)
*/
if ((result = NS_NewImageManager(getter_AddRefs(manager))) != NS_OK) {
return result;
}
// WARNING Extra addref to simulate older be
nsIImageManager *aManager = manager.get();
NS_ADDREF(aManager);
}
gTheApp = new nsNativeViewerApp();

View File

@ -28,6 +28,10 @@
#include "nsQtMenu.h"
#include <stdlib.h>
#include "plevent.h"
#include "nsIServiceManager.h"
#include "nsGfxCIID.h"
static NS_DEFINE_IID(kImageManagerCID, NS_IMAGEMANAGER_CID);
static nsNativeViewerApp* gTheApp;
@ -105,9 +109,25 @@ nsNativeBrowserWindow::DispatchMenuItem(PRInt32 aID)
int main(int argc, char **argv)
{
nsresult result;
// Hack to get il_ss set so it doesn't fail in xpcompat.c
nsIImageManager *manager;
NS_NewImageManager(&manager);
nsCOMPtr<nsIImageManager> manager;
manager = do_GetService(kImageManagerCID, &result);
if (NS_FAILED(result)) {
/* This is just to provide backwards compatibility, until the ImageManagerImpl
can be converted to a service on all platforms. Once, we havedone the conversion
on all platforms, we should be removing the call to NS_NewImageManager(...)
*/
if ((result = NS_NewImageManager(getter_AddRefs(manager))) != NS_OK) {
return result;
}
// WARNING Extra addref to simulate older be
nsIImageManager *aManager = manager.get();
NS_ADDREF(aManager);
}
gTheApp = new nsNativeViewerApp();