Skip to content

Commit a40b1a4

Browse files
committed
Loopback fast path and refactoring for PlatformNotSupportedException (cincuranet/FirebirdSql.Data.FirebirdClient#60).
1 parent ed60dad commit a40b1a4

2 files changed

Lines changed: 31 additions & 11 deletions

File tree

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/GdsConnection.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ public virtual void Connect()
124124
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, _packetSize);
125125
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, _packetSize);
126126
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
127-
_socket.SetKeepAlive(KeepAliveTime, KeepAliveInterval);
127+
_socket.TrySetKeepAlive(KeepAliveTime, KeepAliveInterval);
128+
_socket.TryEnableLoopbackFastPath();
128129

129130
_socket.Connect(endPoint);
130131
_networkStream = new NetworkStream(_socket, false);

Provider/src/FirebirdSql.Data.FirebirdClient/Common/Extensions.cs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,34 @@ namespace FirebirdSql.Data.Common
2727
{
2828
internal static class Extensions
2929
{
30-
public static bool SetKeepAlive(this Socket socket, ulong time, ulong interval)
30+
static bool TrySocketAction(Action action)
31+
{
32+
try
33+
{
34+
action();
35+
return true;
36+
}
37+
catch (SocketException)
38+
{
39+
return false;
40+
}
41+
catch (PlatformNotSupportedException)
42+
{
43+
return false;
44+
}
45+
}
46+
47+
public static bool TrySetKeepAlive(this Socket socket, ulong time, ulong interval)
3148
{
3249
const int BytesPerLong = 4;
3350
const int BitsPerByte = 8;
34-
3551
bool turnOn = time != 0 && interval != 0;
3652
ulong[] input = new[]
3753
{
3854
turnOn ? (ulong)1 : (ulong)0,
3955
time,
4056
interval
4157
};
42-
4358
// tcp_keepalive struct
4459
byte[] inValue = new byte[3 * BytesPerLong];
4560
for (int i = 0; i < input.Length; i++)
@@ -49,19 +64,23 @@ public static bool SetKeepAlive(this Socket socket, ulong time, ulong interval)
4964
inValue[i * BytesPerLong + 1] = (byte)(input[i] >> ((BytesPerLong - 3) * BitsPerByte) & 0xFF);
5065
inValue[i * BytesPerLong + 0] = (byte)(input[i] >> ((BytesPerLong - 4) * BitsPerByte) & 0xFF);
5166
}
52-
5367
byte[] outValue = BitConverter.GetBytes(0);
5468

55-
try
69+
return TrySocketAction(() =>
5670
{
5771
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, turnOn ? 1 : 0);
5872
socket.IOControl(IOControlCode.KeepAliveValues, inValue, outValue);
59-
}
60-
catch (SocketException)
73+
});
74+
}
75+
76+
public static bool TryEnableLoopbackFastPath(this Socket socket)
77+
{
78+
const int SIOLoopbackFastPath = -1744830448; //0x98000010;
79+
byte[] inValue = BitConverter.GetBytes(1);
80+
return TrySocketAction(() =>
6181
{
62-
return false;
63-
}
64-
return true;
82+
socket.IOControl(SIOLoopbackFastPath, inValue, null);
83+
});
6584
}
6685

6786
public static int AsInt(this IntPtr ptr)

0 commit comments

Comments
 (0)