RPC_STATUS
OSF_CCALL::ActivateCall (
IN OSF_BINDING_HANDLE *BindingHandle,
IN OSF_BINDING *Binding,
IN OSF_BINDING *AvailableBindingsList,
IN ULONG CallIdToUse,
IN OSF_CCALL_STATE InitialCallState,
IN PRPC_DISPATCH_TABLE DispatchTable,
IN OSF_CCONNECTION *CConnection
)
/*++
Function Name:ActivateCall
Parameters:
BindingHandle - the binding handle on which the call is made
Binding - the OSF_BINDING to use for this call. Carries a refcount
if AvailableBindingList is NULL.
AvailableBindingsList - the list of available bindings for this call.
If the binding is already selected, it will be NULL. If not, each
element from the list carries a refcount.
CallIdToUse - what call id to use.
InitialCallState - the initial state of this call
DispatchTable - the dispatch table to use for this call. Used only for callbacks
CConnection - the connection on which the call will be made.
Returns:
Remarks:
In the case of failure, the binding(s) should be released by the caller.
--*/
{
RPC_STATUS Status = RPC_S_OK;
ASSERT(BufferQueue.IsQueueEmpty());
MaxSecuritySize = 0;
MaxDataLength = 0;
Connection = CConnection;
this->BindingHandle = BindingHandle; //第一处赋值,一个CCALL对应一个BindingHandle
CurrentBuffer = 0;
CurrentOffset = 0;
CurrentState = InitialCallState; //第二处赋值,一般改为3 ( SendingFirstBuffer ),开始发送数据
CallStack = 0;
RcvBufferLength = 0;
pAsync = 0;
NeededLength = 0;
MaximumFragmentLength = 0;
LastBuffer = NULL;
RecursiveCallsKey = -1;
fDataLengthNegotiated = FALSE;
AllocHint = 0;
Flags.ClearAll();
if (Binding)
{
// we can have both binding and binding list only for non-sync
// calls
ASSERT((AvailableBindingsList == NULL) || (Connection->fExclusive == FALSE));
}
else
{
// if we don't have a binding, this must be a sync call.
// Async calls must have their bindings fixed by now
ASSERT(Connection->fExclusive);
}
Bindings.SelectedBinding = Binding;
Bindings.AvailableBindingsList = AvailableBindingsList;
this->DispatchTableCallback = DispatchTable;
CallId = CallIdToUse; //第三处赋值,一个上下文的第几次调用
fCallCancelled = FALSE;
CancelState = CANCEL_NOTREGISTERED;
AdditionalSpaceForSecurity = Connection->AdditionalSpaceForSecurity;
fPeerChoked = 0;
HeaderSize = 0;
if (Connection->fExclusive == 0)
{
//
// 1. The first reference is removed when
// all the sends are complete. This is called the send reference
// CCALL++
// 2. The second one is removed when the client is done with the call,
// ie: when freebuffer is called or when an operation fails. This is called
// the call reference. CCALL++
//
SetReferenceCount(2);
fAdvanceCallCount.SetInteger(0);
AsyncStatus = RPC_S_ASYNC_CALL_PENDING ;
FirstSend = 1;
NotificationIssued = -1;
fChoked = 0;
fLastSendComplete = 0;
CallingThread = RpcpGetThreadPointer();
ASSERT(CallingThread != 0);
Status = Connection->AddActiveCall(
CallIdToUse,
this);
}
else
{
CallingThread = 0;
}
return Status;
}