consolidate client view exit paths, this seems to

cause a different synchronization issue in other
shutdown routines, though I'm not sure why
afrisby
Sean Dague 2007-12-11 21:47:18 +00:00
parent d67009a78b
commit 2e38e534d9
2 changed files with 33 additions and 37 deletions

View File

@ -73,7 +73,6 @@ namespace OpenSim.Region.ClientStack
private uint m_circuitCode; private uint m_circuitCode;
private int m_moneyBalance; private int m_moneyBalance;
private byte[] m_channelVersion=new byte[] { 0x00} ; // Dummy value needed by libSL private byte[] m_channelVersion=new byte[] { 0x00} ; // Dummy value needed by libSL
/* protected variables */ /* protected variables */
@ -188,11 +187,6 @@ namespace OpenSim.Region.ClientStack
PacketQueue = new PacketQueue(); PacketQueue = new PacketQueue();
//this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
AckTimer = new Timer(750);
AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
AckTimer.Start();
RegisterLocalPacketHandlers(); RegisterLocalPacketHandlers();
ClientThread = new Thread(new ThreadStart(AuthUser)); ClientThread = new Thread(new ThreadStart(AuthUser));
@ -211,18 +205,29 @@ namespace OpenSim.Region.ClientStack
public void Close() public void Close()
{ {
// FLUSH Packets
PacketQueue.Flush();
PacketQueue.Close();
// Pull Client out of Region // Pull Client out of Region
m_scene.RemoveClient(AgentId); m_scene.RemoveClient(AgentId);
// Send the STOP packet
libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket();
OutPacket(disable, ThrottleOutPacketType.Task);
// FLUSH Packets
PacketQueue.Close();
PacketQueue.Flush();
// Shut down timers // Shut down timers
AckTimer.Stop();
clientPingTimer.Stop(); clientPingTimer.Stop();
// This is just to give the client a reasonable chance of
// flushing out all it's packets. There should probably
// be a better mechanism here
Thread.Sleep(2000);
ClientThread.Abort(); ClientThread.Abort();
} }
public void Kick(string message) public void Kick(string message)
{ {
KickUserPacket kupack = new KickUserPacket(); KickUserPacket kupack = new KickUserPacket();
@ -234,17 +239,11 @@ namespace OpenSim.Region.ClientStack
kupack.TargetBlock.TargetPort = (ushort)0; kupack.TargetBlock.TargetPort = (ushort)0;
kupack.UserInfo.Reason = Helpers.StringToField(message); kupack.UserInfo.Reason = Helpers.StringToField(message);
OutPacket(kupack, ThrottleOutPacketType.Task); OutPacket(kupack, ThrottleOutPacketType.Task);
} }
public void Stop() public void Stop()
{ {
clientPingTimer.Stop(); Close();
libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket();
OutPacket(disable, ThrottleOutPacketType.Task);
ClientThread.Abort();
} }
#endregion #endregion
@ -389,6 +388,13 @@ namespace OpenSim.Region.ClientStack
protected virtual void InitNewClient() protected virtual void InitNewClient()
{ {
//this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
// Establish our two timers. We could probably get this down to one
AckTimer = new Timer(750);
AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
AckTimer.Start();
clientPingTimer = new Timer(5000); clientPingTimer = new Timer(5000);
clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity); clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
clientPingTimer.Enabled = true; clientPingTimer.Enabled = true;
@ -407,6 +413,7 @@ namespace OpenSim.Region.ClientStack
{ {
//session/circuit not authorised //session/circuit not authorised
MainLog.Instance.Notice("CLIENT", "New user request denied to " + userEP.ToString()); MainLog.Instance.Notice("CLIENT", "New user request denied to " + userEP.ToString());
PacketQueue.Close();
ClientThread.Abort(); ClientThread.Abort();
} }
else else
@ -423,6 +430,7 @@ namespace OpenSim.Region.ClientStack
{ {
m_secureSessionId = sessionInfo.LoginInfo.SecureSession; m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
} }
// This sets up all the timers
InitNewClient(); InitNewClient();
ClientLoop(); ClientLoop();
@ -431,11 +439,6 @@ namespace OpenSim.Region.ClientStack
# endregion # endregion
protected void KillThread()
{
ClientThread.Abort();
}
// Previously ClientView.API partial class // Previously ClientView.API partial class
public event Action<IClientAPI> OnLogout; public event Action<IClientAPI> OnLogout;
public event ObjectPermissions OnObjectPermissions; public event ObjectPermissions OnObjectPermissions;
@ -2171,7 +2174,7 @@ namespace OpenSim.Region.ClientStack
"ClientView.PacketQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + "ClientView.PacketQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " +
userEP.ToString() + " - killing thread"); userEP.ToString() + " - killing thread");
MainLog.Instance.Error(e.ToString()); MainLog.Instance.Error(e.ToString());
KillThread(); Close();
} }
} }

View File

@ -44,6 +44,8 @@ namespace OpenSim.Region.ClientStack
{ {
public class PacketQueue public class PacketQueue
{ {
private bool m_enabled = true;
private BlockingQueue<QueItem> SendQueue; private BlockingQueue<QueItem> SendQueue;
private Queue<QueItem> IncomingPacketQueue; private Queue<QueItem> IncomingPacketQueue;
@ -127,8 +129,10 @@ namespace OpenSim.Region.ClientStack
public void Enqueue(QueItem item) public void Enqueue(QueItem item)
{ {
if (!m_enabled) {return;}
// We could micro lock, but that will tend to actually // We could micro lock, but that will tend to actually
// probably be worse than just synchronizing on SendQueue // probably be worse than just synchronizing on SendQueue
lock (this) { lock (this) {
switch (item.throttleType) switch (item.throttleType)
{ {
@ -209,6 +213,7 @@ namespace OpenSim.Region.ClientStack
public void Close() public void Close()
{ {
m_enabled = false;
throttleTimer.Stop(); throttleTimer.Stop();
} }
@ -235,18 +240,6 @@ namespace OpenSim.Region.ClientStack
TextureOutgoingPacketQueue.Count > 0); TextureOutgoingPacketQueue.Count > 0);
} }
// Run through our wait queues and flush out allotted numbers of bytes into the process queue
// private bool ThrottlingTime()
// {
// if(DateTime.Now.Ticks > (LastThrottle + ThrottleInterval)) {
// LastThrottle = DateTime.Now.Ticks;
// return true;
// } else {
// return false;
// }
// }
public void ProcessThrottle() public void ProcessThrottle()
{ {