bug #16328. Share a single nsToolkit instance among all widgets.

This commit is contained in:
rpotts%netscape.com 1999-10-15 00:49:11 +00:00
parent d372095c34
commit fff994fd79
6 changed files with 195 additions and 1 deletions

View File

@ -43,3 +43,8 @@ interface nsIToolkit : nsISupports
void Init(in PRThread aThread);
};
%{ C++
extern NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult);
%}

View File

@ -19,6 +19,12 @@
#include "nscore.h" // needed for 'nsnull'
#include "nsToolkit.h"
//
// Static thread local storage index of the Toolkit
// object associated with a given thread...
//
static PRUintn gToolkitTLSIndex = 0;
//-------------------------------------------------------------------------
//
// constructor
@ -39,6 +45,9 @@ nsToolkit::~nsToolkit()
{
if (mSharedGC)
gdk_gc_unref(mSharedGC);
// Remove the TLS reference to the toolkit...
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
}
//-------------------------------------------------------------------------
@ -77,3 +86,55 @@ NS_IMETHODIMP nsToolkit::Init(PRThread *aThread)
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not
// yet exist, then one will be created...
//
//-------------------------------------------------------------------------
NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
{
nsIToolkit* toolkit = nsnull;
nsresult rv = NS_OK;
PRStatus status;
// Create the TLS index the first time through...
if (0 == gToolkitTLSIndex) {
status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
}
if (NS_SUCCEEDED(rv)) {
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
//
// Create a new toolkit for this thread...
//
if (!toolkit) {
toolkit = new nsToolkit();
if (!toolkit) {
rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ADDREF(toolkit);
toolkit->Init(PR_GetCurrentThread());
//
// The reference stored in the TLS is weak. It is removed in the
// nsToolkit destructor...
//
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
}
} else {
NS_ADDREF(toolkit);
}
*aResult = toolkit;
}
return rv;
}

View File

@ -34,6 +34,12 @@ static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
static nsMacNSPREventQueueHandler* gEventQueueHandler = nsnull;
//
// Static thread local storage index of the Toolkit
// object associated with a given thread...
//
static PRUintn gToolkitTLSIndex = 0;
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
@ -137,6 +143,8 @@ nsToolkit::~nsToolkit()
gEventQueueHandler = nsnull;
}
}
// Remove the TLS reference to the toolkit...
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
}
@ -176,3 +184,53 @@ bool nsToolkit::HasAppearanceManager()
return hasAppearanceManager;
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not
// yet exist, then one will be created...
//
//-------------------------------------------------------------------------
NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
{
nsIToolkit* toolkit = nsnull;
nsresult rv = NS_OK;
PRStatus status;
// Create the TLS index the first time through...
if (0 == gToolkitTLSIndex) {
status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
}
if (NS_SUCCEEDED(rv)) {
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
//
// Create a new toolkit for this thread...
//
if (!toolkit) {
toolkit = new nsToolkit();
if (!toolkit) {
rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ADDREF(toolkit);
toolkit->Init(PR_GetCurrentThread());
//
// The reference stored in the TLS is weak. It is removed in the
// nsToolkit destructor...
//
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
}
} else {
NS_ADDREF(toolkit);
}
*aResult = toolkit;
}
return rv;
}

View File

@ -24,6 +24,12 @@
NS_IMPL_ISUPPORTS(nsToolkit, NS_ITOOLKIT_IID)
//
// Static thread local storage index of the Toolkit
// object associated with a given thread...
//
static PRUintn gToolkitTLSIndex = 0;
HINSTANCE nsToolkit::mDllInstance = 0;
nsWindow *MouseTrailer::mCaptureWindow = NULL;
@ -138,6 +144,9 @@ nsToolkit::~nsToolkit()
// Destroy the Dispatch Window
::DestroyWindow(mDispatchWnd);
mDispatchWnd = NULL;
// Remove the TLS reference to the toolkit...
PR_SetThreadPrivate(gToolkitTLSIndex, nsnull);
}
@ -240,6 +249,58 @@ LRESULT CALLBACK nsToolkit::WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not
// yet exist, then one will be created...
//
//-------------------------------------------------------------------------
NS_METHOD NS_GetCurrentToolkit(nsIToolkit* *aResult)
{
nsIToolkit* toolkit = nsnull;
nsresult rv = NS_OK;
PRStatus status;
// Create the TLS index the first time through...
if (0 == gToolkitTLSIndex) {
status = PR_NewThreadPrivateIndex(&gToolkitTLSIndex, NULL);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
}
if (NS_SUCCEEDED(rv)) {
toolkit = (nsIToolkit*)PR_GetThreadPrivate(gToolkitTLSIndex);
//
// Create a new toolkit for this thread...
//
if (!toolkit) {
toolkit = new nsToolkit();
if (!toolkit) {
rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ADDREF(toolkit);
toolkit->Init(PR_GetCurrentThread());
//
// The reference stored in the TLS is weak. It is removed in the
// nsToolkit destructor...
//
PR_SetThreadPrivate(gToolkitTLSIndex, (void*)toolkit);
}
} else {
NS_ADDREF(toolkit);
}
*aResult = toolkit;
}
return rv;
}
//-------------------------------------------------------------------------
//
//

View File

@ -20,7 +20,7 @@ DEPTH=..\..\..
LIBRARY_NAME = raptorbasewidget_s
REQUIRES=xpcom gfxwin raptor dom js network netlib
DEFINES =-D_IMPL_NS_WIDGET
DEFINES =-D_IMPL_NS_WIDGET -DUSE_TLS_FOR_TOOLKIT
CPPSRCS = \
nsBaseDragService.cpp \

View File

@ -100,6 +100,7 @@ nsBaseWidget::~nsBaseWidget()
NS_IF_RELEASE(mContext);
}
//-------------------------------------------------------------------------
//
// Basic create.
@ -124,6 +125,7 @@ void nsBaseWidget::BaseCreate(nsIWidget *aParent,
}
// it's some top level window with no toolkit passed in.
// Create a default toolkit with the current thread
#if !defined(USE_TLS_FOR_TOOLKIT)
else {
static NS_DEFINE_CID(kToolkitCID, NS_TOOLKIT_CID);
@ -135,6 +137,13 @@ void nsBaseWidget::BaseCreate(nsIWidget *aParent,
if (mToolkit)
mToolkit->Init(PR_GetCurrentThread());
}
#else /* USE_TLS_FOR_TOOLKIT */
else {
nsresult rv;
rv = NS_GetCurrentToolkit(&mToolkit);
}
#endif /* USE_TLS_FOR_TOOLKIT */
}
}