lidgren / lidgren-network-gen3

Lidgren Network Library
https://groups.google.com/forum/#!forum/lidgren-network-gen3
MIT License
1.19k stars 331 forks source link

Unity Android Thread.Mutex NotSupportedException #114

Closed paul-hansen closed 2 years ago

paul-hansen commented 5 years ago

After deploying to Android from Unity, starting a server gives this error message:

[02:16:29:031] <i>AndroidPlayer(ADB@127.0.0.1:34999)</i> NotSupportedException: Specified method is not supported.
  at System.Threading.Mutex..ctor (System.Boolean initiallyOwned, System.String name) [0x00000] in <00000000000000000000000000000000>:0 
  at Lidgren.Network.NetPeer.BindSocket (System.Boolean reBind) [0x00000] in <00000000000000000000000000000000>:0 
  at Lidgren.Network.NetPeer.InitializeNetwork () [0x00000] in <00000000000000000000000000000000>:0 
  at Lidgren.Network.NetPeer.Start () [0x00000] in <00000000000000000000000000000000>:0 
  at Multiplayer.StartClient () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.UI.Button.Press () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchPress (UnityEngine.EventSystems.PointerEventData pointerEvent, System.Boolean pressed, System.Boolean released) [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.EventSystems.StandaloneInputModule.ProcessTouchEvents () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.EventSystems.EventSystem.Update () [0x00000] in <00000000000000000000000000000000>:0 
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchEvents()
UnityEngine.EventSystems.StandaloneInputModule:Process()
UnityEngine.EventSystems.EventSystem:Update()

Which appears to be this line https://github.com/lidgren/lidgren-network-gen3/blob/d3458db59c082e8541f07cd738523996753e2f7c/Lidgren.Network/NetPeer.Internal.cs#L119

It looks like Mutex was added in this commit https://github.com/lidgren/lidgren-network-gen3/commit/f9a56e43255738750d02c15f49bd5353a0c1d2c5 So I built from the previous commit and it works fine on Android.

After some digging I came across this, which states that named Mutex is not supported on mobile https://bugzilla.xamarin.com/show_bug.cgi?id=26067#c3 ☹️

My Environment

Windows 10 Visual Studio Community 2017 V15.9.6 Compilation Symbols: UNITY __CONSTRAINED__ Unity 2018.3.4f1 -- Scripting Runtime Version: .NET 4.x Equivalent -- Scripting Backend: IL2CPP -- Api Compatibility Level .NET 4.x -- Minimum API Level: Android 7.1 'Nougat' (API level 25)

jblai commented 5 years ago

I just came across the same issue while trying Lidgren out with Unity. The use of Mutex is not supported on Mono, therefore it does not work with Unity. Using mutex breaks compatibility with Unity.

The library works when used in the editor, but once it is built, NetPeer.Start() throws a NotSupportedException as described by paul_hansen.

I wasn't even building for iOS/Android, it was a Windows/PC build.

Mockarutan commented 5 years ago

I'm stuck on the same problem. The only solution I found was to revert my local clone to commit e26203f6526835779dcf7d2357e4ebab642e72e6 (Link to the commit that "broke" in mono: https://github.com/lidgren/lidgren-network-gen3/commit/f9a56e43255738750d02c15f49bd5353a0c1d2c5)

devedse commented 4 years ago

I simply commented the Mutex out and replaced it by a simple lock statement. I guess its not the desired solution but it looks like the Mutex is only used to synchronize multiple Lidgren processes on one device.

rabuitendijk commented 4 years ago

Only the named Mutexes (the inter-process ones) seem to cause .net compatibility problems. For a quick fix, you can replace the line in NetPeer.Internal.cs using (var mutex = new Mutex(false, "Global\\lidgrenSocketBind")) with using (var mutex = new Mutex(false))

The lock will still work between threads in the same process, but locking between multiple Lidgren processes will be lost.

kodzuru commented 4 years ago

if you build with il2cpp, you see this error. But if you build mono, work awesome.

01c commented 4 years ago

@kodzuru same here targeting Windows. Any suggestions to make it work with il2cpp?

Edit: Found some more info by Unity Dev 22 Feb, 2016:

Unfortunately we don't have support for named mutexes in IL2CPP, as POSIX platforms like iOS don't provide the underlying support. We probably implement some higher level support for this, but I doubt it will be good to performance. There should be alternatives to using named mutexes though. Do you get a full managed call stack for this exception? That should point to the code which is using a named mutex. Maybe we can determine a viable work around.

paul-hansen commented 2 years ago

Going through and cleaning up my open issues across github. I'm no longer using Lidgren.Network for any active projects. At the time, I think I used the fix mentioned by @rabuitendijk and kept my own copy of the source, which allowed it to work with il2cpp. Using mono also worked. I don't use Unity anymore either so I'm not sure if this works the same with current versions.