Windows-Server-2003/com/rpc/ndrlib/scontext.hxx

145 lines
4.6 KiB
C++

/*++
Copyright (C) Microsoft Corporation, 2000
Module Name:
SContext.hxx
Abstract:
Class definitions for the server side context handles.
Author:
Kamen Moutafov [KamenM]
Revision History:
KamenM Sep 2000 Created
--*/
#if _MSC_VER >= 1200
#pragma once
#endif
#ifndef __SCONTEXT_HXX_
#define __SCONTEXT_HXX_
class ServerContextHandle
{
public:
ServerContextHandle (
IN void *CtxGuard
)
{
// leave ContextChain uninitialized for now
UserContext = NULL;
UserRunDown = NULL;
this->CtxGuard = CtxGuard;
RpcpMemorySet(&WireContext, 0, sizeof(WIRE_CONTEXT));
OwnerSID = NULL;
ReferenceCount = 1;
Flags = ContextPendingAlloc;
DeadlockTag = 0;
}
inline void
AddReference (
void
)
{
long LocalRefCount;
ASSERT(ReferenceCount >= 0);
LocalRefCount = InterlockedIncrement(&ReferenceCount);
LogEvent(SU_CTXHANDLE, EV_INC, this, 0, LocalRefCount, 1, 0);
}
inline long
RemoveReference (
void
)
{
long LocalRefCount;
LocalRefCount = InterlockedDecrement(&ReferenceCount);
LogEvent(SU_CTXHANDLE, EV_DEC, this, 0, LocalRefCount, 1, 0);
ASSERT(LocalRefCount >= 0);
return LocalRefCount;
}
LIST_ENTRY ContextChain; // entry for the context chain
void *UserContext; // context for the user
NDR_RUNDOWN UserRunDown; // user routine to call
void *CtxGuard;
WIRE_CONTEXT WireContext;
// a context handle is not locked until it is put into ContextCompletedAlloc
// state and inserted into the collection.
SWMRLock Lock;
PSID OwnerSID;
// Not protected. Use interlocks. There is one lifetime reference,
// and one or more usage reference. Two paths may clear the lifetime
// reference - the rundown and the marshall path. Both have the lock
// and need to check for the deleted flag to avoid the case where both
// take the lifetime reference
// Whenever the lifetime reference is taken away, the object must be
// removed from the collection so that no new code picks it up
long ReferenceCount;
// All contexts in the collection must have the ContextCompletedAlloc
// flag. Since by the time they enter the collection, this flags
// is constant, no synchronization discipline are necessary for this
// flag
static const long ContextPendingAlloc = 0;
static const long ContextCompletedAlloc = 1;
static const long ContextAllocState = 1;
// Set in the rundown and marshall paths. Checked in the
// the marshall path. All those paths
// set it/check it under the protection of the
// collection lock. If this flag is set, the context is already
// removed, and the lifetime reference is taken away - don't remove
// it and don't take the lifetime reference
// The opposite is also true - if the context handle is in the
// collection, this flag must not be set
static const long ContextRemovedFromCollection = 2;
static const long ContextRemovedFromCollectionMask = 2;
// Set in the rundown path. Checked whenever the refcount drops
// to 0. In both cases protected by the collection lock
static const long ContextNeedsRundown = 4;
static const long ContextNeedsRundownMask = 4;
// the first time newly created context is marshalled, this flag
// is raised. The first time it is unmarshalled, it is taken down
// This allows us to figure out which contexts have been created,
// but not returned to the client in case marshalling fails and treat
// them appropriately. Set in the marshalling path. Checked in the
// unmarshall path. In both cases this is done under the protection
// of the lock
static const long ContextNewlyCreated = 8;
static const long ContextNewlyCreatedMask = 8;
// can be ContextDeleted, ContextPendingAlloc/ContextCompletedAlloc,
// ContextNeedsRundown, ContextNewlyCreated
// Protected by the collection lock for all context handles inserted
// in the collection. No protection needed for the others as no
// multithreaded access is possible
unsigned long Flags;
// When multiple Context handles are active in a call, the possibility
// of cross-call deadlock exists. This field is used to detect possible
// deadlocks when unmarshalling a context handle. The routines AquireDeadlockProtection
// and ReleaseDeadlockProtection use this value to detect possible deadlock,
// see those routines for an explanation of the algorithm.
volatile long DeadlockTag;
};
#endif // __SCONTEXT_HXX