RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

.NET Framework 4.0 Exception?

mumuboy

Sorceror
I have been getting this exception quite frequently lately:
I use the newest RunUO SVN with .NET Framework 4.0.


Exception:
System.ArgumentNullException: Value cannot be null.
at System.Threading.Monitor.Enter(Object obj)
at Server.Network.NetState.Receive_Process(SocketAsyncEventArgs e)
at Server.Network.NetState.Receive_Completion(Object sender, SocketAsyncEventArgs e)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

The error is related to this:
Code:
lock ( m_AsyncLock ) {
m_AsyncState &= ~AsyncState.Pending;
}

I am not an expert in locking mechanisms, so I am not sure where to go with this.

Maybe the wonderful devs of RunUO can look at this and fix it for those of us using .NET Framework 4.0 64bit on a blade server.
 

mumuboy

Sorceror
I created this functions:
Code:
public static object EnsureVolatileObject( ref object obj, object objfallback )
{
object objread = Thread.VolatileRead( ref obj );
if ( objread == null )
{
Thread.VolatileWrite( ref obj, objfallback );
return objfallback;
}
else
{
if ( objfallback is IDisposable )
((IDisposable)objfallback).Dispose(); //Assume that objfallback can be destroyed, ALWAYS (to prevent leaks)
return objread;
}
}

And I am using it like this:

Code:
object asynclock = Utility.EnsureVolatileObject( ref m_AsyncLock, new object() );
if ( asynclock != null )
{
lock ( asynclock ) {

Unfortunately, its not easy to test since it looks like a timing issue. At this point I am hoping I nailed the problem.

EDIT: It didn't work.
 

fwiffo

Sorceror
May I ask you for more infos on the fix? I did find only one time this error on my side, and the help on a fix would be appreciated :)

edit1: maybe is while (result && !m_Disposing)? but I wonder if we are talking of the same thing or if I didn't understand you
 

Vorspire

Knight
We experienced this error on PAndora - but to be honest the performance gains with the new socketing cde is minute - the best combination is to compile with 4.0 - but disable or separate the sockets code.
The socketing code in RunUO for .NET 4.0 has never been tested.

One way to disable the socketing code is to rename the Framework_4_0 tag to Framework_4_0_Sockets in placed were the #if preprocessor symbols are checked in relation to sockets.
 

fwiffo

Sorceror
disabling the code is easy, but to tell you the truth, at least I'm speaking only for me, I merged the new runuo core in our game server (that is using almost anything custom outside, it doesn't even resemble a runuo server for certain aspects, since we emulated sphere 0.51a game mechanism, bugs excluded *cough*) to get those performance gain, and I prefer to find a solution, not to mask it with old code...I don't know how your servers work now, but on our side, since we upgraded from network code from runuo 2.0rc2, we got a lot of performance improvement, and I prefer not to leave this new code in excange for the "old" one. If it is necessary I'll debug it by myself.
 

mumuboy

Sorceror
I only experienced the problem with encryption support. It is quite possible that the script for encryption supports needs to be updated. Now instead of crashing it says that it has detected an unknown client. It is weird because I am using razor normally with encryption off, and instead of detecting that it doesn't have encryption, it think it has an invalid encryption. If I add a dispose check, then the server doesn't crash, but of course the player experiences freezes. This seems to happen ONLY while the netstate doesn't have an attached mobile (login process).

If I disable the encryption support, then I do not get any issues.
 

Vorspire

Knight
The current release of the encryption system is on my list of updates to standardize client encryption support in RunUO - as a plug-play module of my VitaNexCore project - without the need to update a list of encryption keys for new or old clients, it can automatically generate the correct keys for any client, tested with 5.x, 6.x, 7.x
 

jeffcarley

Sorceror
I disabled the socketing code and renamed the Framework_4_0 tag to Framework_4_0_Sockets and placed this in the Netstate.cs and Listener.cs scripts where the #if preprocessor symbols are checked in relation to sockets, but it did not solve the problem, any other ideas?

Can anyone tell me if this is another possible solution to this problem?

GoldDraco13 wrote this information:
This is where it is happening, within the core files, NetState.cs ln 699+

Code:
private void Receive_Process( SocketAsyncEventArgs e )
{
int byteCount = e.BytesTransferred;

if ( e.SocketError != SocketError.Success || byteCount <= 0 ) {
Dispose( false );
return;
}

m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes( 1.2 );

byte[] buffer = m_RecvBuffer;

if ( m_Encoder != null )
m_Encoder.DecodeIncomingPacket( this, ref buffer, ref byteCount );

lock ( m_Buffer )
m_Buffer.Enqueue( buffer, 0, byteCount );

m_MessagePump.OnReceive( this );

lock ( m_AsyncLock ) {
m_AsyncState &= ~AsyncState.Pending;
}
}
I'm thinking the byteCount is returning a null which isn't checked as far as I can see, but I could be wrong.

Did anyone actually fix this problem yet? Any insight would be appreciated
 

mumuboy

Sorceror
This is how the function looks. Instead of crashing the shard, it will disconnect the client. I am not sure why, but even with no encryption scripts, I still (occasionally) get a console message saying "Encrypted Client detected" and the shard does not crash like it used to.

Code:
          private void Receive_Process( SocketAsyncEventArgs e )
          {
              int byteCount = e.BytesTransferred;
 
              if ( e.SocketError != SocketError.Success || byteCount <= 0 )
              {
                    Dispose( false );
                    return;
              }
 
              m_NextCheckActivity = DateTime.Now + TimeSpan.FromMinutes( 1.2 );
 
              byte[] buffer = m_RecvBuffer;
 
              if ( m_Encoder != null )
                    m_Encoder.DecodeIncomingPacket( this, ref buffer, ref byteCount );
 
              //If DecodeIncomingPacket fails and disposes of the client (in the case of encrypted clients), then then the client will be DISPOSED at this point.
              if ( !m_Disposing )
              {
                    lock ( m_Buffer )
                        m_Buffer.Enqueue( buffer, 0, byteCount );
 
                    m_MessagePump.OnReceive( this );
 
                    lock ( m_AsyncLock )
                        m_AsyncState &= ~AsyncState.Pending;
              }
          }
 

fwiffo

Sorceror
Yes. I solved it too this way, but I did put the check on the while (result) and transformed it to while (result && !m_Disposing)...but I have too a different netstate, since it has been changed to solve other issues.
 

jeffcarley

Sorceror
I got this advice, can anyone tell me how to actually make this happen?

ASayre moved the new networking code behind a new directive to disable it but keep the .net 4 stuff enabled. You could disable the new networking code like it is done in the new RunUO svn.
 
Top