Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

383 lines
9.9 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: xactdisp.cxx
//
// Contents: CTransactionDispenser implementation
//
// Classes:
//
// Functions:
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
#include "xacthead.cxx"
#pragma hdrstop
#include "xactdisp.hxx"
#include "coord.hxx"
#include "xactenum.hxx"
CTransactionDispenser g_tdOleDispenser;
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::CTransactionDispenser, public
//
// Synopsis: Constructor
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CTransactionDispenser::CTransactionDispenser()
{
xactDebugOut((DEB_ITRACE, "In CTransactionDispenser::CTransactionDispenser:%p()\n", this));
_cReferences = 1;
_xstat.cOpen = 0;
_xstat.cCommitting = 0;
_xstat.cCommitted = 0;
_xstat.cAborting = 0;
_xstat.cAborted = 0;
_xstat.cInDoubt = 0;
_xstat.cHeuristicDecision = 0;
GetSystemTimeAsFileTime(&_xstat.timeTransactionsUp);
xactDebugOut((DEB_ITRACE, "Out CTransactionDispenser::CTransactionDispenser\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::QueryInterface, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionDispenser::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc = S_OK;
xactDebugOut((DEB_TRACE,
"In CTransactionDispenser::QueryInterface:%p()\n",
this));
*ppvObj = NULL;
if ((IsEqualIID(iid, IID_IUnknown)) ||
(IsEqualIID(iid, IID_ITransactionDispenser)))
{
*ppvObj = (ITransactionDispenser *)this;
}
else if (IsEqualIID(iid, IID_ITransactionDispenserAdmin))
{
*ppvObj = (ITransactionDispenserAdmin *)this;
}
else
{
sc = E_NOINTERFACE;
}
if (SUCCEEDED(sc))
{
CTransactionDispenser::AddRef();
}
xactDebugOut((DEB_TRACE, "Out CTransactionDispenser::QueryInterface\n"));
return ResultFromScode(sc);
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::AddRef, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CTransactionDispenser::AddRef(void)
{
ULONG ulRet;
xactDebugOut((DEB_TRACE,
"In CTransactionDispenser::AddRef:%p()\n",
this));
InterlockedIncrement(&_cReferences);
ulRet = _cReferences;
xactDebugOut((DEB_TRACE, "Out CTransactionDispenser::AddRef\n"));
return ulRet;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::Release, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CTransactionDispenser::Release(void)
{
LONG lRet;
xactDebugOut((DEB_TRACE,
"In CTransactionDispenser::Release:%p()\n",
this));
xactAssert(_cReferences > 0);
lRet = InterlockedDecrement(&_cReferences);
if (lRet == 0)
{
xactAssert(FALSE &&
"Refcount on OLE transaction dispenser went to 0.");
//We don't delete the object, since we're static. A refcount of
// zero indicates someone released too many times.
// delete this;
}
else if (lRet < 0)
lRet = 0;
xactDebugOut((DEB_TRACE, "Out CTransactionDispenser::Release\n"));
return (ULONG)lRet;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::BeginTransaction, public
//
// Synopsis: Begin a new coordinated transaction
//
// Arguments: [punkOuter] -- Pointer to controlling unknown for ITransaction
// [isoLevel] -- Desired isolation level
// [isoFlags] -- From ISOFLAG enumeration
// [ulTimeout] -- Amount of time before transaction is
// automatically aborted.
// [punkTransactionCoord] -- Pointer to enclosing transaction
// [ppTransaction] -- Return of ITransaction pointer
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionDispenser::BeginTransaction(
IUnknown *punkOuter,
ISOLEVEL isoLevel,
ULONG isoFlags,
ULONG ulTimeout,
IUnknown *punkTransactionCoord,
ITransaction **ppTransaction)
{
xactDebugOut((DEB_ITRACE,
"In CTransactionDispenser::BeginTransaction:%p()\n",
this));
SCODE sc;
CTransactionCoordinator *ptc = NULL;
CXactList *pxl;
if (punkTransactionCoord != NULL)
{
//We don't support nesting these things yet.
//BUGBUG: Do we want to support this?
return XACT_E_NOENLIST;
}
if (isoLevel > ISOLATIONLEVEL_READUNCOMMITTED)
{
//Can we really support higher isolation levels with this coordinator?
// Is the read-uncommitted requirement really part of the docfile/OFS
// resource manager, and not that of the coordinator?
return XACT_E_ISOLATIONLEVEL;
}
//BUGBUG: Check ISOFLAGS
xactMem(pxl = new CXactList);
xactMem(ptc = new CTransactionCoordinator(this,
punkOuter,
isoLevel,
isoFlags,
ulTimeout));
xactChk(ptc->Init());
pxl->SetNext(_pxlTransactions);
_pxlTransactions = pxl;
pxl->SetTransaction((ITransaction *)ptc);
*ppTransaction = (ITransaction *)ptc;
_xstat.cOpen++;
xactDebugOut((DEB_ITRACE, "Out CTransactionDispenser::BeginTransaction\n"));
return sc;
Err:
delete ptc;
delete pxl;
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::EnumTransactions, public
//
// Synopsis: Get enumerator on current transactions
//
// Arguments: [ppenum] -- Return location for IEnumTransaction object
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionDispenser::EnumTransactions(IEnumTransaction **ppenum)
{
SCODE sc;
xactDebugOut((DEB_ITRACE,
"In CTransactionDispenser::EnumTransactions:%p()\n",
this));
xactMem(*ppenum = new CTransactionEnum(this));
xactDebugOut((DEB_ITRACE, "Out CTransactionDispenser::EnumTransactions\n"));
Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::GetStatistics, public
//
// Synopsis: Return statistics
//
// Arguments: [pStatistics] -- Return location for statistics
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionDispenser::GetStatistics(XACTSTATS *pStatistics)
{
xactDebugOut((DEB_ITRACE,
"In CTransactionDispenser::GetStatistics:%p()\n",
this));
*pStatistics = _xstat;
xactDebugOut((DEB_ITRACE, "Out CTransactionDispenser::GetStatistics\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionDispenser::Defect, public
//
// Synopsis: Defect a transaction from the list.
//
// Arguments: [pt] -- Pointer to transaction to defect
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
SCODE CTransactionDispenser::Defect(ITransaction *pt)
{
xactDebugOut((DEB_ITRACE, "In CTransactionDispenser::Defect:%p()\n", this));
CXactList *pxlPrev = NULL;
CXactList *pxlTemp = _pxlTransactions;
while (pxlTemp->GetTransaction() != pt)
{
pxlPrev = pxlTemp;
pxlTemp = pxlTemp->GetNext();
xactAssert(pxlTemp != NULL);
}
if (pxlPrev == NULL)
{
_pxlTransactions = _pxlTransactions->GetNext();
}
else
{
pxlPrev->SetNext(pxlTemp->GetNext());
}
delete pxlTemp;
_xstat.cOpen--;
xactDebugOut((DEB_ITRACE, "Out CTransactionDispenser::Defect\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Function: OleGetTransactionDispenser, public
//
// Synopsis: Return a pointer to the OLE default transaction dispenser
//
// Arguments: [pptd] -- Return location
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
HRESULT OleGetTransactionDispenser(ITransactionDispenser **pptd)
{
xactDebugOut((DEB_ITRACE, "In OleGetTransactionDispenser()\n"));
*pptd = &g_tdOleDispenser;
g_tdOleDispenser.AddRef();
xactDebugOut((DEB_ITRACE, "Out OleGetTransactionDispenser\n"));
return S_OK;
}