Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//******************************************************************************
//
// ESSUTILS.CPP
//
// Copyright (C) 1996-1999 Microsoft Corporation
//
//******************************************************************************
#include "precomp.h"
#include <stdio.h>
#include "ess.h"
#include "essutils.h"
#include <tls.h>
CTLS g_tlsContext;
long g_lNumExternalThreadObjects = 0;
INTERNAL CEssThreadObject* GetCurrentEssThreadObject() { CEssThreadObject* pObj = (CEssThreadObject*)g_tlsContext.Get(); if ( pObj != NULL ) { //
// mark the fact that we are handing the thread object to the
// outside world. We use this later on when checking
// thread object leaks.
//
pObj->SetReferencedExternally(); }
return pObj; }
void SetCurrentEssThreadObject(IWbemContext* pContext) { //
// make sure we're not overwriting an existing internal thread object.
// if its externally referenced, we really can't tell if this would
// be a leak or not.
//
CEssThreadObject* pOldObj = (CEssThreadObject*)g_tlsContext.Get(); _DBG_ASSERT( pOldObj == NULL || pOldObj->IsReferencedExternally() );
CEssThreadObject* pObj = new CEssThreadObject(pContext); g_tlsContext.Set((void*)pObj); }
void SetConstructedEssThreadObject(CEssThreadObject* pObj) { //
// make sure we're not overwriting an existing internal thread object.
// if its externally referenced, we really can't tell if this would
// be a leak or not.
//
CEssThreadObject* pOldObj = (CEssThreadObject*)g_tlsContext.Get(); _DBG_ASSERT( pOldObj == NULL || pOldObj->IsReferencedExternally() );
//
// since this object was passed in from the outside world, then
// mark it as externally referenced.
//
if ( pObj != NULL ) { pObj->SetReferencedExternally(); }
g_tlsContext.Set((void*)pObj); }
void ClearCurrentEssThreadObject() { //
// make sure we're not overwriting an existing internal thread object.
// if its externally referenced, we really can't tell if this would
// be a leak or not.
//
CEssThreadObject* pObj = (CEssThreadObject*)g_tlsContext.Get(); _DBG_ASSERT( pObj == NULL || pObj->IsReferencedExternally() ); g_tlsContext.Set(NULL); }
INTERNAL IWbemContext* GetCurrentEssContext() { CEssThreadObject* pThreadObj = (CEssThreadObject*)g_tlsContext.Get(); if(pThreadObj) return pThreadObj->m_pContext; else return NULL; }
INTERNAL CPostponedList* GetCurrentPostponedList() { CEssThreadObject* pThreadObj = (CEssThreadObject*)g_tlsContext.Get(); if(pThreadObj) return &pThreadObj->m_PostponedList; else return NULL; }
INTERNAL CPostponedList* GetCurrentPostponedEventList() { CEssThreadObject* pThreadObj = (CEssThreadObject*)g_tlsContext.Get(); if(pThreadObj) return &pThreadObj->m_PostponedEventList; else return NULL; } CEssThreadObject::CEssThreadObject( IWbemContext* pContext ) : m_bReferencedExternally( FALSE ) { m_pContext = pContext; if( m_pContext == NULL ) { m_pContext = GetSpecialContext(); }
if ( m_pContext != NULL ) { m_pContext->AddRef(); } }
void CEssThreadObject::SetReferencedExternally() { if ( !m_bReferencedExternally ) { g_lNumExternalThreadObjects++; m_bReferencedExternally = TRUE; } }
IWbemContext* CEssThreadObject::mstatic_pSpecialContext = NULL;
INTERNAL IWbemContext* CEssThreadObject::GetSpecialContext() { // Create a "special" context object that will make sure that our
// calls back into CIMOM are not blocked
// ==============================================================
if(mstatic_pSpecialContext == NULL) { IWbemCausalityAccess* pCause = NULL; HRESULT hres = CoCreateInstance(CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER, IID_IWbemCausalityAccess, (void**)&pCause); if(FAILED(hres)) { ERRORTRACE((LOG_ESS, "Unable to create special context object: " "0x%X. Danger of deadlock\n", hres)); return NULL; }
CReleaseMe rm1(pCause);
hres = pCause->MakeSpecial(); if(FAILED(hres)) { ERRORTRACE((LOG_ESS, "Unable to make the context special: " "0x%X. Danger of deadlock\n", hres)); return NULL; }
IWbemContext* pContext = NULL; hres = pCause->QueryInterface(IID_IWbemContext, (void**)&pContext); if(FAILED(hres)) { ERRORTRACE((LOG_ESS, "Internal error: invalid context (0x%X)\n", hres)); return NULL; }
if(mstatic_pSpecialContext == NULL) // tiny window for a one-time leak
mstatic_pSpecialContext = pContext; else pContext->Release(); } return mstatic_pSpecialContext; }
CEssThreadObject::~CEssThreadObject() { if ( m_bReferencedExternally ) { g_lNumExternalThreadObjects--;
//
// since ClearCurrentEssThreadObject() can reference the
// thread object ( for leak checking ) and because we previously
// supported the thread object being deleted before
// CurrentThreadEssThreadObject(), make sure that we perform the
// Clear if the current thread object matches this one. This only
// can happen when the thread object is referenced externally.
//
CEssThreadObject* pObj = (CEssThreadObject*)g_tlsContext.Get();
if ( pObj == this ) { ClearCurrentEssThreadObject(); } }
_DBG_ASSERT( m_PostponedList.IsEmpty() );
if ( m_pContext != NULL ) { m_pContext->Release(); } }
void /*static*/ CEssThreadObject::ClearSpecialContext() { // Call only when no other work can be taking place, e.g. in DllCanUnloadNow
// =========================================================================
if(mstatic_pSpecialContext) mstatic_pSpecialContext->Release(); mstatic_pSpecialContext = NULL; }
|