1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-18 16:16:35 +09:00

global mutex on bind added

This commit is contained in:
lidgren
2018-10-20 10:53:23 +02:00
committed by GitHub
parent e26203f652
commit f9a56e4325

View File

@@ -4,12 +4,12 @@ using System.Threading;
using System.Diagnostics; using System.Diagnostics;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Net.Sockets; using System.Net.Sockets;
using System.Collections.Generic; using System.Collections.Generic;
#if !__NOIPENDPOINT__ #if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint; using NetEndPoint = System.Net.IPEndPoint;
#endif #endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
public partial class NetPeer public partial class NetPeer
@@ -39,13 +39,13 @@ namespace Lidgren.Network
internal bool m_executeFlushSendQueue; internal bool m_executeFlushSendQueue;
private AutoResetEvent m_messageReceivedEvent; private AutoResetEvent m_messageReceivedEvent;
private List<NetTuple<SynchronizationContext, SendOrPostCallback>> m_receiveCallbacks; private List<NetTuple<SynchronizationContext, SendOrPostCallback>> m_receiveCallbacks;
/// <summary> /// <summary>
/// Gets the socket, if Start() has been called /// Gets the socket, if Start() has been called
/// </summary> /// </summary>
public Socket Socket { get { return m_socket; } } public Socket Socket { get { return m_socket; } }
/// <summary> /// <summary>
/// Call this to register a callback for when a new message arrives /// Call this to register a callback for when a new message arrives
/// </summary> /// </summary>
@@ -58,18 +58,18 @@ namespace Lidgren.Network
if (m_receiveCallbacks == null) if (m_receiveCallbacks == null)
m_receiveCallbacks = new List<NetTuple<SynchronizationContext, SendOrPostCallback>>(); m_receiveCallbacks = new List<NetTuple<SynchronizationContext, SendOrPostCallback>>();
m_receiveCallbacks.Add(new NetTuple<SynchronizationContext, SendOrPostCallback>(syncContext, callback)); m_receiveCallbacks.Add(new NetTuple<SynchronizationContext, SendOrPostCallback>(syncContext, callback));
} }
/// <summary> /// <summary>
/// Call this to unregister a callback, but remember to do it in the same synchronization context! /// Call this to unregister a callback, but remember to do it in the same synchronization context!
/// </summary> /// </summary>
public void UnregisterReceivedCallback(SendOrPostCallback callback) public void UnregisterReceivedCallback(SendOrPostCallback callback)
{ {
if (m_receiveCallbacks == null) if (m_receiveCallbacks == null)
return; return;
// remove all callbacks regardless of sync context // remove all callbacks regardless of sync context
m_receiveCallbacks.RemoveAll(tuple => tuple.Item2.Equals(callback)); m_receiveCallbacks.RemoveAll(tuple => tuple.Item2.Equals(callback));
if (m_receiveCallbacks.Count < 1) if (m_receiveCallbacks.Count < 1)
m_receiveCallbacks = null; m_receiveCallbacks = null;
@@ -112,44 +112,45 @@ namespace Lidgren.Network
if (now - m_lastSocketBind < 1.0) if (now - m_lastSocketBind < 1.0)
{ {
LogDebug("Suppressed socket rebind; last bound " + (now - m_lastSocketBind) + " seconds ago"); LogDebug("Suppressed socket rebind; last bound " + (now - m_lastSocketBind) + " seconds ago");
return; // only allow rebind once every second return; // only allow rebind once every second
} }
m_lastSocketBind = now; m_lastSocketBind = now;
if (m_socket == null) using (var mutex = new Mutex(false, "Global\\lidgrenSocketBind"))
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (reBind)
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);
m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize;
m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false;
var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port);
m_socket.Bind(ep);
// try catch only works on linux not osx
try
{
// this is not supported in mono / mac or linux yet.
if(Environment.OSVersion.Platform != PlatformID.Unix)
{
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
}
else
{
LogDebug("Platform doesn't support SIO_UDP_CONNRESET");
}
}
catch (System.Exception e)
{ {
LogDebug("Platform doesn't support SIO_UDP_CONNRESET"); try
// this will be thrown on linux but not mac if it doesn't exist. {
// ignore; SIO_UDP_CONNRESET not supported on this platform mutex.WaitOne();
if (m_socket == null)
m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
if (reBind)
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);
m_socket.ReceiveBufferSize = m_configuration.ReceiveBufferSize;
m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false;
var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port);
m_socket.Bind(ep);
try
{
const uint IOC_IN = 0x80000000;
const uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
}
catch
{
// ignore; SIO_UDP_CONNRESET not supported on this platform
}
}
finally
{
mutex.ReleaseMutex();
}
} }
var boundEp = m_socket.LocalEndPoint as NetEndPoint; var boundEp = m_socket.LocalEndPoint as NetEndPoint;