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);
}
}