Commit 03060353 authored by Marc Gravell's avatar Marc Gravell

Merge branch 'piccit-master'

parents e432b29a b9d93137
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
using System.Runtime.Serialization; using System.Runtime.Serialization;
#endif #endif
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace StackExchange.Redis namespace StackExchange.Redis
...@@ -493,15 +494,19 @@ public void SetResponseReceived() ...@@ -493,15 +494,19 @@ public void SetResponseReceived()
performance?.SetResponseReceived(); performance?.SetResponseReceived();
} }
public bool TryComplete(bool isAsync) public bool TryComplete(bool isAsync)
{ {
if (resultBox != null) //Ensure we can never call TryComplete on the same resultBox from two threads by grabbing it now
{ var currBox = Interlocked.Exchange(ref resultBox, null);
var ret = resultBox.TryComplete(isAsync); if (currBox != null)
{
var ret = currBox.TryComplete(isAsync);
if (ret && isAsync) //in async mode TryComplete will have unwrapped and recycled resultBox
if (!(ret && isAsync))
{ {
resultBox = null; // in async mode TryComplete will have unwrapped and recycled resultBox; ensure we no longer reference it via this message //put result box back if it was not already recycled
Interlocked.Exchange(ref resultBox, currBox);
} }
performance?.SetCompleted(); performance?.SetCompleted();
......
...@@ -35,11 +35,13 @@ public Message PeekPing(out int queueLength) ...@@ -35,11 +35,13 @@ public Message PeekPing(out int queueLength)
queueLength = high.Count + regular.Count; queueLength = high.Count + regular.Count;
if (high.Count != 0 && (peeked = high.Peek()).Command == RedisCommand.PING) if (high.Count != 0 && (peeked = high.Peek()).Command == RedisCommand.PING)
{ {
return peeked; //In a disconnect scenario, we don't want to complete the Ping message twice,
//dequeue it now so it wont get dequeued in AbortUnsent (if we're going down that code path)
return high.Dequeue();
} }
if (regular.Count != 0 && (peeked = regular.Peek()).Command == RedisCommand.PING) if (regular.Count != 0 && (peeked = regular.Peek()).Command == RedisCommand.PING)
{ {
return peeked; return regular.Dequeue();
} }
} }
return null; return null;
......
...@@ -315,7 +315,6 @@ internal void OnDisconnected(ConnectionFailureType failureType, PhysicalConnecti ...@@ -315,7 +315,6 @@ internal void OnDisconnected(ConnectionFailureType failureType, PhysicalConnecti
Trace("OnDisconnected"); Trace("OnDisconnected");
// if the next thing in the pipe is a PING, we can tell it that we failed (this really helps spot doomed connects) // if the next thing in the pipe is a PING, we can tell it that we failed (this really helps spot doomed connects)
// note that for simplicity we haven't removed it from the queue; that's OK
int count; int count;
var ping = queue.PeekPing(out count); var ping = queue.PeekPing(out count);
if (ping != null) if (ping != null)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment