Commit b2fc76fc authored by Marc Gravell's avatar Marc Gravell

Compiles for mono; not saying it works...

parent bbab86d5
......@@ -139,10 +139,10 @@ public ConfigurationOptions()
/// </summary>
public int WriteBuffer { get { return writeBuffer.GetValueOrDefault(4096); } set { writeBuffer = value; } }
internal LocalCertificateSelectionCallback CertificateSelectionCallback { get { return CertificateSelection; } }
internal LocalCertificateSelectionCallback CertificateSelectionCallback { get { return CertificateSelection; } private set { CertificateSelection = value; } }
// these just rip out the underlying handlers, bypassing the event accessors - needed when creating the SSL stream
internal RemoteCertificateValidationCallback CertificateValidationCallback { get { return CertificateValidation; } }
internal RemoteCertificateValidationCallback CertificateValidationCallback { get { return CertificateValidation; } private set { CertificateValidation = value; } }
/// <summary>
/// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException
......@@ -181,8 +181,8 @@ public ConfigurationOptions Clone()
abortOnConnectFail = abortOnConnectFail,
resolveDns = resolveDns,
CommandMap = CommandMap,
CertificateValidation = CertificateValidation,
CertificateSelection = CertificateSelection,
CertificateValidationCallback = CertificateValidationCallback,
CertificateSelectionCallback = CertificateSelectionCallback,
ChannelPrefix = ChannelPrefix.Clone(),
SocketManager = SocketManager,
};
......
......@@ -162,7 +162,13 @@ internal void OnErrorMessage(EndPoint endpoint, string message)
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
static void Write<T>(ZipArchive zip, string name, Task task, Action<T, StreamWriter> callback)
{
var entry = zip.CreateEntry(name, CompressionLevel.Optimal);
var entry = zip.CreateEntry(name,
#if MONO
CompressionLevel.Fastest
#else
CompressionLevel.Optimal
#endif
);
using (var stream = entry.Open())
using (var writer = new StreamWriter(stream))
{
......
......@@ -423,7 +423,9 @@ private void OnInternalError(Exception exception, [CallerMemberName] string orig
internal void RemovePhysical(PhysicalConnection connection)
{
#pragma warning disable 0420
Interlocked.CompareExchange(ref physical, null, connection);
#pragma warning restore 0420
}
[Conditional("VERBOSE")]
......@@ -512,7 +514,9 @@ internal bool WriteMessageDirect(PhysicalConnection tmp, Message next)
private State ChangeState(State newState)
{
#pragma warning disable 0420
var oldState = (State)Interlocked.Exchange(ref state, (int)newState);
#pragma warning restore 0420
if (oldState != newState)
{
multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState);
......@@ -539,7 +543,9 @@ private void AbortUnsent()
private bool ChangeState(State oldState, State newState)
{
#pragma warning disable 0420
bool result = Interlocked.CompareExchange(ref state, (int)newState, (int)oldState) == (int)oldState;
#pragma warning restore 0420
if (result)
{
multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState);
......
......@@ -477,7 +477,11 @@ SocketMode ISocketCallback.Connected(Stream stream)
{
try
{
#if MONO
var socketMode = SocketMode.Async;
#else
var socketMode = SocketMode.Poll;
#endif
// disallow connection in some cases
OnDebugAbort();
......@@ -487,7 +491,11 @@ SocketMode ISocketCallback.Connected(Stream stream)
if (!string.IsNullOrWhiteSpace(config.SslHost))
{
var ssl = new SslStream(stream, false, config.CertificateValidationCallback, config.CertificateSelectionCallback, EncryptionPolicy.RequireEncryption);
var ssl = new SslStream(stream, false, config.CertificateValidationCallback, config.CertificateSelectionCallback
#if !MONO
, EncryptionPolicy.RequireEncryption
#endif
);
ssl.AuthenticateAsClient(config.SslHost);
stream = ssl;
socketMode = SocketMode.Async;
......
......@@ -1670,14 +1670,13 @@ Message GetStringGetWithExpiryMessage(RedisKey key, CommandFlags flags, out Resu
throw new NotSupportedException("This operation is not possible inside a transaction or batch; please issue separate GetString and KeyTimeToLive requests");
}
var features = GetFeatures(Db, key, flags, out server);
processor = StringGetWithExpiryProcessor.Default;
if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL))
{
processor = StringGetWithExpiryProcessor.PTTL;
return new StringGetWithExpiryMessage(Db, flags, RedisCommand.PTTL, key);
}
// if we use TTL, it doesn't matter which server
server = null;
processor = StringGetWithExpiryProcessor.TTL;
return new StringGetWithExpiryMessage(Db, flags, RedisCommand.TTL, key);
}
......@@ -2027,12 +2026,8 @@ internal override void WriteImpl(PhysicalConnection physical)
private class StringGetWithExpiryProcessor : ResultProcessor<RedisValueWithExpiry>
{
public static readonly ResultProcessor<RedisValueWithExpiry> TTL = new StringGetWithExpiryProcessor(false), PTTL = new StringGetWithExpiryProcessor(true);
private readonly bool isMilliseconds;
private StringGetWithExpiryProcessor(bool isMilliseconds)
{
this.isMilliseconds = isMilliseconds;
}
public static readonly ResultProcessor<RedisValueWithExpiry> Default = new StringGetWithExpiryProcessor();
private StringGetWithExpiryProcessor() { }
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{
switch(result.Type)
......
......@@ -84,12 +84,7 @@ public static readonly TimeSpanProcessor
public static readonly ResultProcessor<RedisResult>
ScriptResult = new ScriptResultProcessor();
static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK ");
static readonly char[] space = { ' ' };
static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK ");
public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException)
{
......
......@@ -40,9 +40,7 @@ public SocketManager(string name = null)
/// </summary>
public string Name { get { return name; } }
bool isDisposed;
private readonly Dictionary<IntPtr, SocketPair> socketLookup = new Dictionary<IntPtr, SocketPair>();
bool isDisposed;
struct SocketPair
{
public readonly Socket Socket;
......@@ -52,8 +50,9 @@ public SocketPair(Socket socket, ISocketCallback callback)
this.Socket = socket;
this.Callback = callback;
}
}
}
#if !MONO
/// <summary>
/// Adds a new socket and callback to the manager
/// </summary>
......@@ -77,7 +76,10 @@ private void AddRead(Socket socket, ISocketCallback callback)
}
}
}
private readonly Dictionary<IntPtr, SocketPair> socketLookup = new Dictionary<IntPtr, SocketPair>();
#endif
internal void RequestWrite(PhysicalBridge bridge, bool forced)
{
if (Interlocked.CompareExchange(ref bridge.inWriteQueue, 1, 0) == 0 || forced)
......@@ -95,8 +97,10 @@ internal void RequestWrite(PhysicalBridge bridge, bool forced)
}
}
}
}
}
#if !MONO
private int readerCount;
private void StartReader()
{
var thread = new Thread(read, 32 * 1024); // don't need a huge stack
......@@ -124,7 +128,7 @@ private void Read()
{
if (weAreReader) Interlocked.Exchange(ref readerCount, 0);
}
}
}
readonly Queue<IntPtr> readQueue = new Queue<IntPtr>(), errorQueue = new Queue<IntPtr>();
......@@ -304,15 +308,34 @@ public TimeValue(int microSeconds)
Microseconds = (int)(microSeconds % 1000000L);
}
}
static readonly WaitCallback HelpProcessItems = state =>
{
var qdsl = state as QueueDrainSyncLock;
if (qdsl != null && qdsl.Consume())
{
var mgr = qdsl.Manager;
mgr.ProcessItems();
qdsl.Pulse();
}
};
private void ProcessItems()
{
ProcessItems(socketLookup, readQueue, CallbackOperation.Read);
ProcessItems(socketLookup, errorQueue, CallbackOperation.Error);
}
#endif
private void Shutdown(Socket socket)
{
if (socket != null)
{
{
#if !MONO
lock (socketLookup)
{
socketLookup.Remove(socket.Handle);
}
#endif
try { socket.Shutdown(SocketShutdown.Both); } catch { }
try { socket.Close(); } catch { }
try { socket.Dispose(); } catch { }
......@@ -323,23 +346,6 @@ internal void Shutdown(SocketToken token)
Shutdown(token.Socket);
}
static readonly WaitCallback HelpProcessItems = state =>
{
var qdsl = state as QueueDrainSyncLock;
if (qdsl != null && qdsl.Consume())
{
var mgr = qdsl.Manager;
mgr.ProcessItems();
qdsl.Pulse();
}
};
private void ProcessItems()
{
ProcessItems(socketLookup, readQueue, CallbackOperation.Read);
ProcessItems(socketLookup, errorQueue, CallbackOperation.Error);
}
private static void ProcessItems(Dictionary<IntPtr, SocketPair> socketLookup, Queue<IntPtr> queue, CallbackOperation operation)
{
......@@ -390,7 +396,6 @@ private enum CallbackOperation
Error
}
private int readerCount;
/// <summary>
/// Releases all resources associated with this instance
......@@ -402,13 +407,15 @@ public void Dispose()
// make sure writer threads know to exit
isDisposed = true;
Monitor.PulseAll(writeQueue);
}
}
#if !MONO
lock (socketLookup)
{
isDisposed = true;
socketLookup.Clear();
Monitor.PulseAll(socketLookup);
}
#endif
}
private readonly Queue<PhysicalBridge> writeQueue = new Queue<PhysicalBridge>();
......@@ -518,10 +525,12 @@ private void EndConnect(IAsyncResult ar)
var netStream = new NetworkStream(socket, false);
var socketMode = callback == null ? SocketMode.Abort : callback.Connected(netStream);
switch (socketMode)
{
{
#if !MONO
case SocketMode.Poll:
AddRead(socket, callback);
break;
#endif
case SocketMode.Async:
try { callback.StartReading(); }
catch { Shutdown(socket); }
......@@ -570,8 +579,10 @@ internal interface ISocketCallback
internal enum SocketMode
{
Abort,
Abort,
#if !MONO
Poll,
#endif
Async
}
......
@rd /s /q StackExchange.Redis\bin\mono
@md StackExchange.Redis\bin\mono
@call mcs -recurse:StackExchange.Redis\*.cs -out:StackExchange.Redis\bin\mono\StackExchange.Redis.dll -target:library -unsafe+ -r:System.IO.Compression.dll -d:MONO
\ No newline at end of file
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