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() ...@@ -139,10 +139,10 @@ public ConfigurationOptions()
/// </summary> /// </summary>
public int WriteBuffer { get { return writeBuffer.GetValueOrDefault(4096); } set { writeBuffer = value; } } 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 // 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> /// <summary>
/// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException /// Gets or sets whether connect/configuration timeouts should be explicitly notified via a TimeoutException
...@@ -181,8 +181,8 @@ public ConfigurationOptions Clone() ...@@ -181,8 +181,8 @@ public ConfigurationOptions Clone()
abortOnConnectFail = abortOnConnectFail, abortOnConnectFail = abortOnConnectFail,
resolveDns = resolveDns, resolveDns = resolveDns,
CommandMap = CommandMap, CommandMap = CommandMap,
CertificateValidation = CertificateValidation, CertificateValidationCallback = CertificateValidationCallback,
CertificateSelection = CertificateSelection, CertificateSelectionCallback = CertificateSelectionCallback,
ChannelPrefix = ChannelPrefix.Clone(), ChannelPrefix = ChannelPrefix.Clone(),
SocketManager = SocketManager, SocketManager = SocketManager,
}; };
......
...@@ -162,7 +162,13 @@ internal void OnErrorMessage(EndPoint endpoint, string message) ...@@ -162,7 +162,13 @@ internal void OnErrorMessage(EndPoint endpoint, string message)
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] [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) 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 stream = entry.Open())
using (var writer = new StreamWriter(stream)) using (var writer = new StreamWriter(stream))
{ {
......
...@@ -423,7 +423,9 @@ private void OnInternalError(Exception exception, [CallerMemberName] string orig ...@@ -423,7 +423,9 @@ private void OnInternalError(Exception exception, [CallerMemberName] string orig
internal void RemovePhysical(PhysicalConnection connection) internal void RemovePhysical(PhysicalConnection connection)
{ {
#pragma warning disable 0420
Interlocked.CompareExchange(ref physical, null, connection); Interlocked.CompareExchange(ref physical, null, connection);
#pragma warning restore 0420
} }
[Conditional("VERBOSE")] [Conditional("VERBOSE")]
...@@ -512,7 +514,9 @@ internal bool WriteMessageDirect(PhysicalConnection tmp, Message next) ...@@ -512,7 +514,9 @@ internal bool WriteMessageDirect(PhysicalConnection tmp, Message next)
private State ChangeState(State newState) private State ChangeState(State newState)
{ {
#pragma warning disable 0420
var oldState = (State)Interlocked.Exchange(ref state, (int)newState); var oldState = (State)Interlocked.Exchange(ref state, (int)newState);
#pragma warning restore 0420
if (oldState != newState) if (oldState != newState)
{ {
multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState); multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState);
...@@ -539,7 +543,9 @@ private void AbortUnsent() ...@@ -539,7 +543,9 @@ private void AbortUnsent()
private bool ChangeState(State oldState, State newState) private bool ChangeState(State oldState, State newState)
{ {
#pragma warning disable 0420
bool result = Interlocked.CompareExchange(ref state, (int)newState, (int)oldState) == (int)oldState; bool result = Interlocked.CompareExchange(ref state, (int)newState, (int)oldState) == (int)oldState;
#pragma warning restore 0420
if (result) if (result)
{ {
multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState); multiplexer.Trace(connectionType + " state changed from " + oldState + " to " + newState);
......
...@@ -477,7 +477,11 @@ SocketMode ISocketCallback.Connected(Stream stream) ...@@ -477,7 +477,11 @@ SocketMode ISocketCallback.Connected(Stream stream)
{ {
try try
{ {
#if MONO
var socketMode = SocketMode.Async;
#else
var socketMode = SocketMode.Poll; var socketMode = SocketMode.Poll;
#endif
// disallow connection in some cases // disallow connection in some cases
OnDebugAbort(); OnDebugAbort();
...@@ -487,7 +491,11 @@ SocketMode ISocketCallback.Connected(Stream stream) ...@@ -487,7 +491,11 @@ SocketMode ISocketCallback.Connected(Stream stream)
if (!string.IsNullOrWhiteSpace(config.SslHost)) 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); ssl.AuthenticateAsClient(config.SslHost);
stream = ssl; stream = ssl;
socketMode = SocketMode.Async; socketMode = SocketMode.Async;
......
...@@ -1670,14 +1670,13 @@ Message GetStringGetWithExpiryMessage(RedisKey key, CommandFlags flags, out Resu ...@@ -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"); 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); var features = GetFeatures(Db, key, flags, out server);
processor = StringGetWithExpiryProcessor.Default;
if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL)) if (server != null && features.MillisecondExpiry && multiplexer.CommandMap.IsAvailable(RedisCommand.PTTL))
{ {
processor = StringGetWithExpiryProcessor.PTTL;
return new StringGetWithExpiryMessage(Db, flags, RedisCommand.PTTL, key); return new StringGetWithExpiryMessage(Db, flags, RedisCommand.PTTL, key);
} }
// if we use TTL, it doesn't matter which server // if we use TTL, it doesn't matter which server
server = null; server = null;
processor = StringGetWithExpiryProcessor.TTL;
return new StringGetWithExpiryMessage(Db, flags, RedisCommand.TTL, key); return new StringGetWithExpiryMessage(Db, flags, RedisCommand.TTL, key);
} }
...@@ -2027,12 +2026,8 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2027,12 +2026,8 @@ internal override void WriteImpl(PhysicalConnection physical)
private class StringGetWithExpiryProcessor : ResultProcessor<RedisValueWithExpiry> private class StringGetWithExpiryProcessor : ResultProcessor<RedisValueWithExpiry>
{ {
public static readonly ResultProcessor<RedisValueWithExpiry> TTL = new StringGetWithExpiryProcessor(false), PTTL = new StringGetWithExpiryProcessor(true); public static readonly ResultProcessor<RedisValueWithExpiry> Default = new StringGetWithExpiryProcessor();
private readonly bool isMilliseconds; private StringGetWithExpiryProcessor() { }
private StringGetWithExpiryProcessor(bool isMilliseconds)
{
this.isMilliseconds = isMilliseconds;
}
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{ {
switch(result.Type) switch(result.Type)
......
...@@ -84,13 +84,8 @@ public static readonly TimeSpanProcessor ...@@ -84,13 +84,8 @@ public static readonly TimeSpanProcessor
public static readonly ResultProcessor<RedisResult> public static readonly ResultProcessor<RedisResult>
ScriptResult = new ScriptResultProcessor(); ScriptResult = new ScriptResultProcessor();
static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK "); static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK ");
static readonly char[] space = { ' ' };
public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException) public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException)
{ {
PhysicalConnection.IdentifyFailureType(innerException, ref fail); PhysicalConnection.IdentifyFailureType(innerException, ref fail);
......
...@@ -41,8 +41,6 @@ public SocketManager(string name = null) ...@@ -41,8 +41,6 @@ public SocketManager(string name = null)
public string Name { get { return name; } } public string Name { get { return name; } }
bool isDisposed; bool isDisposed;
private readonly Dictionary<IntPtr, SocketPair> socketLookup = new Dictionary<IntPtr, SocketPair>();
struct SocketPair struct SocketPair
{ {
public readonly Socket Socket; public readonly Socket Socket;
...@@ -54,6 +52,7 @@ public SocketPair(Socket socket, ISocketCallback callback) ...@@ -54,6 +52,7 @@ public SocketPair(Socket socket, ISocketCallback callback)
} }
} }
#if !MONO
/// <summary> /// <summary>
/// Adds a new socket and callback to the manager /// Adds a new socket and callback to the manager
/// </summary> /// </summary>
...@@ -77,6 +76,9 @@ private void AddRead(Socket socket, ISocketCallback callback) ...@@ -77,6 +76,9 @@ 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) internal void RequestWrite(PhysicalBridge bridge, bool forced)
{ {
...@@ -97,6 +99,8 @@ internal void RequestWrite(PhysicalBridge bridge, bool forced) ...@@ -97,6 +99,8 @@ internal void RequestWrite(PhysicalBridge bridge, bool forced)
} }
} }
#if !MONO
private int readerCount;
private void StartReader() private void StartReader()
{ {
var thread = new Thread(read, 32 * 1024); // don't need a huge stack var thread = new Thread(read, 32 * 1024); // don't need a huge stack
...@@ -304,15 +308,34 @@ public TimeValue(int microSeconds) ...@@ -304,15 +308,34 @@ public TimeValue(int microSeconds)
Microseconds = (int)(microSeconds % 1000000L); 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) private void Shutdown(Socket socket)
{ {
if (socket != null) if (socket != null)
{ {
#if !MONO
lock (socketLookup) lock (socketLookup)
{ {
socketLookup.Remove(socket.Handle); socketLookup.Remove(socket.Handle);
} }
#endif
try { socket.Shutdown(SocketShutdown.Both); } catch { } try { socket.Shutdown(SocketShutdown.Both); } catch { }
try { socket.Close(); } catch { } try { socket.Close(); } catch { }
try { socket.Dispose(); } catch { } try { socket.Dispose(); } catch { }
...@@ -323,23 +346,6 @@ internal void Shutdown(SocketToken token) ...@@ -323,23 +346,6 @@ internal void Shutdown(SocketToken token)
Shutdown(token.Socket); 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) private static void ProcessItems(Dictionary<IntPtr, SocketPair> socketLookup, Queue<IntPtr> queue, CallbackOperation operation)
{ {
...@@ -390,7 +396,6 @@ private enum CallbackOperation ...@@ -390,7 +396,6 @@ private enum CallbackOperation
Error Error
} }
private int readerCount;
/// <summary> /// <summary>
/// Releases all resources associated with this instance /// Releases all resources associated with this instance
...@@ -403,12 +408,14 @@ public void Dispose() ...@@ -403,12 +408,14 @@ public void Dispose()
isDisposed = true; isDisposed = true;
Monitor.PulseAll(writeQueue); Monitor.PulseAll(writeQueue);
} }
#if !MONO
lock (socketLookup) lock (socketLookup)
{ {
isDisposed = true; isDisposed = true;
socketLookup.Clear(); socketLookup.Clear();
Monitor.PulseAll(socketLookup); Monitor.PulseAll(socketLookup);
} }
#endif
} }
private readonly Queue<PhysicalBridge> writeQueue = new Queue<PhysicalBridge>(); private readonly Queue<PhysicalBridge> writeQueue = new Queue<PhysicalBridge>();
...@@ -519,9 +526,11 @@ private void EndConnect(IAsyncResult ar) ...@@ -519,9 +526,11 @@ private void EndConnect(IAsyncResult ar)
var socketMode = callback == null ? SocketMode.Abort : callback.Connected(netStream); var socketMode = callback == null ? SocketMode.Abort : callback.Connected(netStream);
switch (socketMode) switch (socketMode)
{ {
#if !MONO
case SocketMode.Poll: case SocketMode.Poll:
AddRead(socket, callback); AddRead(socket, callback);
break; break;
#endif
case SocketMode.Async: case SocketMode.Async:
try { callback.StartReading(); } try { callback.StartReading(); }
catch { Shutdown(socket); } catch { Shutdown(socket); }
...@@ -571,7 +580,9 @@ internal interface ISocketCallback ...@@ -571,7 +580,9 @@ internal interface ISocketCallback
internal enum SocketMode internal enum SocketMode
{ {
Abort, Abort,
#if !MONO
Poll, Poll,
#endif
Async 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