aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs2
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs2
-rw-r--r--OpenSim/Framework/Watchdog.cs40
-rw-r--r--OpenSim/Region/Application/OpenSim.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs75
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs29
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs49
-rw-r--r--prebuild.xml1
10 files changed, 150 insertions, 75 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
index fc8daf3..3171759 100644
--- a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Framework.Servers.HttpServer
107 107
108 public bool IsSecured 108 public bool IsSecured
109 { 109 {
110 get { return _context.Secured; } 110 get { return _context.IsSecured; }
111 } 111 }
112 112
113 public bool KeepAlive 113 public bool KeepAlive
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 0062d4e..f96fd1f 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
66 ThreadPriority.Normal, 66 ThreadPriority.Normal,
67 false, 67 false,
68 true, 68 true,
69 null,
69 int.MaxValue); 70 int.MaxValue);
70 } 71 }
71 72
@@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer
75 ThreadPriority.Normal, 76 ThreadPriority.Normal,
76 false, 77 false,
77 true, 78 true,
79 null,
78 1000 * 60 * 10); 80 1000 * 60 * 10);
79 } 81 }
80 82
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 881b6aa..68bf477 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -42,7 +42,7 @@ namespace OpenSim.Framework
42 const double WATCHDOG_INTERVAL_MS = 2500.0d; 42 const double WATCHDOG_INTERVAL_MS = 2500.0d;
43 43
44 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary> 44 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
45 const int WATCHDOG_TIMEOUT_MS = 5000; 45 public const int WATCHDOG_TIMEOUT_MS = 5000;
46 46
47 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] 47 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
48 public class ThreadWatchdogInfo 48 public class ThreadWatchdogInfo
@@ -58,7 +58,7 @@ namespace OpenSim.Framework
58 public int FirstTick { get; private set; } 58 public int FirstTick { get; private set; }
59 59
60 /// <summary> 60 /// <summary>
61 /// First time this heartbeat update was invoked 61 /// Last time this heartbeat update was invoked
62 /// </summary> 62 /// </summary>
63 public int LastTick { get; set; } 63 public int LastTick { get; set; }
64 64
@@ -77,6 +77,11 @@ namespace OpenSim.Framework
77 /// </summary> 77 /// </summary>
78 public bool AlarmIfTimeout { get; set; } 78 public bool AlarmIfTimeout { get; set; }
79 79
80 /// <summary>
81 /// Method execute if alarm goes off. If null then no alarm method is fired.
82 /// </summary>
83 public Func<string> AlarmMethod { get; set; }
84
80 public ThreadWatchdogInfo(Thread thread, int timeout) 85 public ThreadWatchdogInfo(Thread thread, int timeout)
81 { 86 {
82 Thread = thread; 87 Thread = thread;
@@ -87,16 +92,10 @@ namespace OpenSim.Framework
87 } 92 }
88 93
89 /// <summary> 94 /// <summary>
90 /// This event is called whenever a tracked thread is stopped or 95 /// This event is called whenever a tracked thread is
91 /// has not called UpdateThread() in time 96 /// stopped or has not called UpdateThread() in time<
92 /// </summary> 97 /// /summary>
93 /// <param name="thread">The thread that has been identified as dead</param> 98 public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
94 /// <param name="lastTick">The last time this thread called UpdateThread()</param>
95 public delegate void WatchdogTimeout(Thread thread, int lastTick);
96
97 /// <summary>This event is called whenever a tracked thread is
98 /// stopped or has not called UpdateThread() in time</summary>
99 public static event WatchdogTimeout OnWatchdogTimeout;
100 99
101 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 100 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
102 private static Dictionary<int, ThreadWatchdogInfo> m_threads; 101 private static Dictionary<int, ThreadWatchdogInfo> m_threads;
@@ -123,7 +122,7 @@ namespace OpenSim.Framework
123 public static Thread StartThread( 122 public static Thread StartThread(
124 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) 123 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
125 { 124 {
126 return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS); 125 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS);
127 } 126 }
128 127
129 /// <summary> 128 /// <summary>
@@ -135,17 +134,24 @@ namespace OpenSim.Framework
135 /// <param name="isBackground">True to run this thread as a background 134 /// <param name="isBackground">True to run this thread as a background
136 /// thread, otherwise false</param> 135 /// thread, otherwise false</param>
137 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> 136 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
137 /// <param name="alarmMethod">
138 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
139 /// Normally, this will just return some useful debugging information.
140 /// </param>
138 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> 141 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
139 /// <returns>The newly created Thread object</returns> 142 /// <returns>The newly created Thread object</returns>
140 public static Thread StartThread( 143 public static Thread StartThread(
141 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout) 144 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
145 bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
142 { 146 {
143 Thread thread = new Thread(start); 147 Thread thread = new Thread(start);
144 thread.Name = name; 148 thread.Name = name;
145 thread.Priority = priority; 149 thread.Priority = priority;
146 thread.IsBackground = isBackground; 150 thread.IsBackground = isBackground;
147 151
148 ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; 152 ThreadWatchdogInfo twi
153 = new ThreadWatchdogInfo(thread, timeout)
154 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
149 155
150 m_log.DebugFormat( 156 m_log.DebugFormat(
151 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); 157 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
@@ -258,7 +264,7 @@ namespace OpenSim.Framework
258 /// <param name="e"></param> 264 /// <param name="e"></param>
259 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) 265 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
260 { 266 {
261 WatchdogTimeout callback = OnWatchdogTimeout; 267 Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
262 268
263 if (callback != null) 269 if (callback != null)
264 { 270 {
@@ -296,7 +302,7 @@ namespace OpenSim.Framework
296 302
297 if (callbackInfos != null) 303 if (callbackInfos != null)
298 foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) 304 foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
299 callback(callbackInfo.Thread, callbackInfo.LastTick); 305 callback(callbackInfo);
300 } 306 }
301 307
302 m_watchdogTimer.Start(); 308 m_watchdogTimer.Start();
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 28f9481..ac0e3e1 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -438,12 +438,16 @@ namespace OpenSim
438 } 438 }
439 } 439 }
440 440
441 private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick) 441 private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
442 { 442 {
443 int now = Environment.TickCount & Int32.MaxValue; 443 int now = Environment.TickCount & Int32.MaxValue;
444 444
445 m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago", 445 m_log.ErrorFormat(
446 thread.Name, thread.ThreadState, now - lastTick); 446 "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
447 twi.Thread.Name,
448 twi.Thread.ThreadState,
449 now - twi.LastTick,
450 twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
447 } 451 }
448 452
449 #region Console Commands 453 #region Console Commands
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d310d65..3bdde3b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -163,6 +163,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
163 163
164 private int m_malformedCount = 0; // Guard against a spamming attack 164 private int m_malformedCount = 0; // Guard against a spamming attack
165 165
166 /// <summary>
167 /// Record current outgoing client for monitoring purposes.
168 /// </summary>
169 private IClientAPI m_currentOutgoingClient;
170
171 /// <summary>
172 /// Recording current incoming client for monitoring purposes.
173 /// </summary>
174 private IClientAPI m_currentIncomingClient;
175
166 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 176 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
167 : base(listenIP, (int)port) 177 : base(listenIP, (int)port)
168 { 178 {
@@ -244,19 +254,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
244 if (m_scene == null) 254 if (m_scene == null)
245 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); 255 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
246 256
247 m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode"); 257 m_log.InfoFormat(
258 "[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
259 m_asyncPacketHandling ? "asynchronous" : "synchronous");
248 260
249 base.Start(m_recvBufferSize, m_asyncPacketHandling); 261 base.Start(m_recvBufferSize, m_asyncPacketHandling);
250 262
251 // Start the packet processing threads 263 // Start the packet processing threads
252 Watchdog.StartThread( 264 Watchdog.StartThread(
253 IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); 265 IncomingPacketHandler,
266 string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
267 ThreadPriority.Normal,
268 false,
269 true,
270 GetWatchdogIncomingAlarmData,
271 Watchdog.WATCHDOG_TIMEOUT_MS);
272
254 Watchdog.StartThread( 273 Watchdog.StartThread(
255 OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); 274 OutgoingPacketHandler,
275 string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
276 ThreadPriority.Normal,
277 false,
278 true,
279 GetWatchdogOutgoingAlarmData,
280 Watchdog.WATCHDOG_TIMEOUT_MS);
256 281
257 m_elapsedMSSinceLastStatReport = Environment.TickCount; 282 m_elapsedMSSinceLastStatReport = Environment.TickCount;
258 } 283 }
259 284
285 /// <summary>
286 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
287 /// </summary>
288 /// <returns></returns>
289 private string GetWatchdogIncomingAlarmData()
290 {
291 return string.Format(
292 "Client is {0}",
293 m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none");
294 }
295
296 /// <summary>
297 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
298 /// </summary>
299 /// <returns></returns>
300 private string GetWatchdogOutgoingAlarmData()
301 {
302 return string.Format(
303 "Client is {0}",
304 m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
305 }
306
260 public new void Stop() 307 public new void Stop()
261 { 308 {
262 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); 309 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
@@ -1067,6 +1114,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1067 client.IsLoggingOut = true; 1114 client.IsLoggingOut = true;
1068 client.Close(false); 1115 client.Close(false);
1069 } 1116 }
1117 else
1118 {
1119 m_log.WarnFormat(
1120 "[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}",
1121 udpClient.AgentID, m_scene.RegionInfo.RegionName);
1122 }
1070 } 1123 }
1071 1124
1072 private void IncomingPacketHandler() 1125 private void IncomingPacketHandler()
@@ -1175,6 +1228,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 // client. m_packetSent will be set to true if a packet is sent 1228 // client. m_packetSent will be set to true if a packet is sent
1176 m_scene.ForEachClient(clientPacketHandler); 1229 m_scene.ForEachClient(clientPacketHandler);
1177 1230
1231 m_currentOutgoingClient = null;
1232
1178 // If nothing was sent, sleep for the minimum amount of time before a 1233 // If nothing was sent, sleep for the minimum amount of time before a
1179 // token bucket could get more tokens 1234 // token bucket could get more tokens
1180 if (!m_packetSent) 1235 if (!m_packetSent)
@@ -1193,6 +1248,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1193 1248
1194 private void ClientOutgoingPacketHandler(IClientAPI client) 1249 private void ClientOutgoingPacketHandler(IClientAPI client)
1195 { 1250 {
1251 m_currentOutgoingClient = client;
1252
1196 try 1253 try
1197 { 1254 {
1198 if (client is LLClientView) 1255 if (client is LLClientView)
@@ -1218,8 +1275,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1218 } 1275 }
1219 catch (Exception ex) 1276 catch (Exception ex)
1220 { 1277 {
1221 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + 1278 m_log.Error(
1222 " threw an exception: " + ex.Message, ex); 1279 string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
1223 } 1280 }
1224 } 1281 }
1225 1282
@@ -1245,6 +1302,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1245 { 1302 {
1246 nticks++; 1303 nticks++;
1247 watch1.Start(); 1304 watch1.Start();
1305 m_currentOutgoingClient = client;
1306
1248 try 1307 try
1249 { 1308 {
1250 if (client is LLClientView) 1309 if (client is LLClientView)
@@ -1346,6 +1405,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1346 // Make sure this client is still alive 1405 // Make sure this client is still alive
1347 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1406 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1348 { 1407 {
1408 m_currentIncomingClient = client;
1409
1349 try 1410 try
1350 { 1411 {
1351 // Process this packet 1412 // Process this packet
@@ -1363,6 +1424,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1363 m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); 1424 m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
1364 m_log.Error(e.Message, e); 1425 m_log.Error(e.Message, e);
1365 } 1426 }
1427 finally
1428 {
1429 m_currentIncomingClient = null;
1430 }
1366 } 1431 }
1367 else 1432 else
1368 { 1433 {
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 874693e..7081989 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
42 public class AssetTransactionModule : INonSharedRegionModule, 42 public class AssetTransactionModule : INonSharedRegionModule,
43 IAgentAssetTransactions 43 IAgentAssetTransactions
44 { 44 {
45// private static readonly ILog m_log = LogManager.GetLogger( 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46// MethodBase.GetCurrentMethod().DeclaringType);
47 46
48 protected Scene m_Scene; 47 protected Scene m_Scene;
49 private bool m_dumpAssetsToFile = false; 48 private bool m_dumpAssetsToFile = false;
@@ -209,15 +208,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
209 /// and comes through this method. 208 /// and comes through this method.
210 /// </summary> 209 /// </summary>
211 /// <param name="remoteClient"></param> 210 /// <param name="remoteClient"></param>
211 /// <param name="part"></param>
212 /// <param name="transactionID"></param> 212 /// <param name="transactionID"></param>
213 /// <param name="item"></param> 213 /// <param name="item"></param>
214 public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient, 214 public void HandleTaskItemUpdateFromTransaction(
215 SceneObjectPart part, UUID transactionID, 215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
216 TaskInventoryItem item)
217 { 216 {
218// m_log.DebugFormat( 217 m_log.DebugFormat(
219// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", 218 "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
220// item.Name); 219 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
221 220
222 AgentAssetTransactions transactions = 221 AgentAssetTransactions transactions =
223 GetUserTransactions(remoteClient.AgentId); 222 GetUserTransactions(remoteClient.AgentId);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 31820e0..d30c2e2 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -216,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
216 } 216 }
217 else 217 else
218 { 218 {
219 IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>(); 219 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
220 if (agentTransactions != null) 220 if (agentTransactions != null)
221 { 221 {
222 agentTransactions.HandleItemCreationFromTransaction( 222 agentTransactions.HandleItemCreationFromTransaction(
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 270b01b..e1281a6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -435,10 +435,9 @@ namespace OpenSim.Region.Framework.Scenes
435 } 435 }
436 else 436 else
437 { 437 {
438 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 438 if (AgentTransactionsModule != null)
439 if (agentTransactions != null)
440 { 439 {
441 agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); 440 AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
442 } 441 }
443 } 442 }
444 } 443 }
@@ -1566,21 +1565,17 @@ namespace OpenSim.Region.Framework.Scenes
1566 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the 1565 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
1567 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) 1566 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
1568 // will not pass in a transaction ID in the update message. 1567 // will not pass in a transaction ID in the update message.
1569 if (transactionID != UUID.Zero) 1568 if (transactionID != UUID.Zero && AgentTransactionsModule != null)
1570 { 1569 {
1571 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 1570 AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
1572 if (agentTransactions != null) 1571 remoteClient, part, transactionID, currentItem);
1573 { 1572
1574 agentTransactions.HandleTaskItemUpdateFromTransaction( 1573// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1575 remoteClient, part, transactionID, currentItem); 1574// remoteClient.SendAgentAlertMessage("Notecard saved", false);
1576 1575// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1577// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) 1576// remoteClient.SendAgentAlertMessage("Script saved", false);
1578// remoteClient.SendAgentAlertMessage("Notecard saved", false); 1577// else
1579// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) 1578// remoteClient.SendAgentAlertMessage("Item saved", false);
1580// remoteClient.SendAgentAlertMessage("Script saved", false);
1581// else
1582// remoteClient.SendAgentAlertMessage("Item saved", false);
1583 }
1584 } 1579 }
1585 1580
1586 // Base ALWAYS has move 1581 // Base ALWAYS has move
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 9c80d3e..78fbd3b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -521,6 +521,7 @@ namespace OpenSim.Region.Framework.Scenes
521 521
522 public IAttachmentsModule AttachmentsModule { get; set; } 522 public IAttachmentsModule AttachmentsModule { get; set; }
523 public IEntityTransferModule EntityTransferModule { get; private set; } 523 public IEntityTransferModule EntityTransferModule { get; private set; }
524 public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
524 525
525 public IAvatarFactoryModule AvatarFactory 526 public IAvatarFactoryModule AvatarFactory
526 { 527 {
@@ -1289,6 +1290,7 @@ namespace OpenSim.Region.Framework.Scenes
1289 m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); 1290 m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1290 EntityTransferModule = RequestModuleInterface<IEntityTransferModule>(); 1291 EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
1291 m_groupsModule = RequestModuleInterface<IGroupsModule>(); 1292 m_groupsModule = RequestModuleInterface<IGroupsModule>();
1293 AgentTransactionsModule = RequestModuleInterface<IAgentAssetTransactions>();
1292 } 1294 }
1293 1295
1294 #endregion 1296 #endregion
@@ -3428,32 +3430,33 @@ namespace OpenSim.Region.Framework.Scenes
3428 { 3430 {
3429 m_eventManager.TriggerOnRemovePresence(agentID); 3431 m_eventManager.TriggerOnRemovePresence(agentID);
3430 3432
3431 if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc) 3433 if (!isChildAgent)
3432 { 3434 {
3433 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 3435 if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
3434 // Don't save attachments for HG visitors, it
3435 // messes up their inventory. When a HG visitor logs
3436 // out on a foreign grid, their attachments will be
3437 // reloaded in the state they were in when they left
3438 // the home grid. This is best anyway as the visited
3439 // grid may use an incompatible script engine.
3440 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3441 AttachmentsModule.SaveChangedAttachments(avatar, false);
3442 }
3443
3444 ForEachClient(
3445 delegate(IClientAPI client)
3446 { 3436 {
3447 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3437 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
3448 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3438 // Don't save attachments for HG visitors, it
3449 catch (NullReferenceException) { } 3439 // messes up their inventory. When a HG visitor logs
3450 }); 3440 // out on a foreign grid, their attachments will be
3451 3441 // reloaded in the state they were in when they left
3452 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 3442 // the home grid. This is best anyway as the visited
3453 if (agentTransactions != null) 3443 // grid may use an incompatible script engine.
3454 { 3444 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3455 agentTransactions.RemoveAgentAssetTransactions(agentID); 3445 AttachmentsModule.SaveChangedAttachments(avatar, false);
3446 }
3447
3448 ForEachClient(
3449 delegate(IClientAPI client)
3450 {
3451 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3452 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3453 catch (NullReferenceException) { }
3454 });
3456 } 3455 }
3456
3457 // It's possible for child agents to have transactions if changes are being made cross-border.
3458 if (AgentTransactionsModule != null)
3459 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3457 } 3460 }
3458 finally 3461 finally
3459 { 3462 {
diff --git a/prebuild.xml b/prebuild.xml
index c840f03..3a64af9 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -126,6 +126,7 @@
126 126
127 <ReferencePath>../../../../bin/</ReferencePath> 127 <ReferencePath>../../../../bin/</ReferencePath>
128 <Reference name="System"/> 128 <Reference name="System"/>
129 <Reference name="System.Core"/>
129 <Reference name="System.Xml"/> 130 <Reference name="System.Xml"/>
130 <Reference name="System.Web"/> 131 <Reference name="System.Web"/>
131 <Reference name="OpenSim.Framework"/> 132 <Reference name="OpenSim.Framework"/>