private CheckEnqueueRead ( byte buffer, int offset, int count, AsyncProtocolRequest request ) : int | ||
buffer | byte | |
offset | int | |
count | int | |
request | AsyncProtocolRequest | |
리턴 | int |
internal int CheckEnqueueRead(byte[] buffer, int offset, int count, AsyncProtocolRequest request)
{
int lockState = Interlocked.CompareExchange(ref _lockReadState, LockRead, LockNone);
if (lockState != LockHandshake)
{
// Proceed, no concurrent handshake is ongoing so no need for a lock.
return CheckOldKeyDecryptedData(buffer, offset, count);
}
LazyAsyncResult lazyResult = null;
lock (this)
{
int result = CheckOldKeyDecryptedData(buffer, offset, count);
if (result != -1)
{
return result;
}
// Check again under lock.
if (_lockReadState != LockHandshake)
{
// The other thread has finished before we grabbed the lock.
_lockReadState = LockRead;
return -1;
}
_lockReadState = LockPendingRead;
if (request != null)
{
// Request queued.
_queuedReadStateRequest = request;
return 0;
}
lazyResult = new LazyAsyncResult(null, null, /*must be */ null);
_queuedReadStateRequest = lazyResult;
}
// Need to exit from lock before waiting.
lazyResult.InternalWaitForCompletion();
lock (this)
{
return CheckOldKeyDecryptedData(buffer, offset, count);
}
}
// // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte. // private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { int result = 0; if (InternalBufferCount != 0) { NetEventSource.Fail(this, $"Previous frame was not consumed. InternalBufferCount: {InternalBufferCount}"); } do { if (asyncRequest != null) { asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncReadCallback); } int copyBytes = _sslState.CheckEnqueueRead(buffer, offset, count, asyncRequest); if (copyBytes == 0) { // Queued but not completed! return(0); } if (copyBytes != -1) { asyncRequest?.CompleteUser(copyBytes); return(copyBytes); } } // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping. while ((result = StartFrameHeader(buffer, offset, count, asyncRequest)) == -1); return(result); }