aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs4
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs60
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs11
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs1
-rw-r--r--OpenSim/Framework/ClientInfo.cs4
-rw-r--r--OpenSim/Framework/Communications/RestClient.cs2
-rw-r--r--OpenSim/Framework/Monitoring/JobEngine.cs320
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs96
-rw-r--r--OpenSim/Framework/Monitoring/WorkManager.cs212
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs4
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs64
-rw-r--r--OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs4
-rw-r--r--OpenSim/Framework/Tests/AnimationTests.cs1
-rw-r--r--OpenSim/Framework/Util.cs63
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs33
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs17
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs328
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs98
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs66
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs505
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs762
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs106
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs79
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs425
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs224
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs6
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs66
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs165
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs344
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs215
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs85
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs181
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs100
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs844
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs62
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs192
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs1
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs21
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs1
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs3
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs3
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs3
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs15
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs8
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs1
-rw-r--r--OpenSim/Server/Base/HttpServerBase.cs39
-rw-r--r--OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs1
-rw-r--r--OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs2
-rw-r--r--OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs7
-rw-r--r--OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs5
-rw-r--r--OpenSim/Server/Handlers/Simulation/AgentHandlers.cs3
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs4
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs2
-rw-r--r--OpenSim/Services/HypergridService/HGAssetService.cs2
-rw-r--r--OpenSim/Services/HypergridService/HGFriendsService.cs3
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs17
-rw-r--r--OpenSim/Services/Interfaces/OpenProfileClient.cs7
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs3
-rw-r--r--OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs1
-rw-r--r--OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs95
-rw-r--r--OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs1
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs1
-rw-r--r--OpenSim/Tests/Common/Mock/BaseAssetRepository.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestLLUDPServer.cs (renamed from OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs)3
-rw-r--r--OpenSim/Tests/Common/Mock/TestLandChannel.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestScene.cs2
-rw-r--r--OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs2
-rw-r--r--OpenSim/Tests/Performance/NPCPerformanceTests.cs1
-rw-r--r--OpenSim/Tests/Performance/ObjectPerformanceTests.cs1
-rw-r--r--OpenSim/Tests/Performance/ScriptPerformanceTests.cs1
-rw-r--r--OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs3
-rw-r--r--OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs3
171 files changed, 4798 insertions, 1447 deletions
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
index 9fbc1b3..7d57de1 100644
--- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
@@ -561,7 +561,7 @@ namespace OpenSim.Groups
561 561
562 // so we have the list of urls to send the notice to 562 // so we have the list of urls to send the notice to
563 // this may take a long time... 563 // this may take a long time...
564 Watchdog.RunInThread(delegate 564 WorkManager.RunInThread(delegate
565 { 565 {
566 foreach (string u in urls) 566 foreach (string u in urls)
567 { 567 {
@@ -572,7 +572,7 @@ namespace OpenSim.Groups
572 hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID)); 572 hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
573 } 573 }
574 } 574 }
575 }, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID) , null); 575 }, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
576 576
577 return true; 577 return true;
578 } 578 }
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
index 720640e..9fe00e0 100644
--- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Specialized; 30using System.Collections.Specialized;
31using System.Reflection; 31using System.Reflection;
32using System.IO; 32using System.IO;
33using System.Text;
33using System.Web; 34using System.Web;
34using log4net; 35using log4net;
35using Nini.Config; 36using Nini.Config;
@@ -43,41 +44,37 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
43 44
44namespace OpenSim.Capabilities.Handlers 45namespace OpenSim.Capabilities.Handlers
45{ 46{
46 public class GetMeshHandler 47 public class GetMeshHandler : BaseStreamHandler
47 { 48 {
48// private static readonly ILog m_log = 49// private static readonly ILog m_log =
49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 51
51 private IAssetService m_assetService; 52 private IAssetService m_assetService;
52 53
53 public GetMeshHandler(IAssetService assService) 54 public GetMeshHandler(string path, IAssetService assService, string name, string description)
55 : base("GET", path, name, description)
54 { 56 {
55 m_assetService = assService; 57 m_assetService = assService;
56 } 58 }
57 59
58 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) 60 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
59 { 61 {
60 Hashtable responsedata = new Hashtable(); 62 // Try to parse the texture ID from the request URL
61 responsedata["int_response_code"] = 400; //501; //410; //404; 63 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
62 responsedata["content_type"] = "text/plain"; 64 string meshStr = query.GetOne("mesh_id");
63 responsedata["keepalive"] = false;
64 responsedata["str_response_string"] = "Request wasn't what was expected";
65 65
66 string meshStr = string.Empty; 66// m_log.DebugFormat("Fetching mesh {0}", meshStr);
67
68 if (request.ContainsKey("mesh_id"))
69 meshStr = request["mesh_id"].ToString();
70 67
71 UUID meshID = UUID.Zero; 68 UUID meshID = UUID.Zero;
72 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) 69 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
73 { 70 {
74 if (m_assetService == null) 71 if (m_assetService == null)
75 { 72 {
76 responsedata["int_response_code"] = 404; //501; //410; //404; 73 httpResponse.StatusCode = 404;
77 responsedata["content_type"] = "text/plain"; 74 httpResponse.ContentType = "text/plain";
78 responsedata["keepalive"] = false; 75 byte[] data = Encoding.UTF8.GetBytes("The asset service is unavailable. So is your mesh.");
79 responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; 76 httpResponse.Body.Write(data, 0, data.Length);
80 return responsedata; 77 return null;
81 } 78 }
82 79
83 AssetBase mesh = m_assetService.Get(meshID.ToString()); 80 AssetBase mesh = m_assetService.Get(meshID.ToString());
@@ -86,31 +83,32 @@ namespace OpenSim.Capabilities.Handlers
86 { 83 {
87 if (mesh.Type == (SByte)AssetType.Mesh) 84 if (mesh.Type == (SByte)AssetType.Mesh)
88 { 85 {
89 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); 86 byte[] data = mesh.Data;
90 responsedata["content_type"] = "application/vnd.ll.mesh"; 87 httpResponse.Body.Write(data, 0, data.Length);
91 responsedata["int_response_code"] = 200; 88 httpResponse.ContentType = "application/vnd.ll.mesh";
89 httpResponse.StatusCode = 200;
92 } 90 }
93 // Optionally add additional mesh types here 91 // Optionally add additional mesh types here
94 else 92 else
95 { 93 {
96 responsedata["int_response_code"] = 404; //501; //410; //404; 94 httpResponse.StatusCode = 404;
97 responsedata["content_type"] = "text/plain"; 95 httpResponse.ContentType = "text/plain";
98 responsedata["keepalive"] = false; 96 byte[] data = Encoding.UTF8.GetBytes("Unfortunately, this asset isn't a mesh.");
99 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; 97 httpResponse.Body.Write(data, 0, data.Length);
100 return responsedata; 98 httpResponse.KeepAlive = false;
101 } 99 }
102 } 100 }
103 else 101 else
104 { 102 {
105 responsedata["int_response_code"] = 404; //501; //410; //404; 103 httpResponse.StatusCode = 404;
106 responsedata["content_type"] = "text/plain"; 104 httpResponse.ContentType = "text/plain";
107 responsedata["keepalive"] = false; 105 byte[] data = Encoding.UTF8.GetBytes("Your Mesh wasn't found. Sorry!");
108 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; 106 httpResponse.Body.Write(data, 0, data.Length);
109 return responsedata; 107 httpResponse.KeepAlive = false;
110 } 108 }
111 } 109 }
112 110
113 return responsedata; 111 return null;
114 } 112 }
115 } 113 }
116} \ No newline at end of file 114} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs
index 8a275f3..9c53862 100644
--- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs
@@ -65,15 +65,8 @@ namespace OpenSim.Capabilities.Handlers
65 if (m_AssetService == null) 65 if (m_AssetService == null)
66 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); 66 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
67 67
68 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); 68 server.AddStreamHandler(
69 IRequestHandler reqHandler 69 new GetMeshHandler("/CAPS/GetMesh/" /*+ UUID.Random() */, m_AssetService, "GetMesh", null));
70 = new RestHTTPHandler(
71 "GET",
72 "/CAPS/" + UUID.Random(),
73 httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
74 "GetMesh",
75 null);
76 server.AddStreamHandler(reqHandler);
77 } 70 }
78 } 71 }
79} \ No newline at end of file 72} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
index 4f482f6..e5d9618 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer; 37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Capabilities.Handlers.GetTexture.Tests 41namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
43{ 42{
diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs
index d68078e..98e4465 100644
--- a/OpenSim/Framework/ClientInfo.cs
+++ b/OpenSim/Framework/ClientInfo.cs
@@ -54,6 +54,10 @@ namespace OpenSim.Framework
54 public int assetThrottle; 54 public int assetThrottle;
55 public int textureThrottle; 55 public int textureThrottle;
56 public int totalThrottle; 56 public int totalThrottle;
57
58 // Used by adaptive only
59 public int targetThrottle;
60
57 public int maxThrottle; 61 public int maxThrottle;
58 62
59 public Dictionary<string, int> SyncRequests = new Dictionary<string,int>(); 63 public Dictionary<string, int> SyncRequests = new Dictionary<string,int>();
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs
index de6fe30..72018e4 100644
--- a/OpenSim/Framework/Communications/RestClient.cs
+++ b/OpenSim/Framework/Communications/RestClient.cs
@@ -483,7 +483,7 @@ namespace OpenSim.Framework.Communications
483 /// In case, we are invoked asynchroneously this object will keep track of the state 483 /// In case, we are invoked asynchroneously this object will keep track of the state
484 /// </summary> 484 /// </summary>
485 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); 485 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state);
486 Util.FireAndForget(RequestHelper, ar); 486 Util.FireAndForget(RequestHelper, ar, "RestClient.BeginRequest");
487 return ar; 487 return ar;
488 } 488 }
489 489
diff --git a/OpenSim/Framework/Monitoring/JobEngine.cs b/OpenSim/Framework/Monitoring/JobEngine.cs
new file mode 100644
index 0000000..5925867
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/JobEngine.cs
@@ -0,0 +1,320 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Concurrent;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using OpenSim.Framework;
34
35namespace OpenSim.Framework.Monitoring
36{
37 public class Job
38 {
39 public string Name;
40 public WaitCallback Callback;
41 public object O;
42
43 public Job(string name, WaitCallback callback, object o)
44 {
45 Name = name;
46 Callback = callback;
47 O = o;
48 }
49 }
50
51 public class JobEngine
52 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 public int LogLevel { get; set; }
56
57 public bool IsRunning { get; private set; }
58
59 /// <summary>
60 /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
61 /// </summary>
62 public int RequestProcessTimeoutOnStop { get; set; }
63
64 /// <summary>
65 /// Controls whether we need to warn in the log about exceeding the max queue size.
66 /// </summary>
67 /// <remarks>
68 /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
69 /// order to avoid spamming the log with lots of warnings.
70 /// </remarks>
71 private bool m_warnOverMaxQueue = true;
72
73 private BlockingCollection<Job> m_requestQueue;
74
75 private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
76
77 private Stat m_requestsWaitingStat;
78
79 private Job m_currentJob;
80
81 /// <summary>
82 /// Used to signal that we are ready to complete stop.
83 /// </summary>
84 private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
85
86 public JobEngine()
87 {
88 RequestProcessTimeoutOnStop = 5000;
89
90 MainConsole.Instance.Commands.AddCommand(
91 "Debug",
92 false,
93 "debug jobengine",
94 "debug jobengine <start|stop|status|log>",
95 "Start, stop, get status or set logging level of the job engine.",
96 "If stopped then all outstanding jobs are processed immediately.",
97 HandleControlCommand);
98 }
99
100 public void Start()
101 {
102 lock (this)
103 {
104 if (IsRunning)
105 return;
106
107 IsRunning = true;
108
109 m_finishedProcessingAfterStop.Reset();
110
111 m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
112
113 m_requestsWaitingStat =
114 new Stat(
115 "JobsWaiting",
116 "Number of jobs waiting for processing.",
117 "",
118 "",
119 "server",
120 "jobengine",
121 StatType.Pull,
122 MeasuresOfInterest.None,
123 stat => stat.Value = m_requestQueue.Count,
124 StatVerbosity.Debug);
125
126 StatsManager.RegisterStat(m_requestsWaitingStat);
127
128 WorkManager.StartThread(
129 ProcessRequests,
130 "JobEngineThread",
131 ThreadPriority.Normal,
132 false,
133 true,
134 null,
135 int.MaxValue);
136 }
137 }
138
139 public void Stop()
140 {
141 lock (this)
142 {
143 try
144 {
145 if (!IsRunning)
146 return;
147
148 IsRunning = false;
149
150 int requestsLeft = m_requestQueue.Count;
151
152 if (requestsLeft <= 0)
153 {
154 m_cancelSource.Cancel();
155 }
156 else
157 {
158 m_log.InfoFormat("[JOB ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
159
160 while (requestsLeft > 0)
161 {
162 if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
163 {
164 // After timeout no events have been written
165 if (requestsLeft == m_requestQueue.Count)
166 {
167 m_log.WarnFormat(
168 "[JOB ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
169 RequestProcessTimeoutOnStop, requestsLeft);
170
171 break;
172 }
173 }
174
175 requestsLeft = m_requestQueue.Count;
176 }
177 }
178 }
179 finally
180 {
181 m_cancelSource.Dispose();
182 StatsManager.DeregisterStat(m_requestsWaitingStat);
183 m_requestsWaitingStat = null;
184 m_requestQueue = null;
185 }
186 }
187 }
188
189 public bool QueueRequest(string name, WaitCallback req, object o)
190 {
191 if (LogLevel >= 1)
192 m_log.DebugFormat("[JOB ENGINE]: Queued job {0}", name);
193
194 if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
195 {
196 // m_log.DebugFormat(
197 // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
198 // categories, client.AgentID, m_udpServer.Scene.Name);
199
200 m_requestQueue.Add(new Job(name, req, o));
201
202 if (!m_warnOverMaxQueue)
203 m_warnOverMaxQueue = true;
204
205 return true;
206 }
207 else
208 {
209 if (m_warnOverMaxQueue)
210 {
211// m_log.WarnFormat(
212// "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
213// client.AgentID, m_udpServer.Scene.Name);
214
215 m_log.WarnFormat("[JOB ENGINE]: Request queue at maximum capacity, not recording job");
216
217 m_warnOverMaxQueue = false;
218 }
219
220 return false;
221 }
222 }
223
224 private void ProcessRequests()
225 {
226 try
227 {
228 while (IsRunning || m_requestQueue.Count > 0)
229 {
230 m_currentJob = m_requestQueue.Take(m_cancelSource.Token);
231
232 // QueueEmpty callback = req.Client.OnQueueEmpty;
233 //
234 // if (callback != null)
235 // {
236 // try
237 // {
238 // callback(req.Categories);
239 // }
240 // catch (Exception e)
241 // {
242 // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
243 // }
244 // }
245
246 if (LogLevel >= 1)
247 m_log.DebugFormat("[JOB ENGINE]: Processing job {0}", m_currentJob.Name);
248
249 try
250 {
251 m_currentJob.Callback.Invoke(m_currentJob.O);
252 }
253 catch (Exception e)
254 {
255 m_log.Error(
256 string.Format(
257 "[JOB ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e);
258 }
259
260 if (LogLevel >= 1)
261 m_log.DebugFormat("[JOB ENGINE]: Processed job {0}", m_currentJob.Name);
262
263 m_currentJob = null;
264 }
265 }
266 catch (OperationCanceledException)
267 {
268 }
269
270 m_finishedProcessingAfterStop.Set();
271 }
272
273 private void HandleControlCommand(string module, string[] args)
274 {
275// if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
276// return;
277
278 if (args.Length < 3)
279 {
280 MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|log>");
281 return;
282 }
283
284 string subCommand = args[2];
285
286 if (subCommand == "stop")
287 {
288 Stop();
289 MainConsole.Instance.OutputFormat("Stopped job engine.");
290 }
291 else if (subCommand == "start")
292 {
293 Start();
294 MainConsole.Instance.OutputFormat("Started job engine.");
295 }
296 else if (subCommand == "status")
297 {
298 MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning);
299 MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none");
300 MainConsole.Instance.OutputFormat(
301 "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
302 MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel);
303 }
304 else if (subCommand == "log")
305 {
306// int logLevel;
307 int logLevel = int.Parse(args[3]);
308// if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
309// {
310 LogLevel = logLevel;
311 MainConsole.Instance.OutputFormat("Set debug log level to {0}", LogLevel);
312// }
313 }
314 else
315 {
316 MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
317 }
318 }
319 }
320}
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index 0fcb195..a644fa5 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -38,6 +38,8 @@ namespace OpenSim.Framework.Monitoring
38 /// </summary> 38 /// </summary>
39 public static class Watchdog 39 public static class Watchdog
40 { 40 {
41 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
42
41 /// <summary>Timer interval in milliseconds for the watchdog timer</summary> 43 /// <summary>Timer interval in milliseconds for the watchdog timer</summary>
42 public const double WATCHDOG_INTERVAL_MS = 2500.0d; 44 public const double WATCHDOG_INTERVAL_MS = 2500.0d;
43 45
@@ -141,7 +143,7 @@ namespace OpenSim.Framework.Monitoring
141 get { return m_enabled; } 143 get { return m_enabled; }
142 set 144 set
143 { 145 {
144// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value); 146 // m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
145 147
146 if (value == m_enabled) 148 if (value == m_enabled)
147 return; 149 return;
@@ -157,9 +159,8 @@ namespace OpenSim.Framework.Monitoring
157 m_watchdogTimer.Enabled = m_enabled; 159 m_watchdogTimer.Enabled = m_enabled;
158 } 160 }
159 } 161 }
160 private static bool m_enabled;
161 162
162 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 163 private static bool m_enabled;
163 private static Dictionary<int, ThreadWatchdogInfo> m_threads; 164 private static Dictionary<int, ThreadWatchdogInfo> m_threads;
164 private static System.Timers.Timer m_watchdogTimer; 165 private static System.Timers.Timer m_watchdogTimer;
165 166
@@ -180,94 +181,19 @@ namespace OpenSim.Framework.Monitoring
180 } 181 }
181 182
182 /// <summary> 183 /// <summary>
183 /// Start a new thread that is tracked by the watchdog timer. 184 /// Add a thread to the watchdog tracker.
184 /// </summary> 185 /// </summary>
185 /// <param name="start">The method that will be executed in a new thread</param> 186 /// <param name="info">Information about the thread.</info>
186 /// <param name="name">A name to give to the new thread</param> 187 /// <param name="info">Name of the thread.</info>
187 /// <param name="priority">Priority to run the thread at</param>
188 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
189 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
190 /// <param name="log">If true then creation of thread is logged.</param> 188 /// <param name="log">If true then creation of thread is logged.</param>
191 /// <returns>The newly created Thread object</returns> 189 public static void AddThread(ThreadWatchdogInfo info, string name, bool log = true)
192 public static Thread StartThread(
193 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
194 { 190 {
195 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log);
196 }
197
198 /// <summary>
199 /// Start a new thread that is tracked by the watchdog
200 /// </summary>
201 /// <param name="start">The method that will be executed in a new thread</param>
202 /// <param name="name">A name to give to the new thread</param>
203 /// <param name="priority">Priority to run the thread at</param>
204 /// <param name="isBackground">True to run this thread as a background
205 /// thread, otherwise false</param>
206 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
207 /// <param name="alarmMethod">
208 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
209 /// Normally, this will just return some useful debugging information.
210 /// </param>
211 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
212 /// <param name="log">If true then creation of thread is logged.</param>
213 /// <returns>The newly created Thread object</returns>
214 public static Thread StartThread(
215 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
216 bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
217 {
218 Thread thread = new Thread(start);
219 thread.Priority = priority;
220 thread.IsBackground = isBackground;
221
222 ThreadWatchdogInfo twi
223 = new ThreadWatchdogInfo(thread, timeout, name)
224 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
225
226 if (log) 191 if (log)
227 m_log.DebugFormat( 192 m_log.DebugFormat(
228 "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, twi.Thread.ManagedThreadId); 193 "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, info.Thread.ManagedThreadId);
229 194
230 lock (m_threads) 195 lock (m_threads)
231 m_threads.Add(twi.Thread.ManagedThreadId, twi); 196 m_threads.Add(info.Thread.ManagedThreadId, info);
232
233 thread.Start();
234 thread.Name = name;
235
236
237 return thread;
238 }
239
240 /// <summary>
241 /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
242 /// not propogate it.
243 /// </summary>
244 /// <param name="callback">Code for the thread to execute.</param>
245 /// <param name="name">Name of the thread</param>
246 /// <param name="obj">Object to pass to the thread.</param>
247 public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false)
248 {
249 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
250 {
251 Culture.SetCurrentCulture();
252 callback(obj);
253 return;
254 }
255
256 ThreadStart ts = new ThreadStart(delegate()
257 {
258 try
259 {
260 Culture.SetCurrentCulture();
261 callback(obj);
262 Watchdog.RemoveThread(log:false);
263 }
264 catch (Exception e)
265 {
266 m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
267 }
268 });
269
270 StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
271 } 197 }
272 198
273 /// <summary> 199 /// <summary>
@@ -358,7 +284,7 @@ namespace OpenSim.Framework.Monitoring
358 } 284 }
359 catch { } 285 catch { }
360 } 286 }
361 287
362 /// <summary> 288 /// <summary>
363 /// Get currently watched threads for diagnostic purposes 289 /// Get currently watched threads for diagnostic purposes
364 /// </summary> 290 /// </summary>
diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs
new file mode 100644
index 0000000..9d0eefc
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/WorkManager.cs
@@ -0,0 +1,212 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Threading;
31using log4net;
32
33namespace OpenSim.Framework.Monitoring
34{
35 /// <summary>
36 /// Manages various work items in the simulator.
37 /// </summary>
38 /// <remarks>
39 /// Currently, here work can be started
40 /// * As a long-running and monitored thread.
41 /// * In a thread that will never timeout but where the job is expected to eventually complete.
42 /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins).
43 /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps,
44 /// network waits, etc.).
45 ///
46 /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse
47 /// range of sources (client actions, incoming network, outgoing network calls, etc.).
48 ///
49 /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to
50 /// WorkManager.RunInThreadPool().
51 /// </remarks>
52 public static class WorkManager
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
55
56 public static JobEngine JobEngine { get; private set; }
57
58 static WorkManager()
59 {
60 JobEngine = new JobEngine();
61 }
62
63 /// <summary>
64 /// Start a new long-lived thread.
65 /// </summary>
66 /// <param name="start">The method that will be executed in a new thread</param>
67 /// <param name="name">A name to give to the new thread</param>
68 /// <param name="priority">Priority to run the thread at</param>
69 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
70 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
71 /// <param name="log">If true then creation of thread is logged.</param>
72 /// <returns>The newly created Thread object</returns>
73 public static Thread StartThread(
74 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
75 {
76 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS, log);
77 }
78
79 /// <summary>
80 /// Start a new thread that is tracked by the watchdog
81 /// </summary>
82 /// <param name="start">The method that will be executed in a new thread</param>
83 /// <param name="name">A name to give to the new thread</param>
84 /// <param name="priority">Priority to run the thread at</param>
85 /// <param name="isBackground">True to run this thread as a background
86 /// thread, otherwise false</param>
87 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
88 /// <param name="alarmMethod">
89 /// Alarm method to call if alarmIfTimeout is true and there is a timeout.
90 /// Normally, this will just return some useful debugging information.
91 /// </param>
92 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
93 /// <param name="log">If true then creation of thread is logged.</param>
94 /// <returns>The newly created Thread object</returns>
95 public static Thread StartThread(
96 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
97 bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
98 {
99 Thread thread = new Thread(start);
100 thread.Priority = priority;
101 thread.IsBackground = isBackground;
102
103 Watchdog.ThreadWatchdogInfo twi
104 = new Watchdog.ThreadWatchdogInfo(thread, timeout, name)
105 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
106
107 Watchdog.AddThread(twi, name, log:log);
108
109 thread.Start();
110 thread.Name = name;
111
112 return thread;
113 }
114
115 /// <summary>
116 /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
117 /// not propogate it.
118 /// </summary>
119 /// <param name="callback">Code for the thread to execute.</param>
120 /// <param name="obj">Object to pass to the thread.</param>
121 /// <param name="name">Name of the thread</param>
122 public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false)
123 {
124 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
125 {
126 Culture.SetCurrentCulture();
127 callback(obj);
128 return;
129 }
130
131 ThreadStart ts = new ThreadStart(delegate()
132 {
133 try
134 {
135 Culture.SetCurrentCulture();
136 callback(obj);
137 Watchdog.RemoveThread(log:false);
138 }
139 catch (Exception e)
140 {
141 m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
142 }
143 });
144
145 StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
146 }
147
148 /// <summary>
149 /// Run the callback via a threadpool thread.
150 /// </summary>
151 /// <remarks>
152 /// Such jobs may run after some delay but must always complete.
153 /// </remarks>
154 /// <param name="callback"></param>
155 /// <param name="obj"></param>
156 /// <param name="name">The name of the job. This is used in monitoring and debugging.</param>
157 public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name)
158 {
159 Util.FireAndForget(callback, obj, name);
160 }
161
162 /// <summary>
163 /// Run a job.
164 /// </summary>
165 /// <remarks>
166 /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job
167 /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is
168 /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to
169 /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small
170 /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more
171 /// sophisticated implementation could perform jobs concurrently when the server is under low load.
172 ///
173 /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any
174 /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine
175 /// beyond a single thread will require considerable thought.
176 ///
177 /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot
178 /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues
179 /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where
180 /// the job engine could be improved and so CPU utilization improved by better management of concurrency within
181 /// OpenSimulator.
182 /// </remarks>
183 /// <param name="jobType">General classification for the job (e.g. "RezAttachments").</param>
184 /// <param name="callback">Callback for job.</param>
185 /// <param name="obj">Object to pass to callback when run</param>
186 /// <param name="name">Specific name of job (e.g. "RezAttachments for Joe Bloggs"</param>
187 /// <param name="canRunInThisThread">If set to true then the job may be run in ths calling thread.</param>
188 /// <param name="mustNotTimeout">If the true then the job must never timeout.</param>
189 /// <param name="log">If set to true then extra logging is performed.</param>
190 public static void RunJob(
191 string jobType, WaitCallback callback, object obj, string name,
192 bool canRunInThisThread = false, bool mustNotTimeout = false,
193 bool log = false)
194 {
195 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
196 {
197 Culture.SetCurrentCulture();
198 callback(obj);
199 return;
200 }
201
202 if (JobEngine.IsRunning)
203 JobEngine.QueueRequest(name, callback, obj);
204 else if (canRunInThisThread)
205 callback(obj);
206 else if (mustNotTimeout)
207 RunInThread(callback, obj, name, log);
208 else
209 Util.FireAndForget(callback, obj, name);
210 }
211 }
212} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 4561d23..28bba70 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -120,7 +120,7 @@ namespace OpenSim.Framework.Servers.HttpServer
120 for (uint i = 0; i < m_WorkerThreadCount; i++) 120 for (uint i = 0; i < m_WorkerThreadCount; i++)
121 { 121 {
122 m_workerThreads[i] 122 m_workerThreads[i]
123 = Watchdog.StartThread( 123 = WorkManager.StartThread(
124 PoolWorkerJob, 124 PoolWorkerJob,
125 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), 125 string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
126 ThreadPriority.Normal, 126 ThreadPriority.Normal,
@@ -130,7 +130,7 @@ namespace OpenSim.Framework.Servers.HttpServer
130 int.MaxValue); 130 int.MaxValue);
131 } 131 }
132 132
133 Watchdog.StartThread( 133 WorkManager.StartThread(
134 this.CheckLongPollThreads, 134 this.CheckLongPollThreads,
135 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), 135 string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
136 ThreadPriority.Normal, 136 ThreadPriority.Normal,
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index fd56587..c22c119 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; 30using System.Diagnostics;
31using System.IO; 31using System.IO;
32using System.Linq;
32using System.Reflection; 33using System.Reflection;
33using System.Text; 34using System.Text;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
@@ -292,6 +293,18 @@ namespace OpenSim.Framework.Servers
292 HandleDebugThreadpoolLevel); 293 HandleDebugThreadpoolLevel);
293 294
294 m_console.Commands.AddCommand( 295 m_console.Commands.AddCommand(
296 "Debug", false, "show threadpool calls active",
297 "show threadpool calls active",
298 "Show details about threadpool calls that are still active (currently waiting or in progress)",
299 HandleShowThreadpoolCallsActive);
300
301 m_console.Commands.AddCommand(
302 "Debug", false, "show threadpool calls complete",
303 "show threadpool calls complete",
304 "Show details about threadpool calls that have been completed.",
305 HandleShowThreadpoolCallsComplete);
306
307 m_console.Commands.AddCommand(
295 "Debug", false, "force gc", 308 "Debug", false, "force gc",
296 "force gc", 309 "force gc",
297 "Manually invoke runtime garbage collection. For debugging purposes", 310 "Manually invoke runtime garbage collection. For debugging purposes",
@@ -354,6 +367,57 @@ namespace OpenSim.Framework.Servers
354 Notice("serialosdreq is now {0}", setSerializeOsdRequests); 367 Notice("serialosdreq is now {0}", setSerializeOsdRequests);
355 } 368 }
356 369
370 private void HandleShowThreadpoolCallsActive(string module, string[] args)
371 {
372 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList();
373 calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value));
374 int namedCalls = 0;
375
376 ConsoleDisplayList cdl = new ConsoleDisplayList();
377 foreach (KeyValuePair<string, int> kvp in calls)
378 {
379 if (kvp.Value > 0)
380 {
381 cdl.AddRow(kvp.Key, kvp.Value);
382 namedCalls += kvp.Value;
383 }
384 }
385
386 cdl.AddRow("TOTAL NAMED", namedCalls);
387
388 long allQueuedCalls = Util.TotalQueuedFireAndForgetCalls;
389 long allRunningCalls = Util.TotalRunningFireAndForgetCalls;
390
391 cdl.AddRow("TOTAL QUEUED", allQueuedCalls);
392 cdl.AddRow("TOTAL RUNNING", allRunningCalls);
393 cdl.AddRow("TOTAL ANONYMOUS", allQueuedCalls + allRunningCalls - namedCalls);
394 cdl.AddRow("TOTAL ALL", allQueuedCalls + allRunningCalls);
395
396 MainConsole.Instance.Output(cdl.ToString());
397 }
398
399 private void HandleShowThreadpoolCallsComplete(string module, string[] args)
400 {
401 List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsMade().ToList();
402 calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value));
403 int namedCallsMade = 0;
404
405 ConsoleDisplayList cdl = new ConsoleDisplayList();
406 foreach (KeyValuePair<string, int> kvp in calls)
407 {
408 cdl.AddRow(kvp.Key, kvp.Value);
409 namedCallsMade += kvp.Value;
410 }
411
412 cdl.AddRow("TOTAL NAMED", namedCallsMade);
413
414 long allCallsMade = Util.TotalFireAndForgetCallsMade;
415 cdl.AddRow("TOTAL ANONYMOUS", allCallsMade - namedCallsMade);
416 cdl.AddRow("TOTAL ALL", allCallsMade);
417
418 MainConsole.Instance.Output(cdl.ToString());
419 }
420
357 private void HandleDebugThreadpoolStatus(string module, string[] args) 421 private void HandleDebugThreadpoolStatus(string module, string[] args)
358 { 422 {
359 int workerThreads, iocpThreads; 423 int workerThreads, iocpThreads;
diff --git a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
index f33a045..d182a71 100644
--- a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
+++ b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
@@ -15,7 +15,7 @@ namespace OpenSim.Framework.ServiceAuth
15 private string m_Username, m_Password; 15 private string m_Username, m_Password;
16 private string m_CredentialsB64; 16 private string m_CredentialsB64;
17 17
18 private string remove_me; 18// private string remove_me;
19 19
20 public string Credentials 20 public string Credentials
21 { 21 {
@@ -24,7 +24,7 @@ namespace OpenSim.Framework.ServiceAuth
24 24
25 public BasicHttpAuthentication(IConfigSource config, string section) 25 public BasicHttpAuthentication(IConfigSource config, string section)
26 { 26 {
27 remove_me = section; 27// remove_me = section;
28 m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty); 28 m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty);
29 m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty); 29 m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty);
30 string str = m_Username + ":" + m_Password; 30 string str = m_Username + ":" + m_Password;
diff --git a/OpenSim/Framework/Tests/AnimationTests.cs b/OpenSim/Framework/Tests/AnimationTests.cs
index f3be81b..d8f17d0 100644
--- a/OpenSim/Framework/Tests/AnimationTests.cs
+++ b/OpenSim/Framework/Tests/AnimationTests.cs
@@ -32,7 +32,6 @@ using OpenMetaverse;
32using OpenMetaverse.StructuredData; 32using OpenMetaverse.StructuredData;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Tests.Common; 34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36using Animation = OpenSim.Framework.Animation; 35using Animation = OpenSim.Framework.Animation;
37 36
38namespace OpenSim.Framework.Tests 37namespace OpenSim.Framework.Tests
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index fefa050..97c958a 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1928,11 +1928,6 @@ namespace OpenSim.Framework
1928 } 1928 }
1929 } 1929 }
1930 1930
1931 public static void FireAndForget(System.Threading.WaitCallback callback)
1932 {
1933 FireAndForget(callback, null, null);
1934 }
1935
1936 public static void InitThreadPool(int minThreads, int maxThreads) 1931 public static void InitThreadPool(int minThreads, int maxThreads)
1937 { 1932 {
1938 if (maxThreads < 2) 1933 if (maxThreads < 2)
@@ -1977,8 +1972,7 @@ namespace OpenSim.Framework
1977 throw new NotImplementedException(); 1972 throw new NotImplementedException();
1978 } 1973 }
1979 } 1974 }
1980 1975
1981
1982 /// <summary> 1976 /// <summary>
1983 /// Additional information about threads in the main thread pool. Used to time how long the 1977 /// Additional information about threads in the main thread pool. Used to time how long the
1984 /// thread has been running, and abort it if it has timed-out. 1978 /// thread has been running, and abort it if it has timed-out.
@@ -2052,12 +2046,15 @@ namespace OpenSim.Framework
2052 } 2046 }
2053 } 2047 }
2054 2048
2055
2056 private static long nextThreadFuncNum = 0; 2049 private static long nextThreadFuncNum = 0;
2057 private static long numQueuedThreadFuncs = 0; 2050 private static long numQueuedThreadFuncs = 0;
2058 private static long numRunningThreadFuncs = 0; 2051 private static long numRunningThreadFuncs = 0;
2052 private static long numTotalThreadFuncsCalled = 0;
2059 private static Int32 threadFuncOverloadMode = 0; 2053 private static Int32 threadFuncOverloadMode = 0;
2060 2054
2055 public static long TotalQueuedFireAndForgetCalls { get { return numQueuedThreadFuncs; } }
2056 public static long TotalRunningFireAndForgetCalls { get { return numRunningThreadFuncs; } }
2057
2061 // Maps (ThreadFunc number -> Thread) 2058 // Maps (ThreadFunc number -> Thread)
2062 private static ConcurrentDictionary<long, ThreadInfo> activeThreads = new ConcurrentDictionary<long, ThreadInfo>(); 2059 private static ConcurrentDictionary<long, ThreadInfo> activeThreads = new ConcurrentDictionary<long, ThreadInfo>();
2063 2060
@@ -2086,14 +2083,49 @@ namespace OpenSim.Framework
2086 } 2083 }
2087 } 2084 }
2088 2085
2086 public static long TotalFireAndForgetCallsMade { get { return numTotalThreadFuncsCalled; } }
2087
2088 public static Dictionary<string, int> GetFireAndForgetCallsMade()
2089 {
2090 return new Dictionary<string, int>(m_fireAndForgetCallsMade);
2091 }
2092
2093 private static Dictionary<string, int> m_fireAndForgetCallsMade = new Dictionary<string, int>();
2094
2095 public static Dictionary<string, int> GetFireAndForgetCallsInProgress()
2096 {
2097 return new Dictionary<string, int>(m_fireAndForgetCallsInProgress);
2098 }
2099
2100 private static Dictionary<string, int> m_fireAndForgetCallsInProgress = new Dictionary<string, int>();
2101
2102 public static void FireAndForget(System.Threading.WaitCallback callback)
2103 {
2104 FireAndForget(callback, null, null);
2105 }
2089 2106
2090 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 2107 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
2091 { 2108 {
2092 FireAndForget(callback, obj, null); 2109 FireAndForget(callback, obj, null);
2093 } 2110 }
2094 2111
2095 public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) 2112 public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context)
2096 { 2113 {
2114 Interlocked.Increment(ref numTotalThreadFuncsCalled);
2115
2116 if (context != null)
2117 {
2118 if (!m_fireAndForgetCallsMade.ContainsKey(context))
2119 m_fireAndForgetCallsMade[context] = 1;
2120 else
2121 m_fireAndForgetCallsMade[context]++;
2122
2123 if (!m_fireAndForgetCallsInProgress.ContainsKey(context))
2124 m_fireAndForgetCallsInProgress[context] = 1;
2125 else
2126 m_fireAndForgetCallsInProgress[context]++;
2127 }
2128
2097 WaitCallback realCallback; 2129 WaitCallback realCallback;
2098 2130
2099 bool loggingEnabled = LogThreadPool > 0; 2131 bool loggingEnabled = LogThreadPool > 0;
@@ -2104,7 +2136,15 @@ namespace OpenSim.Framework
2104 if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) 2136 if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
2105 { 2137 {
2106 // If we're running regression tests, then we want any exceptions to rise up to the test code. 2138 // If we're running regression tests, then we want any exceptions to rise up to the test code.
2107 realCallback = o => { Culture.SetCurrentCulture(); callback(o); }; 2139 realCallback =
2140 o =>
2141 {
2142 Culture.SetCurrentCulture();
2143 callback(o);
2144
2145 if (context != null)
2146 m_fireAndForgetCallsInProgress[context]--;
2147 };
2108 } 2148 }
2109 else 2149 else
2110 { 2150 {
@@ -2143,6 +2183,9 @@ namespace OpenSim.Framework
2143 activeThreads.TryRemove(threadFuncNum, out dummy); 2183 activeThreads.TryRemove(threadFuncNum, out dummy);
2144 if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) 2184 if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
2145 m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); 2185 m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed()));
2186
2187 if (context != null)
2188 m_fireAndForgetCallsInProgress[context]--;
2146 } 2189 }
2147 }; 2190 };
2148 } 2191 }
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index ab606a3..3be411a 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -337,6 +337,10 @@ namespace OpenSim
337 { 337 {
338 // Called from base.StartUp() 338 // Called from base.StartUp()
339 339
340 IConfig startupConfig = Config.Configs["Startup"];
341 if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true))
342 WorkManager.JobEngine.Start();
343
340 m_httpServerPort = m_networkServersInfo.HttpListenerPort; 344 m_httpServerPort = m_networkServersInfo.HttpListenerPort;
341 SceneManager.OnRestartSim += HandleRestartRegion; 345 SceneManager.OnRestartSim += HandleRestartRegion;
342 346
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index fb24f58..16a902d 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.OptionalModules.World.NPC; 44using OpenSim.Region.OptionalModules.World.NPC;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.ClientStack.Linden.Tests 47namespace OpenSim.Region.ClientStack.Linden.Tests
49{ 48{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 8e1f63a..4aecc99 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -110,32 +110,29 @@ namespace OpenSim.Region.ClientStack.Linden
110 110
111 #endregion 111 #endregion
112 112
113
114 public void RegisterCaps(UUID agentID, Caps caps) 113 public void RegisterCaps(UUID agentID, Caps caps)
115 { 114 {
116// UUID capID = UUID.Random();
117 115
118 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 116 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
119 if (m_URL == "localhost") 117 if (m_URL == "localhost")
120 { 118 {
121// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 119 // m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
122 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); 120
123 IRequestHandler reqHandler 121 UUID capID = UUID.Random();
124 = new RestHTTPHandler( 122
125 "GET", 123 caps.RegisterHandler(
126 "/CAPS/" + UUID.Random(), 124 "GetMesh",
127 httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), 125 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString()));
128 "GetMesh",
129 agentID.ToString());
130
131 caps.RegisterHandler("GetMesh", reqHandler);
132 } 126 }
133 else 127 else
134 { 128 {
135// m_log.DebugFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 129 // m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
136 caps.RegisterHandler("GetMesh", m_URL); 130 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
131 if (handler != null)
132 handler.RegisterExternalUserCapsHandler(agentID, caps, "GetMesh", m_URL);
133 else
134 caps.RegisterHandler("GetMesh", m_URL);
137 } 135 }
138 } 136 }
139
140 } 137 }
141} 138} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index ec45c81..d4bdef6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -85,16 +85,21 @@ namespace OpenSim.Region.ClientStack.Linden
85 { 85 {
86 // These are normaly set in their respective modules 86 // These are normaly set in their respective modules
87 m_SearchURL = config.GetString("SearchServerURI", m_SearchURL); 87 m_SearchURL = config.GetString("SearchServerURI", m_SearchURL);
88
88 m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL); 89 m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL);
90
89 if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config 91 if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config
90 m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL); 92 m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL);
93
91 m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); 94 m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
92 m_GridURL = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI", 95
93 new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty); 96 m_GridURL = Util.GetConfigVarFromSections<string>(
97 source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty);
98
94 m_GridName = config.GetString("GridName", string.Empty); 99 m_GridName = config.GetString("GridName", string.Empty);
95 if (m_GridName == string.Empty) 100 if (m_GridName == string.Empty)
96 m_GridName = Util.GetConfigVarFromSections<string>(source, "gridname", 101 m_GridName = Util.GetConfigVarFromSections<string>(
97 new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty); 102 source, "gridname", new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty);
98 } 103 }
99 104
100 AddDefaultFeatures(); 105 AddDefaultFeatures();
@@ -148,13 +153,13 @@ namespace OpenSim.Region.ClientStack.Linden
148 m_features["MeshUploadEnabled"] = true; 153 m_features["MeshUploadEnabled"] = true;
149 m_features["MeshXferEnabled"] = true; 154 m_features["MeshXferEnabled"] = true;
150 m_features["PhysicsMaterialsEnabled"] = true; 155 m_features["PhysicsMaterialsEnabled"] = true;
151 156
152 OSDMap typesMap = new OSDMap(); 157 OSDMap typesMap = new OSDMap();
153 typesMap["convex"] = true; 158 typesMap["convex"] = true;
154 typesMap["none"] = true; 159 typesMap["none"] = true;
155 typesMap["prim"] = true; 160 typesMap["prim"] = true;
156 m_features["PhysicsShapeTypes"] = typesMap; 161 m_features["PhysicsShapeTypes"] = typesMap;
157 162
158 // Extra information for viewers that want to use it 163 // Extra information for viewers that want to use it
159 // TODO: Take these out of here into their respective modules, like map-server-url 164 // TODO: Take these out of here into their respective modules, like map-server-url
160 OSDMap extrasMap; 165 OSDMap extrasMap;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
index ee1ea1a..39209ec 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.Framework;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Services.Interfaces; 48using OpenSim.Services.Interfaces;
49using OpenSim.Tests.Common; 49using OpenSim.Tests.Common;
50using OpenSim.Tests.Common.Mock;
51using OSDArray = OpenMetaverse.StructuredData.OSDArray; 50using OSDArray = OpenMetaverse.StructuredData.OSDArray;
52using OSDMap = OpenMetaverse.StructuredData.OSDMap; 51using OSDMap = OpenMetaverse.StructuredData.OSDMap;
53 52
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 87192a0..84ca4bb 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Region.ClientStack.Linden
207 207
208 for (uint i = 0; i < 2; i++) 208 for (uint i = 0; i < 2; i++)
209 { 209 {
210 m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests, 210 m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests,
211 String.Format("InventoryWorkerThread{0}", i), 211 String.Format("InventoryWorkerThread{0}", i),
212 ThreadPriority.Normal, 212 ThreadPriority.Normal,
213 false, 213 false,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs
new file mode 100644
index 0000000..6f40b24
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs
@@ -0,0 +1,328 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Concurrent;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Framework.Monitoring;
35using OpenSim.Region.Framework.Scenes;
36
37namespace OpenSim.Region.ClientStack.LindenUDP
38{
39 public class Job
40 {
41 public string Name;
42 public WaitCallback Callback;
43 public object O;
44
45 public Job(string name, WaitCallback callback, object o)
46 {
47 Name = name;
48 Callback = callback;
49 O = o;
50 }
51 }
52
53 // TODO: These kinds of classes MUST be generalized with JobEngine, etc.
54 public class IncomingPacketAsyncHandlingEngine
55 {
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57
58 public int LogLevel { get; set; }
59
60 public bool IsRunning { get; private set; }
61
62 /// <summary>
63 /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
64 /// </summary>
65 public int RequestProcessTimeoutOnStop { get; set; }
66
67 /// <summary>
68 /// Controls whether we need to warn in the log about exceeding the max queue size.
69 /// </summary>
70 /// <remarks>
71 /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
72 /// order to avoid spamming the log with lots of warnings.
73 /// </remarks>
74 private bool m_warnOverMaxQueue = true;
75
76 private BlockingCollection<Job> m_requestQueue;
77
78 private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
79
80 private LLUDPServer m_udpServer;
81
82 private Stat m_requestsWaitingStat;
83
84 private Job m_currentJob;
85
86 /// <summary>
87 /// Used to signal that we are ready to complete stop.
88 /// </summary>
89 private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
90
91 public IncomingPacketAsyncHandlingEngine(LLUDPServer server)
92 {
93 //LogLevel = 1;
94 m_udpServer = server;
95 RequestProcessTimeoutOnStop = 5000;
96
97 // MainConsole.Instance.Commands.AddCommand(
98 // "Debug",
99 // false,
100 // "debug jobengine",
101 // "debug jobengine <start|stop|status>",
102 // "Start, stop or get status of the job engine.",
103 // "If stopped then all jobs are processed immediately.",
104 // HandleControlCommand);
105 }
106
107 public void Start()
108 {
109 lock (this)
110 {
111 if (IsRunning)
112 return;
113
114 IsRunning = true;
115
116 m_finishedProcessingAfterStop.Reset();
117
118 m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
119
120 m_requestsWaitingStat =
121 new Stat(
122 "IncomingPacketAsyncRequestsWaiting",
123 "Number of incoming packets waiting for async processing in engine.",
124 "",
125 "",
126 "clientstack",
127 m_udpServer.Scene.Name,
128 StatType.Pull,
129 MeasuresOfInterest.None,
130 stat => stat.Value = m_requestQueue.Count,
131 StatVerbosity.Debug);
132
133 StatsManager.RegisterStat(m_requestsWaitingStat);
134
135 WorkManager.StartThread(
136 ProcessRequests,
137 string.Format("Incoming Packet Async Handling Engine Thread ({0})", m_udpServer.Scene.Name),
138 ThreadPriority.Normal,
139 false,
140 true,
141 null,
142 int.MaxValue);
143 }
144 }
145
146 public void Stop()
147 {
148 lock (this)
149 {
150 try
151 {
152 if (!IsRunning)
153 return;
154
155 IsRunning = false;
156
157 int requestsLeft = m_requestQueue.Count;
158
159 if (requestsLeft <= 0)
160 {
161 m_cancelSource.Cancel();
162 }
163 else
164 {
165 m_log.InfoFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
166
167 while (requestsLeft > 0)
168 {
169 if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
170 {
171 // After timeout no events have been written
172 if (requestsLeft == m_requestQueue.Count)
173 {
174 m_log.WarnFormat(
175 "[INCOMING PACKET ASYNC HANDLING ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
176 RequestProcessTimeoutOnStop, requestsLeft);
177
178 break;
179 }
180 }
181
182 requestsLeft = m_requestQueue.Count;
183 }
184 }
185 }
186 finally
187 {
188 m_cancelSource.Dispose();
189 StatsManager.DeregisterStat(m_requestsWaitingStat);
190 m_requestsWaitingStat = null;
191 m_requestQueue = null;
192 }
193 }
194 }
195
196 public bool QueueRequest(string name, WaitCallback req, object o)
197 {
198 if (LogLevel >= 1)
199 m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Queued job {0}", name);
200
201 if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
202 {
203 // m_log.DebugFormat(
204 // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
205 // categories, client.AgentID, m_udpServer.Scene.Name);
206
207 m_requestQueue.Add(new Job(name, req, o));
208
209 if (!m_warnOverMaxQueue)
210 m_warnOverMaxQueue = true;
211
212 return true;
213 }
214 else
215 {
216 if (m_warnOverMaxQueue)
217 {
218 // m_log.WarnFormat(
219 // "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
220 // client.AgentID, m_udpServer.Scene.Name);
221
222 m_log.WarnFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Request queue at maximum capacity, not recording job");
223
224 m_warnOverMaxQueue = false;
225 }
226
227 return false;
228 }
229 }
230
231 private void ProcessRequests()
232 {
233 try
234 {
235 while (IsRunning || m_requestQueue.Count > 0)
236 {
237 m_currentJob = m_requestQueue.Take(m_cancelSource.Token);
238
239 // QueueEmpty callback = req.Client.OnQueueEmpty;
240 //
241 // if (callback != null)
242 // {
243 // try
244 // {
245 // callback(req.Categories);
246 // }
247 // catch (Exception e)
248 // {
249 // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
250 // }
251 // }
252
253 if (LogLevel >= 1)
254 m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Processing job {0}", m_currentJob.Name);
255
256 try
257 {
258 m_currentJob.Callback.Invoke(m_currentJob.O);
259 }
260 catch (Exception e)
261 {
262 m_log.Error(
263 string.Format(
264 "[INCOMING PACKET ASYNC HANDLING ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e);
265 }
266
267 if (LogLevel >= 1)
268 m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Processed job {0}", m_currentJob.Name);
269
270 m_currentJob = null;
271 }
272 }
273 catch (OperationCanceledException)
274 {
275 }
276
277 m_finishedProcessingAfterStop.Set();
278 }
279
280 // private void HandleControlCommand(string module, string[] args)
281 // {
282 // // if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
283 // // return;
284 //
285 // if (args.Length < 3)
286 // {
287 // MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>");
288 // return;
289 // }
290 //
291 // string subCommand = args[2];
292 //
293 // if (subCommand == "stop")
294 // {
295 // Stop();
296 // MainConsole.Instance.OutputFormat("Stopped job engine.");
297 // }
298 // else if (subCommand == "start")
299 // {
300 // Start();
301 // MainConsole.Instance.OutputFormat("Started job engine.");
302 // }
303 // else if (subCommand == "status")
304 // {
305 // MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning);
306 // MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none");
307 // MainConsole.Instance.OutputFormat(
308 // "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
309 // MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel);
310 // }
311 //
312 // else if (subCommand == "loglevel")
313 // {
314 // // int logLevel;
315 // int logLevel = int.Parse(args[3]);
316 // // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
317 // // {
318 // LogLevel = logLevel;
319 // MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel);
320 // // }
321 // }
322 // else
323 // {
324 // MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
325 // }
326 // }
327 }
328}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index c839c05..85f9d68 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -648,12 +648,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
648 /// <returns>true if the handler was added. This is currently always the case.</returns> 648 /// <returns>true if the handler was added. This is currently always the case.</returns>
649 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) 649 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
650 { 650 {
651 return AddLocalPacketHandler(packetType, handler, doAsync, false);
652 }
653
654 /// <summary>
655 /// Add a handler for the given packet type.
656 /// </summary>
657 /// <param name="packetType"></param>
658 /// <param name="handler"></param>
659 /// <param name="doAsync">
660 /// If true, when the packet is received handle it on a different thread. Whether this is given direct to
661 /// a threadpool thread or placed in a queue depends on the inEngine parameter.
662 /// </param>
663 /// <param name="inEngine">
664 /// If async is false then this parameter is ignored.
665 /// If async is true and inEngine is false, then the packet is sent directly to a
666 /// threadpool thread.
667 /// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine.
668 /// This may result in slower handling but reduces the risk of overloading the simulator when there are many
669 /// simultaneous async requests.
670 /// </param>
671 /// <returns>true if the handler was added. This is currently always the case.</returns>
672 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine)
673 {
651 bool result = false; 674 bool result = false;
652 lock (m_packetHandlers) 675 lock (m_packetHandlers)
653 { 676 {
654 if (!m_packetHandlers.ContainsKey(packetType)) 677 if (!m_packetHandlers.ContainsKey(packetType))
655 { 678 {
656 m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync }); 679 m_packetHandlers.Add(
680 packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine });
657 result = true; 681 result = true;
658 } 682 }
659 } 683 }
@@ -688,21 +712,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
688 PacketProcessor pprocessor; 712 PacketProcessor pprocessor;
689 if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) 713 if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor))
690 { 714 {
715 ClientInfo cinfo = UDPClient.GetClientInfo();
716
691 //there is a local handler for this packet type 717 //there is a local handler for this packet type
692 if (pprocessor.Async) 718 if (pprocessor.Async)
693 { 719 {
694 ClientInfo cinfo = UDPClient.GetClientInfo();
695 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) 720 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
696 cinfo.AsyncRequests[packet.Type.ToString()] = 0; 721 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
697 cinfo.AsyncRequests[packet.Type.ToString()]++; 722 cinfo.AsyncRequests[packet.Type.ToString()]++;
698 723
699 object obj = new AsyncPacketProcess(this, pprocessor.method, packet); 724 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
700 Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString()); 725
726 if (pprocessor.InEngine)
727 m_udpServer.IpahEngine.QueueRequest(
728 packet.Type.ToString(),
729 ProcessSpecificPacketAsync,
730 obj);
731 else
732 Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString());
733
701 result = true; 734 result = true;
702 } 735 }
703 else 736 else
704 { 737 {
705 ClientInfo cinfo = UDPClient.GetClientInfo();
706 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) 738 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
707 cinfo.SyncRequests[packet.Type.ToString()] = 0; 739 cinfo.SyncRequests[packet.Type.ToString()] = 0;
708 cinfo.SyncRequests[packet.Type.ToString()]++; 740 cinfo.SyncRequests[packet.Type.ToString()]++;
@@ -1161,7 +1193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1161 /// <param name="map">heightmap</param> 1193 /// <param name="map">heightmap</param>
1162 public virtual void SendLayerData(float[] map) 1194 public virtual void SendLayerData(float[] map)
1163 { 1195 {
1164 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData()); 1196 Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData");
1165 } 1197 }
1166 1198
1167 /// <summary> 1199 /// <summary>
@@ -1373,7 +1405,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1373 /// <param name="windSpeeds">16x16 array of wind speeds</param> 1405 /// <param name="windSpeeds">16x16 array of wind speeds</param>
1374 public virtual void SendWindData(Vector2[] windSpeeds) 1406 public virtual void SendWindData(Vector2[] windSpeeds)
1375 { 1407 {
1376 Util.FireAndForget(DoSendWindData, windSpeeds); 1408 Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData");
1377 } 1409 }
1378 1410
1379 /// <summary> 1411 /// <summary>
@@ -1382,7 +1414,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1382 /// <param name="windSpeeds">16x16 array of cloud densities</param> 1414 /// <param name="windSpeeds">16x16 array of cloud densities</param>
1383 public virtual void SendCloudData(float[] cloudDensity) 1415 public virtual void SendCloudData(float[] cloudDensity)
1384 { 1416 {
1385 Util.FireAndForget(DoSendCloudData, cloudDensity); 1417 Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData");
1386 } 1418 }
1387 1419
1388 /// <summary> 1420 /// <summary>
@@ -3834,11 +3866,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3834 /// </summary> 3866 /// </summary>
3835 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3867 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3836 { 3868 {
3837 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3869 if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3838 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3870 {
3871 ImprovedTerseObjectUpdatePacket packet
3872 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3839 3873
3840 lock (m_entityUpdates.SyncRoot) 3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3841 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); 3875 packet.RegionData.TimeDilation = Utils.FloatToUInt16(1, 0.0f, 1.0f);
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
3877 packet.ObjectData[0] = CreateImprovedTerseBlock(entity, false);
3878 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3879 }
3880 else
3881 {
3882 //double priority = m_prioritizer.GetUpdatePriority(this, entity);
3883 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3884
3885 lock (m_entityUpdates.SyncRoot)
3886 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
3887 }
3842 } 3888 }
3843 3889
3844 /// <summary> 3890 /// <summary>
@@ -5540,10 +5586,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5540 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); 5586 AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
5541 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); 5587 AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
5542 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); 5588 AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
5543 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); 5589 AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true);
5544 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); 5590 AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true);
5545 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); 5591 AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
5546 AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); 5592 AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true);
5547 AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); 5593 AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
5548 AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); 5594 AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
5549 AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); 5595 AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
@@ -5728,8 +5774,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5728 AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); 5774 AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete);
5729 AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); 5775 AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete);
5730 AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); 5776 AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate);
5731 AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate); 5777 AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true);
5732 AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate); 5778 AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true);
5733 AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); 5779 AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights);
5734 AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); 5780 AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery);
5735 AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); 5781 AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry);
@@ -8079,7 +8125,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8079 { 8125 {
8080 // This requests the asset if needed 8126 // This requests the asset if needed
8081 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer); 8127 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
8082 }); 8128 }, null, "LLClientView.HandleTransferRequest");
8129
8083 return true; 8130 return true;
8084 } 8131 }
8085 } 8132 }
@@ -12786,8 +12833,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12786 12833
12787 public struct PacketProcessor 12834 public struct PacketProcessor
12788 { 12835 {
12789 public PacketMethod method; 12836 /// <summary>
12790 public bool Async; 12837 /// Packet handling method.
12838 /// </summary>
12839 public PacketMethod method { get; set; }
12840
12841 /// <summary>
12842 /// Should this packet be handled asynchronously?
12843 /// </summary>
12844 public bool Async { get; set; }
12845
12846 /// <summary>
12847 /// If async is true, should this packet be handled in the async engine or given directly to a threadpool
12848 /// thread?
12849 /// </summary>
12850 public bool InEngine { get; set; }
12791 } 12851 }
12792 12852
12793 public class AsyncPacketProcess 12853 public class AsyncPacketProcess
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index d8ca343..8f14806 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -97,7 +97,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
97 { 97 {
98 m_throttleDebugLevel = value; 98 m_throttleDebugLevel = value;
99 m_throttleClient.DebugLevel = m_throttleDebugLevel; 99 m_throttleClient.DebugLevel = m_throttleDebugLevel;
100 m_throttleCategory.DebugLevel = m_throttleDebugLevel;
101 foreach (TokenBucket tb in m_throttleCategories) 100 foreach (TokenBucket tb in m_throttleCategories)
102 tb.DebugLevel = m_throttleDebugLevel; 101 tb.DebugLevel = m_throttleDebugLevel;
103 } 102 }
@@ -172,8 +171,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
172 get { return m_throttleClient; } 171 get { return m_throttleClient; }
173 } 172 }
174 173
175 /// <summary>Throttle bucket for this agent's connection</summary>
176 private readonly TokenBucket m_throttleCategory;
177 /// <summary>Throttle buckets for each packet category</summary> 174 /// <summary>Throttle buckets for each packet category</summary>
178 private readonly TokenBucket[] m_throttleCategories; 175 private readonly TokenBucket[] m_throttleCategories;
179 /// <summary>Outgoing queues for throttled packets</summary> 176 /// <summary>Outgoing queues for throttled packets</summary>
@@ -232,13 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
232 m_throttleClient 229 m_throttleClient
233 = new AdaptiveTokenBucket( 230 = new AdaptiveTokenBucket(
234 string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name), 231 string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
235 parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); 232 parentThrottle, 0, rates.Total, rates.AdaptiveThrottlesEnabled);
236
237 // Create a token bucket throttle for the total category with the client bucket as a throttle
238 m_throttleCategory
239 = new TokenBucket(
240 string.Format("total throttle for {0} in {1}", AgentID, server.Scene.Name),
241 m_throttleClient, 0);
242 233
243 // Create an array of token buckets for this clients different throttle categories 234 // Create an array of token buckets for this clients different throttle categories
244 m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; 235 m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
@@ -256,7 +247,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 m_throttleCategories[i] 247 m_throttleCategories[i]
257 = new TokenBucket( 248 = new TokenBucket(
258 string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name), 249 string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name),
259 m_throttleCategory, rates.GetRate(type)); 250 m_throttleClient, rates.GetRate(type), 0);
260 } 251 }
261 252
262 // Default the retransmission timeout to one second 253 // Default the retransmission timeout to one second
@@ -301,7 +292,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
301 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; 292 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
302 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; 293 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
303 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; 294 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
304 m_info.totalThrottle = (int)m_throttleCategory.DripRate; 295 m_info.totalThrottle = (int)m_throttleClient.DripRate;
296 m_info.targetThrottle = (int)m_throttleClient.TargetDripRate;
305 m_info.maxThrottle = (int)m_throttleClient.MaxDripRate; 297 m_info.maxThrottle = (int)m_throttleClient.MaxDripRate;
306 298
307 return m_info; 299 return m_info;
@@ -320,6 +312,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
320 } 312 }
321 313
322 /// <summary> 314 /// <summary>
315 /// Get the total number of pakcets queued for this client.
316 /// </summary>
317 /// <returns></returns>
318 public int GetTotalPacketsQueuedCount()
319 {
320 int total = 0;
321
322 for (int i = 0; i <= (int)ThrottleOutPacketType.Asset; i++)
323 total += m_packetOutboxes[i].Count;
324
325 return total;
326 }
327
328 /// <summary>
329 /// Get the number of packets queued for the given throttle type.
330 /// </summary>
331 /// <returns></returns>
332 /// <param name="throttleType"></param>
333 public int GetPacketsQueuedCount(ThrottleOutPacketType throttleType)
334 {
335 if ((int)throttleType > 0)
336 return m_packetOutboxes[(int)throttleType].Count;
337 else
338 return 0;
339 }
340
341 /// <summary>
323 /// Return statistics information about client packet queues. 342 /// Return statistics information about client packet queues.
324 /// </summary> 343 /// </summary>
325 /// <remarks> 344 /// <remarks>
@@ -388,6 +407,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
388 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; 407 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
389 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); 408 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
390 409
410 if (ThrottleDebugLevel > 0)
411 {
412 long total = resend + land + wind + cloud + task + texture + asset;
413 m_log.DebugFormat(
414 "[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
415 AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
416 }
417
391 // Make sure none of the throttles are set below our packet MTU, 418 // Make sure none of the throttles are set below our packet MTU,
392 // otherwise a throttle could become permanently clogged 419 // otherwise a throttle could become permanently clogged
393 resend = Math.Max(resend, LLUDPServer.MTU); 420 resend = Math.Max(resend, LLUDPServer.MTU);
@@ -407,11 +434,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
407 //int total = resend + land + wind + cloud + task + texture + asset; 434 //int total = resend + land + wind + cloud + task + texture + asset;
408 435
409 if (ThrottleDebugLevel > 0) 436 if (ThrottleDebugLevel > 0)
437 {
438 long total = resend + land + wind + cloud + task + texture + asset;
410 m_log.DebugFormat( 439 m_log.DebugFormat(
411 "[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}", 440 "[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
412 AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset); 441 AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
442 }
413 443
414 // Update the token buckets with new throttle values 444 // Update the token buckets with new throttle values
445 if (m_throttleClient.AdaptiveEnabled)
446 {
447 long total = resend + land + wind + cloud + task + texture + asset;
448 m_throttleClient.TargetDripRate = total;
449 }
450
415 TokenBucket bucket; 451 TokenBucket bucket;
416 452
417 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; 453 bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
@@ -696,7 +732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
696 if (!m_udpServer.OqrEngine.IsRunning) 732 if (!m_udpServer.OqrEngine.IsRunning)
697 { 733 {
698 // Asynchronously run the callback 734 // Asynchronously run the callback
699 Util.FireAndForget(FireQueueEmpty, categories); 735 Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty");
700 } 736 }
701 else 737 else
702 { 738 {
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 9757d35..2f97516 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -34,7 +34,6 @@ using System.Net.Sockets;
34using System.Reflection; 34using System.Reflection;
35using System.Threading; 35using System.Threading;
36using log4net; 36using log4net;
37using NDesk.Options;
38using Nini.Config; 37using Nini.Config;
39using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
40using OpenSim.Framework; 39using OpenSim.Framework;
@@ -222,6 +221,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
222 /// </summary> 221 /// </summary>
223 public int DefaultClientPacketDebugLevel { get; set; } 222 public int DefaultClientPacketDebugLevel { get; set; }
224 223
224 /// <summary>
225 /// If set then all inbound agent updates are discarded. For debugging purposes.
226 /// discard agent update.
227 /// </summary>
228 public bool DiscardInboundAgentUpdates { get; set; }
229
225 /// <summary>The measured resolution of Environment.TickCount</summary> 230 /// <summary>The measured resolution of Environment.TickCount</summary>
226 public readonly float TickCountResolution; 231 public readonly float TickCountResolution;
227 232
@@ -238,12 +243,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
238 /// <summary>Incoming packets that are awaiting handling</summary> 243 /// <summary>Incoming packets that are awaiting handling</summary>
239 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 244 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
240 245
241 /// <summary></summary>
242 //private UDPClientCollection m_clients = new UDPClientCollection();
243 /// <summary>Bandwidth throttle for this UDP server</summary> 246 /// <summary>Bandwidth throttle for this UDP server</summary>
244 protected TokenBucket m_throttle; 247 public TokenBucket Throttle { get; private set; }
245 248
246 /// <summary>Bandwidth throttle rates for this UDP server</summary> 249 /// <summary>Per client throttle rates enforced by this server</summary>
250 /// <remarks>
251 /// If the total rate is non-zero, then this is the maximum total throttle setting that any client can ever have.
252 /// The other rates (resend, asset, etc.) are the defaults for a new client and can be changed (and usually
253 /// do get changed immediately). They do not need to sum to the total.
254 /// </remarks>
247 public ThrottleRates ThrottleRates { get; private set; } 255 public ThrottleRates ThrottleRates { get; private set; }
248 256
249 /// <summary>Manages authentication for agent circuits</summary> 257 /// <summary>Manages authentication for agent circuits</summary>
@@ -356,6 +364,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
356 private IClientAPI m_currentIncomingClient; 364 private IClientAPI m_currentIncomingClient;
357 365
358 /// <summary> 366 /// <summary>
367 /// Queue some low priority but potentially high volume async requests so that they don't overwhelm available
368 /// threadpool threads.
369 /// </summary>
370 public IncomingPacketAsyncHandlingEngine IpahEngine { get; private set; }
371
372 /// <summary>
359 /// Experimental facility to run queue empty processing within a controlled number of threads rather than 373 /// Experimental facility to run queue empty processing within a controlled number of threads rather than
360 /// requiring massive numbers of short-lived threads from the threadpool when there are a high number of 374 /// requiring massive numbers of short-lived threads from the threadpool when there are a high number of
361 /// connections. 375 /// connections.
@@ -439,13 +453,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439// = new TokenBucket( 453// = new TokenBucket(
440// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps); 454// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps);
441 455
442 m_throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps); 456 Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps);
443 457
444 ThrottleRates = new ThrottleRates(configSource); 458 ThrottleRates = new ThrottleRates(configSource);
445 459
446 if (usePools) 460 if (usePools)
447 EnablePools(); 461 EnablePools();
448 462
463 IpahEngine = new IncomingPacketAsyncHandlingEngine(this);
449 OqrEngine = new OutgoingQueueRefillEngine(this); 464 OqrEngine = new OutgoingQueueRefillEngine(this);
450 } 465 }
451 466
@@ -453,12 +468,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
453 { 468 {
454 StartInbound(); 469 StartInbound();
455 StartOutbound(); 470 StartOutbound();
471 IpahEngine.Start();
456 OqrEngine.Start(); 472 OqrEngine.Start();
457 473
458 m_elapsedMSSinceLastStatReport = Environment.TickCount; 474 m_elapsedMSSinceLastStatReport = Environment.TickCount;
459 } 475 }
460 476
461 private void StartInbound() 477 public void StartInbound()
462 { 478 {
463 m_log.InfoFormat( 479 m_log.InfoFormat(
464 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", 480 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
@@ -467,7 +483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
467 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); 483 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
468 484
469 // This thread will process the packets received that are placed on the packetInbox 485 // This thread will process the packets received that are placed on the packetInbox
470 Watchdog.StartThread( 486 WorkManager.StartThread(
471 IncomingPacketHandler, 487 IncomingPacketHandler,
472 string.Format("Incoming Packets ({0})", Scene.Name), 488 string.Format("Incoming Packets ({0})", Scene.Name),
473 ThreadPriority.Normal, 489 ThreadPriority.Normal,
@@ -477,13 +493,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
477 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 493 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
478 } 494 }
479 495
480 private new void StartOutbound() 496 public override void StartOutbound()
481 { 497 {
482 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); 498 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
483 499
484 base.StartOutbound(); 500 base.StartOutbound();
485 501
486 Watchdog.StartThread( 502 WorkManager.StartThread(
487 OutgoingPacketHandler, 503 OutgoingPacketHandler,
488 string.Format("Outgoing Packets ({0})", Scene.Name), 504 string.Format("Outgoing Packets ({0})", Scene.Name),
489 ThreadPriority.Normal, 505 ThreadPriority.Normal,
@@ -498,10 +514,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
498 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name); 514 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
499 base.StopOutbound(); 515 base.StopOutbound();
500 base.StopInbound(); 516 base.StopInbound();
517 IpahEngine.Stop();
501 OqrEngine.Stop(); 518 OqrEngine.Stop();
502 } 519 }
503 520
504 protected override bool EnablePools() 521 public override bool EnablePools()
505 { 522 {
506 if (!UsePools) 523 if (!UsePools)
507 { 524 {
@@ -515,7 +532,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
515 return false; 532 return false;
516 } 533 }
517 534
518 protected override bool DisablePools() 535 public override bool DisablePools()
519 { 536 {
520 if (UsePools) 537 if (UsePools)
521 { 538 {
@@ -535,7 +552,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
535 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene 552 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
536 /// stats. 553 /// stats.
537 /// </summary> 554 /// </summary>
538 private void EnablePoolStats() 555 protected internal void EnablePoolStats()
539 { 556 {
540 m_poolCountStat 557 m_poolCountStat
541 = new Stat( 558 = new Stat(
@@ -569,7 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
569 /// <summary> 586 /// <summary>
570 /// Disables pool stats. 587 /// Disables pool stats.
571 /// </summary> 588 /// </summary>
572 private void DisablePoolStats() 589 protected internal void DisablePoolStats()
573 { 590 {
574 StatsManager.DeregisterStat(m_poolCountStat); 591 StatsManager.DeregisterStat(m_poolCountStat);
575 m_poolCountStat = null; 592 m_poolCountStat = null;
@@ -683,434 +700,45 @@ namespace OpenSim.Region.ClientStack.LindenUDP
683 StatType.Pull, 700 StatType.Pull,
684 stat => stat.Value = PacketPool.Instance.BlocksPooled, 701 stat => stat.Value = PacketPool.Instance.BlocksPooled,
685 StatVerbosity.Debug)); 702 StatVerbosity.Debug));
703
704 StatsManager.RegisterStat(
705 new Stat(
706 "OutgoingPacketsQueuedCount",
707 "Packets queued for outgoing send",
708 "Number of queued outgoing packets across all connections",
709 "",
710 "clientstack",
711 Scene.Name,
712 StatType.Pull,
713 MeasuresOfInterest.AverageChangeOverTime,
714 stat => stat.Value = GetTotalQueuedOutgoingPackets(),
715 StatVerbosity.Info));
686 716
687 // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by 717 // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
688 // scene name 718 // scene name
689 if (UsePools) 719 if (UsePools)
690 EnablePoolStats(); 720 EnablePoolStats();
691 721
692 MainConsole.Instance.Commands.AddCommand( 722 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
693 "Debug", false, "debug lludp packet", 723 commands.Register();
694 "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
695 "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
696 "If level > 255 then all incoming and outgoing packets are logged.\n"
697 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
698 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
699 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
700 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
701 + "If level <= 0 then no packets are logged.\n"
702 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
703 + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
704 + "In these cases, you cannot also specify an avatar name.\n"
705 + "If an avatar name is given then only packets from that avatar are logged.",
706 HandlePacketCommand);
707
708 MainConsole.Instance.Commands.AddCommand(
709 "Debug", false, "debug lludp data out",
710 "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
711 "Turn on debugging for final outgoing data to the given user's client.",
712 "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
713 + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
714 + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
715 HandleDataCommand);
716
717 MainConsole.Instance.Commands.AddCommand(
718 "Debug", false, "debug lludp drop",
719 "debug lludp drop <in|out> <add|remove> <packet-name>",
720 "Drop all in or outbound packets that match the given name",
721 "For test purposes.",
722 HandleDropCommand);
723
724 MainConsole.Instance.Commands.AddCommand(
725 "Debug",
726 false,
727 "debug lludp start",
728 "debug lludp start <in|out|all>",
729 "Control LLUDP packet processing.",
730 "No effect if packet processing has already started.\n"
731 + "in - start inbound processing.\n"
732 + "out - start outbound processing.\n"
733 + "all - start in and outbound processing.\n",
734 HandleStartCommand);
735
736 MainConsole.Instance.Commands.AddCommand(
737 "Debug",
738 false,
739 "debug lludp stop",
740 "debug lludp stop <in|out|all>",
741 "Stop LLUDP packet processing.",
742 "No effect if packet processing has already stopped.\n"
743 + "in - stop inbound processing.\n"
744 + "out - stop outbound processing.\n"
745 + "all - stop in and outbound processing.\n",
746 HandleStopCommand);
747
748 MainConsole.Instance.Commands.AddCommand(
749 "Debug",
750 false,
751 "debug lludp pool",
752 "debug lludp pool <on|off>",
753 "Turn object pooling within the lludp component on or off.",
754 HandlePoolCommand);
755
756 MainConsole.Instance.Commands.AddCommand(
757 "Debug",
758 false,
759 "debug lludp status",
760 "debug lludp status",
761 "Return status of LLUDP packet processing.",
762 HandleStatusCommand);
763
764 MainConsole.Instance.Commands.AddCommand(
765 "Debug",
766 false,
767 "debug lludp throttle log",
768 "debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>",
769 "Change debug logging level for throttles.",
770 "If level >= 0 then throttle debug logging is performed.\n"
771 + "If level <= 0 then no throttle debug logging is performed.",
772 HandleThrottleCommand);
773
774 MainConsole.Instance.Commands.AddCommand(
775 "Debug",
776 false,
777 "debug lludp throttle status",
778 "debug lludp throttle status <avatar-first-name> <avatar-last-name>",
779 "Return status information about throttles.",
780 HandleThrottleStatusCommand);
781
782 MainConsole.Instance.Commands.AddCommand(
783 "Debug",
784 false,
785 "debug lludp toggle agentupdate",
786 "debug lludp toggle agentupdate",
787 "Toggle whether agentupdate packets are processed or simply discarded.",
788 HandleAgentUpdateCommand);
789 }
790
791 private void HandleDataCommand(string module, string[] args)
792 {
793 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
794 return;
795
796 if (args.Length != 7)
797 {
798 MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
799 return;
800 }
801
802 int level;
803 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
804 return;
805
806 string firstName = args[5];
807 string lastName = args[6];
808
809 Scene.ForEachScenePresence(sp =>
810 {
811 if (sp.Firstname == firstName && sp.Lastname == lastName)
812 {
813 MainConsole.Instance.OutputFormat(
814 "Data debug for {0} ({1}) set to {2} in {3}",
815 sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name);
816
817 ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
818 }
819 });
820 } 724 }
821 725
822 private void HandleThrottleCommand(string module, string[] args) 726 public bool HandlesRegion(Location x)
823 {
824 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
825 return;
826
827 if (args.Length != 7)
828 {
829 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>");
830 return;
831 }
832
833 int level;
834 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
835 return;
836
837 string firstName = args[5];
838 string lastName = args[6];
839
840 Scene.ForEachScenePresence(sp =>
841 {
842 if (sp.Firstname == firstName && sp.Lastname == lastName)
843 {
844 MainConsole.Instance.OutputFormat(
845 "Throttle log level for {0} ({1}) set to {2} in {3}",
846 sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name);
847
848 ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
849 }
850 });
851 }
852
853 private void HandleThrottleStatusCommand(string module, string[] args)
854 {
855 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
856 return;
857
858 if (args.Length != 6)
859 {
860 MainConsole.Instance.OutputFormat("Usage: debug lludp throttle status <avatar-first-name> <avatar-last-name>");
861 return;
862 }
863
864 string firstName = args[4];
865 string lastName = args[5];
866
867 Scene.ForEachScenePresence(sp =>
868 {
869 if (sp.Firstname == firstName && sp.Lastname == lastName)
870 {
871 MainConsole.Instance.OutputFormat(
872 "Status for {0} ({1}) in {2}",
873 sp.Name, sp.IsChildAgent ? "child" : "root", Scene.Name);
874
875 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
876 MainConsole.Instance.OutputFormat("Adaptive throttle: {0}", udpClient.FlowThrottle.Enabled);
877 }
878 });
879 }
880
881 private void HandlePacketCommand(string module, string[] args)
882 {
883 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
884 return;
885
886 bool setAsDefaultLevel = false;
887 bool setAll = false;
888 OptionSet optionSet = new OptionSet()
889 .Add("default", o => setAsDefaultLevel = (o != null))
890 .Add("all", o => setAll = (o != null));
891 List<string> filteredArgs = optionSet.Parse(args);
892
893 string name = null;
894
895 if (filteredArgs.Count == 6)
896 {
897 if (!(setAsDefaultLevel || setAll))
898 {
899 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
900 }
901 else
902 {
903 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
904 return;
905 }
906 }
907
908 if (filteredArgs.Count > 3)
909 {
910 int newDebug;
911 if (int.TryParse(filteredArgs[3], out newDebug))
912 {
913 if (setAsDefaultLevel || setAll)
914 {
915 DefaultClientPacketDebugLevel = newDebug;
916
917 MainConsole.Instance.OutputFormat(
918 "Packet debug for {0} clients set to {1} in {2}",
919 (setAll ? "all" : "future"), DefaultClientPacketDebugLevel, Scene.Name);
920
921 if (setAll)
922 {
923 Scene.ForEachScenePresence(sp =>
924 {
925 MainConsole.Instance.OutputFormat(
926 "Packet debug for {0} ({1}) set to {2} in {3}",
927 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
928
929 sp.ControllingClient.DebugPacketLevel = newDebug;
930 });
931 }
932 }
933 else
934 {
935 Scene.ForEachScenePresence(sp =>
936 {
937 if (name == null || sp.Name == name)
938 {
939 MainConsole.Instance.OutputFormat(
940 "Packet debug for {0} ({1}) set to {2} in {3}",
941 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name);
942
943 sp.ControllingClient.DebugPacketLevel = newDebug;
944 }
945 });
946 }
947 }
948 else
949 {
950 MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
951 }
952 }
953 }
954
955 private void HandleDropCommand(string module, string[] args)
956 {
957 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
958 return;
959
960 if (args.Length != 6)
961 {
962 MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
963 return;
964 }
965
966 string direction = args[3];
967 string subCommand = args[4];
968 string packetName = args[5];
969
970 if (subCommand == "add")
971 {
972 MainConsole.Instance.OutputFormat(
973 "Adding packet {0} to {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
974
975 Scene.ForEachScenePresence(
976 sp =>
977 {
978 LLClientView llcv = (LLClientView)sp.ControllingClient;
979
980 if (direction == "in")
981 llcv.AddInPacketToDropSet(packetName);
982 else if (direction == "out")
983 llcv.AddOutPacketToDropSet(packetName);
984 }
985 );
986 }
987 else if (subCommand == "remove")
988 {
989 MainConsole.Instance.OutputFormat(
990 "Removing packet {0} from {1} drop list for all connections in {2}", direction, packetName, Scene.Name);
991
992 Scene.ForEachScenePresence(
993 sp =>
994 {
995 LLClientView llcv = (LLClientView)sp.ControllingClient;
996
997 if (direction == "in")
998 llcv.RemoveInPacketFromDropSet(packetName);
999 else if (direction == "out")
1000 llcv.RemoveOutPacketFromDropSet(packetName);
1001 }
1002 );
1003 }
1004 }
1005
1006 private void HandleStartCommand(string module, string[] args)
1007 {
1008 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1009 return;
1010
1011 if (args.Length != 4)
1012 {
1013 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
1014 return;
1015 }
1016
1017 string subCommand = args[3];
1018
1019 if (subCommand == "in" || subCommand == "all")
1020 StartInbound();
1021
1022 if (subCommand == "out" || subCommand == "all")
1023 StartOutbound();
1024 }
1025
1026 private void HandleStopCommand(string module, string[] args)
1027 { 727 {
1028 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) 728 return x == m_location;
1029 return;
1030
1031 if (args.Length != 4)
1032 {
1033 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
1034 return;
1035 }
1036
1037 string subCommand = args[3];
1038
1039 if (subCommand == "in" || subCommand == "all")
1040 StopInbound();
1041
1042 if (subCommand == "out" || subCommand == "all")
1043 StopOutbound();
1044 } 729 }
1045 730
1046 private void HandlePoolCommand(string module, string[] args) 731 public int GetTotalQueuedOutgoingPackets()
1047 { 732 {
1048 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) 733 int total = 0;
1049 return;
1050 734
1051 if (args.Length != 4) 735 foreach (ScenePresence sp in Scene.GetScenePresences())
1052 { 736 {
1053 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); 737 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
1054 return; 738 total += udpClient.GetTotalPacketsQueuedCount();
1055 } 739 }
1056 740
1057 string enabled = args[3]; 741 return total;
1058
1059 if (enabled == "on")
1060 {
1061 if (EnablePools())
1062 {
1063 EnablePoolStats();
1064 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", Scene.Name);
1065 }
1066 }
1067 else if (enabled == "off")
1068 {
1069 if (DisablePools())
1070 {
1071 DisablePoolStats();
1072 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", Scene.Name);
1073 }
1074 }
1075 else
1076 {
1077 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
1078 }
1079 }
1080
1081 bool m_discardAgentUpdates;
1082
1083 private void HandleAgentUpdateCommand(string module, string[] args)
1084 {
1085 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1086 return;
1087
1088 m_discardAgentUpdates = !m_discardAgentUpdates;
1089
1090 MainConsole.Instance.OutputFormat(
1091 "Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, Scene.Name);
1092 }
1093
1094 private void HandleStatusCommand(string module, string[] args)
1095 {
1096 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene)
1097 return;
1098
1099 MainConsole.Instance.OutputFormat(
1100 "IN LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningInbound ? "enabled" : "disabled");
1101
1102 MainConsole.Instance.OutputFormat(
1103 "OUT LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningOutbound ? "enabled" : "disabled");
1104
1105 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", Scene.Name, UsePools ? "on" : "off");
1106
1107 MainConsole.Instance.OutputFormat(
1108 "Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
1109 }
1110
1111 public bool HandlesRegion(Location x)
1112 {
1113 return x == m_location;
1114 } 742 }
1115 743
1116// public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) 744// public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
@@ -1279,6 +907,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1279 // packet so that it isn't sent before a queued update packet. 907 // packet so that it isn't sent before a queued update packet.
1280 bool forceQueue = (type == PacketType.KillObject); 908 bool forceQueue = (type == PacketType.KillObject);
1281 909
910// if (type == PacketType.ImprovedTerseObjectUpdate)
911// {
912// m_log.DebugFormat("Direct send ITOU to {0} in {1}", udpClient.AgentID, Scene.Name);
913// SendPacketFinal(outgoingPacket);
914// return false;
915// }
916// else
917// {
1282 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue)) 918 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
1283 { 919 {
1284 SendPacketFinal(outgoingPacket); 920 SendPacketFinal(outgoingPacket);
@@ -1288,6 +924,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1288 { 924 {
1289 return false; 925 return false;
1290 } 926 }
927// }
1291 928
1292 #endregion Queue or Send 929 #endregion Queue or Send
1293 } 930 }
@@ -1363,7 +1000,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1363 // Fire this out on a different thread so that we don't hold up outgoing packet processing for 1000 // Fire this out on a different thread so that we don't hold up outgoing packet processing for
1364 // everybody else if this is being called due to an ack timeout. 1001 // everybody else if this is being called due to an ack timeout.
1365 // This is the same as processing as the async process of a logout request. 1002 // This is the same as processing as the async process of a logout request.
1366 Util.FireAndForget(o => DeactivateClientDueToTimeout(client, timeoutTicks)); 1003 Util.FireAndForget(
1004 o => DeactivateClientDueToTimeout(client, timeoutTicks), null, "LLUDPServer.DeactivateClientDueToTimeout");
1367 1005
1368 return; 1006 return;
1369 } 1007 }
@@ -1597,7 +1235,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1597 // buffer. 1235 // buffer.
1598 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1236 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1599 1237
1600 Util.FireAndForget(HandleUseCircuitCode, array); 1238 Util.FireAndForget(HandleUseCircuitCode, array, "LLUDPServer.HandleUseCircuitCode");
1601 1239
1602 return; 1240 return;
1603 } 1241 }
@@ -1610,7 +1248,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1610 // buffer. 1248 // buffer.
1611 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1249 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1612 1250
1613 Util.FireAndForget(HandleCompleteMovementIntoRegion, array); 1251 Util.FireAndForget(
1252 HandleCompleteMovementIntoRegion, array, "LLUDPServer.HandleCompleteMovementIntoRegion");
1614 1253
1615 return; 1254 return;
1616 } 1255 }
@@ -1732,7 +1371,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1732 1371
1733 if (packet.Type == PacketType.AgentUpdate) 1372 if (packet.Type == PacketType.AgentUpdate)
1734 { 1373 {
1735 if (m_discardAgentUpdates) 1374 if (DiscardInboundAgentUpdates)
1736 return; 1375 return;
1737 1376
1738 ((LLClientView)client).TotalAgentUpdates++; 1377 ((LLClientView)client).TotalAgentUpdates++;
@@ -2140,7 +1779,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2140 { 1779 {
2141 if (!Scene.TryGetClient(agentID, out client)) 1780 if (!Scene.TryGetClient(agentID, out client))
2142 { 1781 {
2143 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 1782 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, Throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
2144 1783
2145 client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 1784 client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
2146 client.OnLogout += LogoutHandler; 1785 client.OnLogout += LogoutHandler;
@@ -2183,6 +1822,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2183 1822
2184 private void IncomingPacketHandler() 1823 private void IncomingPacketHandler()
2185 { 1824 {
1825 Thread.CurrentThread.Priority = ThreadPriority.Highest;
1826
2186 // Set this culture for the thread that incoming packets are received 1827 // Set this culture for the thread that incoming packets are received
2187 // on to en-US to avoid number parsing issues 1828 // on to en-US to avoid number parsing issues
2188 Culture.SetCurrentCulture(); 1829 Culture.SetCurrentCulture();
@@ -2228,6 +1869,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2228 1869
2229 private void OutgoingPacketHandler() 1870 private void OutgoingPacketHandler()
2230 { 1871 {
1872 Thread.CurrentThread.Priority = ThreadPriority.Highest;
1873
2231 // Set this culture for the thread that outgoing packets are sent 1874 // Set this culture for the thread that outgoing packets are sent
2232 // on to en-US to avoid number parsing issues 1875 // on to en-US to avoid number parsing issues
2233 Culture.SetCurrentCulture(); 1876 Culture.SetCurrentCulture();
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
new file mode 100644
index 0000000..e0398d5
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
@@ -0,0 +1,762 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using NDesk.Options;
32using OpenSim.Framework;
33using OpenSim.Framework.Console;
34using OpenSim.Region.Framework.Scenes;
35
36namespace OpenSim.Region.ClientStack.LindenUDP
37{
38 public class LLUDPServerCommands
39 {
40 private ICommandConsole m_console;
41 private LLUDPServer m_udpServer;
42
43 public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer)
44 {
45 m_console = console;
46 m_udpServer = udpServer;
47 }
48
49 public void Register()
50 {
51 m_console.Commands.AddCommand(
52 "Comms", false, "show server throttles",
53 "show server throttles",
54 "Show information about server throttles",
55 HandleShowServerThrottlesCommand);
56
57 m_console.Commands.AddCommand(
58 "Debug", false, "debug lludp packet",
59 "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
60 "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
61 "If level > 255 then all incoming and outgoing packets are logged.\n"
62 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
63 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
64 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
65 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
66 + "If level <= 0 then no packets are logged.\n"
67 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
68 + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
69 + "In these cases, you cannot also specify an avatar name.\n"
70 + "If an avatar name is given then only packets from that avatar are logged.",
71 HandlePacketCommand);
72
73 m_console.Commands.AddCommand(
74 "Debug", false, "debug lludp data out",
75 "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
76 "Turn on debugging for final outgoing data to the given user's client.",
77 "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
78 + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
79 + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
80 HandleDataCommand);
81
82 m_console.Commands.AddCommand(
83 "Debug", false, "debug lludp drop",
84 "debug lludp drop <in|out> <add|remove> <packet-name>",
85 "Drop all in or outbound packets that match the given name",
86 "For test purposes.",
87 HandleDropCommand);
88
89 m_console.Commands.AddCommand(
90 "Debug",
91 false,
92 "debug lludp start",
93 "debug lludp start <in|out|all>",
94 "Control LLUDP packet processing.",
95 "No effect if packet processing has already started.\n"
96 + "in - start inbound processing.\n"
97 + "out - start outbound processing.\n"
98 + "all - start in and outbound processing.\n",
99 HandleStartCommand);
100
101 m_console.Commands.AddCommand(
102 "Debug",
103 false,
104 "debug lludp stop",
105 "debug lludp stop <in|out|all>",
106 "Stop LLUDP packet processing.",
107 "No effect if packet processing has already stopped.\n"
108 + "in - stop inbound processing.\n"
109 + "out - stop outbound processing.\n"
110 + "all - stop in and outbound processing.\n",
111 HandleStopCommand);
112
113 m_console.Commands.AddCommand(
114 "Debug",
115 false,
116 "debug lludp pool",
117 "debug lludp pool <on|off>",
118 "Turn object pooling within the lludp component on or off.",
119 HandlePoolCommand);
120
121 m_console.Commands.AddCommand(
122 "Debug",
123 false,
124 "debug lludp status",
125 "debug lludp status",
126 "Return status of LLUDP packet processing.",
127 HandleStatusCommand);
128
129 m_console.Commands.AddCommand(
130 "Debug",
131 false,
132 "debug lludp throttles log",
133 "debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]",
134 "Change debug logging level for throttles.",
135 "If level >= 0 then throttle debug logging is performed.\n"
136 + "If level <= 0 then no throttle debug logging is performed.",
137 HandleThrottleCommand);
138
139 m_console.Commands.AddCommand(
140 "Debug",
141 false,
142 "debug lludp throttles get",
143 "debug lludp throttles get [<avatar-first-name> <avatar-last-name>]",
144 "Return debug settings for throttles.",
145 "adaptive - true/false, controls adaptive throttle setting.\n"
146 + "request - request drip rate in kbps.\n"
147 + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp get new-client-throttle-max' to see the setting for new clients.\n",
148 HandleThrottleGetCommand);
149
150 m_console.Commands.AddCommand(
151 "Debug",
152 false,
153 "debug lludp throttles set",
154 "debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]",
155 "Set a throttle parameter for the given client.",
156 "adaptive - true/false, controls adaptive throttle setting.\n"
157 + "current - current drip rate in kbps.\n"
158 + "request - requested drip rate in kbps.\n"
159 + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp set new-client-throttle-max' to change the settings for new clients.\n",
160 HandleThrottleSetCommand);
161
162 m_console.Commands.AddCommand(
163 "Debug",
164 false,
165 "debug lludp get",
166 "debug lludp get",
167 "Get debug parameters for the server.",
168 "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n"
169 + "max-new-client-throttle - the max kbps throttle allowed to new clients. Use 'debug lludp throttles get max' to see the settings for existing clients.",
170 HandleGetCommand);
171
172 m_console.Commands.AddCommand(
173 "Debug",
174 false,
175 "debug lludp set",
176 "debug lludp set <param> <value>",
177 "Set a parameter for the server.",
178 "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n"
179 + "max-new-client-throttle - the max kbps throttle allowed to each new client. Use 'debug lludp throttles set max' to set for existing clients.",
180 HandleSetCommand);
181
182 m_console.Commands.AddCommand(
183 "Debug",
184 false,
185 "debug lludp toggle agentupdate",
186 "debug lludp toggle agentupdate",
187 "Toggle whether agentupdate packets are processed or simply discarded.",
188 HandleAgentUpdateCommand);
189 }
190
191 private void HandleShowServerThrottlesCommand(string module, string[] args)
192 {
193 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
194 return;
195
196 m_console.OutputFormat("Throttles for {0}", m_udpServer.Scene.Name);
197 ConsoleDisplayList cdl = new ConsoleDisplayList();
198 cdl.AddRow("Adaptive throttles", m_udpServer.ThrottleRates.AdaptiveThrottlesEnabled);
199
200 long maxSceneDripRate = m_udpServer.Throttle.MaxDripRate;
201 cdl.AddRow(
202 "Max scene throttle",
203 maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
204
205 int maxClientDripRate = m_udpServer.ThrottleRates.Total;
206 cdl.AddRow(
207 "Max new client throttle",
208 maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
209
210 m_console.Output(cdl.ToString());
211
212 m_console.OutputFormat("{0}\n", GetServerThrottlesReport(m_udpServer));
213 }
214
215 private string GetServerThrottlesReport(LLUDPServer udpServer)
216 {
217 StringBuilder report = new StringBuilder();
218
219 report.AppendFormat(
220 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
221 "Total",
222 "Resend",
223 "Land",
224 "Wind",
225 "Cloud",
226 "Task",
227 "Texture",
228 "Asset");
229
230 report.AppendFormat(
231 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
232 "kb/s",
233 "kb/s",
234 "kb/s",
235 "kb/s",
236 "kb/s",
237 "kb/s",
238 "kb/s",
239 "kb/s");
240
241 ThrottleRates throttleRates = udpServer.ThrottleRates;
242 report.AppendFormat(
243 "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
244 (throttleRates.Total * 8) / 1000,
245 (throttleRates.Resend * 8) / 1000,
246 (throttleRates.Land * 8) / 1000,
247 (throttleRates.Wind * 8) / 1000,
248 (throttleRates.Cloud * 8) / 1000,
249 (throttleRates.Task * 8) / 1000,
250 (throttleRates.Texture * 8) / 1000,
251 (throttleRates.Asset * 8) / 1000);
252
253 return report.ToString();
254 }
255
256 protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
257 {
258 return string.Format(
259 "{0,-" + maxLength + "}{1,-" + columnPadding + "}",
260 entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
261 "");
262 }
263
264 private void HandleDataCommand(string module, string[] args)
265 {
266 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
267 return;
268
269 if (args.Length != 7)
270 {
271 MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
272 return;
273 }
274
275 int level;
276 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
277 return;
278
279 string firstName = args[5];
280 string lastName = args[6];
281
282 m_udpServer.Scene.ForEachScenePresence(sp =>
283 {
284 if (sp.Firstname == firstName && sp.Lastname == lastName)
285 {
286 MainConsole.Instance.OutputFormat(
287 "Data debug for {0} ({1}) set to {2} in {3}",
288 sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
289
290 ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
291 }
292 });
293 }
294
295 private void HandleThrottleCommand(string module, string[] args)
296 {
297 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
298 return;
299
300 bool all = args.Length == 5;
301 bool one = args.Length == 7;
302
303 if (!all && !one)
304 {
305 MainConsole.Instance.OutputFormat(
306 "Usage: debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]");
307 return;
308 }
309
310 int level;
311 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
312 return;
313
314 string firstName = null;
315 string lastName = null;
316
317 if (one)
318 {
319 firstName = args[5];
320 lastName = args[6];
321 }
322
323 m_udpServer.Scene.ForEachScenePresence(sp =>
324 {
325 if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
326 {
327 MainConsole.Instance.OutputFormat(
328 "Throttle log level for {0} ({1}) set to {2} in {3}",
329 sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
330
331 ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
332 }
333 });
334 }
335
336 private void HandleThrottleSetCommand(string module, string[] args)
337 {
338 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
339 return;
340
341 bool all = args.Length == 6;
342 bool one = args.Length == 8;
343
344 if (!all && !one)
345 {
346 MainConsole.Instance.OutputFormat(
347 "Usage: debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]");
348 return;
349 }
350
351 string param = args[4];
352 string rawValue = args[5];
353
354 string firstName = null;
355 string lastName = null;
356
357 if (one)
358 {
359 firstName = args[6];
360 lastName = args[7];
361 }
362
363 if (param == "adaptive")
364 {
365 bool newValue;
366 if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue))
367 return;
368
369 m_udpServer.Scene.ForEachScenePresence(sp =>
370 {
371 if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
372 {
373 MainConsole.Instance.OutputFormat(
374 "Setting param {0} to {1} for {2} ({3}) in {4}",
375 param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
376
377 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
378 udpClient.FlowThrottle.AdaptiveEnabled = newValue;
379 // udpClient.FlowThrottle.MaxDripRate = 0;
380 // udpClient.FlowThrottle.AdjustedDripRate = 0;
381 }
382 });
383 }
384 else if (param == "request")
385 {
386 int newValue;
387 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
388 return;
389
390 int newCurrentThrottleKbps = newValue * 1000 / 8;
391
392 m_udpServer.Scene.ForEachScenePresence(sp =>
393 {
394 if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
395 {
396 MainConsole.Instance.OutputFormat(
397 "Setting param {0} to {1} for {2} ({3}) in {4}",
398 param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
399
400 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
401 udpClient.FlowThrottle.RequestedDripRate = newCurrentThrottleKbps;
402 }
403 });
404 }
405 else if (param == "max")
406 {
407 int newValue;
408 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
409 return;
410
411 int newThrottleMaxKbps = newValue * 1000 / 8;
412
413 m_udpServer.Scene.ForEachScenePresence(sp =>
414 {
415 if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
416 {
417 MainConsole.Instance.OutputFormat(
418 "Setting param {0} to {1} for {2} ({3}) in {4}",
419 param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
420
421 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
422 udpClient.FlowThrottle.MaxDripRate = newThrottleMaxKbps;
423 }
424 });
425 }
426 }
427
428 private void HandleThrottleGetCommand(string module, string[] args)
429 {
430 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
431 return;
432
433 bool all = args.Length == 4;
434 bool one = args.Length == 6;
435
436 if (!all && !one)
437 {
438 MainConsole.Instance.OutputFormat(
439 "Usage: debug lludp throttles get [<avatar-first-name> <avatar-last-name>]");
440 return;
441 }
442
443 string firstName = null;
444 string lastName = null;
445
446 if (one)
447 {
448 firstName = args[4];
449 lastName = args[5];
450 }
451
452 m_udpServer.Scene.ForEachScenePresence(sp =>
453 {
454 if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
455 {
456 m_console.OutputFormat(
457 "Status for {0} ({1}) in {2}",
458 sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
459
460 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
461
462 ConsoleDisplayList cdl = new ConsoleDisplayList();
463 cdl.AddRow("adaptive", udpClient.FlowThrottle.AdaptiveEnabled);
464 cdl.AddRow("current", string.Format("{0} kbps", udpClient.FlowThrottle.DripRate * 8 / 1000));
465 cdl.AddRow("request", string.Format("{0} kbps", udpClient.FlowThrottle.RequestedDripRate * 8 / 1000));
466 cdl.AddRow("max", string.Format("{0} kbps", udpClient.FlowThrottle.MaxDripRate * 8 / 1000));
467
468 m_console.Output(cdl.ToString());
469 }
470 });
471 }
472
473 private void HandleGetCommand(string module, string[] args)
474 {
475 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
476 return;
477
478 m_console.OutputFormat("Debug settings for {0}", m_udpServer.Scene.Name);
479 ConsoleDisplayList cdl = new ConsoleDisplayList();
480
481 long maxSceneDripRate = m_udpServer.Throttle.MaxDripRate;
482 cdl.AddRow(
483 "max-scene-throttle",
484 maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
485
486 int maxClientDripRate = m_udpServer.ThrottleRates.Total;
487 cdl.AddRow(
488 "max-new-client-throttle",
489 maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
490
491 m_console.Output(cdl.ToString());
492 }
493
494 private void HandleSetCommand(string module, string[] args)
495 {
496 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
497 return;
498
499 if (args.Length != 5)
500 {
501 MainConsole.Instance.OutputFormat("Usage: debug lludp set <param> <value>");
502 return;
503 }
504
505 string param = args[3];
506 string rawValue = args[4];
507
508 int newValue;
509
510 if (param == "max-scene-throttle")
511 {
512 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
513 return;
514
515 m_udpServer.Throttle.MaxDripRate = newValue * 1000 / 8;
516 }
517 else if (param == "max-new-client-throttle")
518 {
519 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
520 return;
521
522 m_udpServer.ThrottleRates.Total = newValue * 1000 / 8;
523 }
524 else
525 {
526 return;
527 }
528
529 m_console.OutputFormat("{0} set to {1} in {2}", param, rawValue, m_udpServer.Scene.Name);
530 }
531
532 private void HandlePacketCommand(string module, string[] args)
533 {
534 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
535 return;
536
537 bool setAsDefaultLevel = false;
538 bool setAll = false;
539 OptionSet optionSet = new OptionSet()
540 .Add("default", o => setAsDefaultLevel = (o != null))
541 .Add("all", o => setAll = (o != null));
542 List<string> filteredArgs = optionSet.Parse(args);
543
544 string name = null;
545
546 if (filteredArgs.Count == 6)
547 {
548 if (!(setAsDefaultLevel || setAll))
549 {
550 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
551 }
552 else
553 {
554 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
555 return;
556 }
557 }
558
559 if (filteredArgs.Count > 3)
560 {
561 int newDebug;
562 if (int.TryParse(filteredArgs[3], out newDebug))
563 {
564 if (setAsDefaultLevel || setAll)
565 {
566 m_udpServer.DefaultClientPacketDebugLevel = newDebug;
567
568 MainConsole.Instance.OutputFormat(
569 "Packet debug for {0} clients set to {1} in {2}",
570 (setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name);
571
572 if (setAll)
573 {
574 m_udpServer.Scene.ForEachScenePresence(sp =>
575 {
576 MainConsole.Instance.OutputFormat(
577 "Packet debug for {0} ({1}) set to {2} in {3}",
578 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
579
580 sp.ControllingClient.DebugPacketLevel = newDebug;
581 });
582 }
583 }
584 else
585 {
586 m_udpServer.Scene.ForEachScenePresence(sp =>
587 {
588 if (name == null || sp.Name == name)
589 {
590 MainConsole.Instance.OutputFormat(
591 "Packet debug for {0} ({1}) set to {2} in {3}",
592 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
593
594 sp.ControllingClient.DebugPacketLevel = newDebug;
595 }
596 });
597 }
598 }
599 else
600 {
601 MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
602 }
603 }
604 }
605
606 private void HandleDropCommand(string module, string[] args)
607 {
608 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
609 return;
610
611 if (args.Length != 6)
612 {
613 MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
614 return;
615 }
616
617 string direction = args[3];
618 string subCommand = args[4];
619 string packetName = args[5];
620
621 if (subCommand == "add")
622 {
623 MainConsole.Instance.OutputFormat(
624 "Adding packet {0} to {1} drop list for all connections in {2}",
625 direction, packetName, m_udpServer.Scene.Name);
626
627 m_udpServer.Scene.ForEachScenePresence(
628 sp =>
629 {
630 LLClientView llcv = (LLClientView)sp.ControllingClient;
631
632 if (direction == "in")
633 llcv.AddInPacketToDropSet(packetName);
634 else if (direction == "out")
635 llcv.AddOutPacketToDropSet(packetName);
636 }
637 );
638 }
639 else if (subCommand == "remove")
640 {
641 MainConsole.Instance.OutputFormat(
642 "Removing packet {0} from {1} drop list for all connections in {2}",
643 direction, packetName, m_udpServer.Scene.Name);
644
645 m_udpServer.Scene.ForEachScenePresence(
646 sp =>
647 {
648 LLClientView llcv = (LLClientView)sp.ControllingClient;
649
650 if (direction == "in")
651 llcv.RemoveInPacketFromDropSet(packetName);
652 else if (direction == "out")
653 llcv.RemoveOutPacketFromDropSet(packetName);
654 }
655 );
656 }
657 }
658
659 private void HandleStartCommand(string module, string[] args)
660 {
661 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
662 return;
663
664 if (args.Length != 4)
665 {
666 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
667 return;
668 }
669
670 string subCommand = args[3];
671
672 if (subCommand == "in" || subCommand == "all")
673 m_udpServer.StartInbound();
674
675 if (subCommand == "out" || subCommand == "all")
676 m_udpServer.StartOutbound();
677 }
678
679 private void HandleStopCommand(string module, string[] args)
680 {
681 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
682 return;
683
684 if (args.Length != 4)
685 {
686 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
687 return;
688 }
689
690 string subCommand = args[3];
691
692 if (subCommand == "in" || subCommand == "all")
693 m_udpServer.StopInbound();
694
695 if (subCommand == "out" || subCommand == "all")
696 m_udpServer.StopOutbound();
697 }
698
699 private void HandlePoolCommand(string module, string[] args)
700 {
701 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
702 return;
703
704 if (args.Length != 4)
705 {
706 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
707 return;
708 }
709
710 string enabled = args[3];
711
712 if (enabled == "on")
713 {
714 if (m_udpServer.EnablePools())
715 {
716 m_udpServer.EnablePoolStats();
717 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
718 }
719 }
720 else if (enabled == "off")
721 {
722 if (m_udpServer.DisablePools())
723 {
724 m_udpServer.DisablePoolStats();
725 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
726 }
727 }
728 else
729 {
730 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
731 }
732 }
733
734 private void HandleAgentUpdateCommand(string module, string[] args)
735 {
736 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
737 return;
738
739 m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates;
740
741 MainConsole.Instance.OutputFormat(
742 "Discard AgentUpdates now {0} for {1}", m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name);
743 }
744
745 private void HandleStatusCommand(string module, string[] args)
746 {
747 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
748 return;
749
750 MainConsole.Instance.OutputFormat(
751 "IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled");
752
753 MainConsole.Instance.OutputFormat(
754 "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
755
756 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
757
758 MainConsole.Instance.OutputFormat(
759 "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
760 }
761 }
762} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 88494be..94300f8 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -135,7 +135,7 @@ namespace OpenMetaverse
135 /// manner (not throwing an exception when the remote side resets the 135 /// manner (not throwing an exception when the remote side resets the
136 /// connection). This call is ignored on Mono where the flag is not 136 /// connection). This call is ignored on Mono where the flag is not
137 /// necessary</remarks> 137 /// necessary</remarks>
138 public void StartInbound(int recvBufferSize, bool asyncPacketHandling) 138 public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling)
139 { 139 {
140 m_asyncPacketHandling = asyncPacketHandling; 140 m_asyncPacketHandling = asyncPacketHandling;
141 141
@@ -168,6 +168,12 @@ namespace OpenMetaverse
168 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); 168 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring");
169 } 169 }
170 170
171 // On at least Mono 3.2.8, multiple UDP sockets can bind to the same port by default. At the moment
172 // we never want two regions to listen on the same port as they cannot demultiplex each other's messages,
173 // leading to a confusing bug.
174 // By default, Windows does not allow two sockets to bind to the same port.
175 m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
176
171 if (recvBufferSize != 0) 177 if (recvBufferSize != 0)
172 m_udpSocket.ReceiveBufferSize = recvBufferSize; 178 m_udpSocket.ReceiveBufferSize = recvBufferSize;
173 179
@@ -185,14 +191,14 @@ namespace OpenMetaverse
185 /// <summary> 191 /// <summary>
186 /// Start outbound UDP packet handling. 192 /// Start outbound UDP packet handling.
187 /// </summary> 193 /// </summary>
188 public void StartOutbound() 194 public virtual void StartOutbound()
189 { 195 {
190 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); 196 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
191 197
192 IsRunningOutbound = true; 198 IsRunningOutbound = true;
193 } 199 }
194 200
195 public void StopInbound() 201 public virtual void StopInbound()
196 { 202 {
197 if (IsRunningInbound) 203 if (IsRunningInbound)
198 { 204 {
@@ -203,14 +209,14 @@ namespace OpenMetaverse
203 } 209 }
204 } 210 }
205 211
206 public void StopOutbound() 212 public virtual void StopOutbound()
207 { 213 {
208 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); 214 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
209 215
210 IsRunningOutbound = false; 216 IsRunningOutbound = false;
211 } 217 }
212 218
213 protected virtual bool EnablePools() 219 public virtual bool EnablePools()
214 { 220 {
215 if (!UsePools) 221 if (!UsePools)
216 { 222 {
@@ -224,7 +230,7 @@ namespace OpenMetaverse
224 return false; 230 return false;
225 } 231 }
226 232
227 protected virtual bool DisablePools() 233 public virtual bool DisablePools()
228 { 234 {
229 if (UsePools) 235 if (UsePools)
230 { 236 {
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
index 069c9c8..1e915c3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs
@@ -124,7 +124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
124 124
125 StatsManager.RegisterStat(m_oqreRequestsWaitingStat); 125 StatsManager.RegisterStat(m_oqreRequestsWaitingStat);
126 126
127 Watchdog.StartThread( 127 WorkManager.StartThread(
128 ProcessRequests, 128 ProcessRequests,
129 String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name), 129 String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name),
130 ThreadPriority.Normal, 130 ThreadPriority.Normal,
@@ -217,6 +217,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
217 217
218 private void ProcessRequests() 218 private void ProcessRequests()
219 { 219 {
220 Thread.CurrentThread.Priority = ThreadPriority.Highest;
221
220 try 222 try
221 { 223 {
222 while (IsRunning || m_requestQueue.Count > 0) 224 while (IsRunning || m_requestQueue.Count > 0)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index e9aeffe..a935dd2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -36,7 +36,6 @@ using OpenSim.Framework;
36using OpenSim.Framework.Monitoring; 36using OpenSim.Framework.Monitoring;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40 39
41namespace OpenSim.Region.ClientStack.LindenUDP.Tests 40namespace OpenSim.Region.ClientStack.LindenUDP.Tests
42{ 41{
@@ -47,7 +46,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
47 public class BasicCircuitTests : OpenSimTestCase 46 public class BasicCircuitTests : OpenSimTestCase
48 { 47 {
49 private Scene m_scene; 48 private Scene m_scene;
50 private TestLLUDPServer m_udpServer;
51 49
52 [TestFixtureSetUp] 50 [TestFixtureSetUp]
53 public void FixtureInit() 51 public void FixtureInit()
@@ -73,72 +71,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
73 StatsManager.SimExtraStats = new SimExtraStatsCollector(); 71 StatsManager.SimExtraStats = new SimExtraStatsCollector();
74 } 72 }
75 73
76 /// <summary> 74// /// <summary>
77 /// Build an object name packet for test purposes 75// /// Build an object name packet for test purposes
78 /// </summary> 76// /// </summary>
79 /// <param name="objectLocalId"></param> 77// /// <param name="objectLocalId"></param>
80 /// <param name="objectName"></param> 78// /// <param name="objectName"></param>
81 private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) 79// private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
82 { 80// {
83 ObjectNamePacket onp = new ObjectNamePacket(); 81// ObjectNamePacket onp = new ObjectNamePacket();
84 ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); 82// ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
85 odb.LocalID = objectLocalId; 83// odb.LocalID = objectLocalId;
86 odb.Name = Utils.StringToBytes(objectName); 84// odb.Name = Utils.StringToBytes(objectName);
87 onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb }; 85// onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb };
88 onp.Header.Zerocoded = false; 86// onp.Header.Zerocoded = false;
89 87//
90 return onp; 88// return onp;
91 } 89// }
92 90//
93 private void AddUdpServer()
94 {
95 AddUdpServer(new IniConfigSource());
96 }
97
98 private void AddUdpServer(IniConfigSource configSource)
99 {
100 uint port = 0;
101 AgentCircuitManager acm = m_scene.AuthenticateHandler;
102
103 m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
104 m_udpServer.AddScene(m_scene);
105 }
106
107 /// <summary>
108 /// Used by tests that aren't testing this stage.
109 /// </summary>
110 private ScenePresence AddClient()
111 {
112 UUID myAgentUuid = TestHelpers.ParseTail(0x1);
113 UUID mySessionUuid = TestHelpers.ParseTail(0x2);
114 uint myCircuitCode = 123456;
115 IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
116
117 UseCircuitCodePacket uccp = new UseCircuitCodePacket();
118
119 UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
120 = new UseCircuitCodePacket.CircuitCodeBlock();
121 uccpCcBlock.Code = myCircuitCode;
122 uccpCcBlock.ID = myAgentUuid;
123 uccpCcBlock.SessionID = mySessionUuid;
124 uccp.CircuitCode = uccpCcBlock;
125
126 byte[] uccpBytes = uccp.ToBytes();
127 UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
128 upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
129 Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
130
131 AgentCircuitData acd = new AgentCircuitData();
132 acd.AgentID = myAgentUuid;
133 acd.SessionID = mySessionUuid;
134
135 m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
136
137 m_udpServer.PacketReceived(upb);
138
139 return m_scene.GetScenePresence(myAgentUuid);
140 }
141
142 /// <summary> 91 /// <summary>
143 /// Test adding a client to the stack 92 /// Test adding a client to the stack
144 /// </summary> 93 /// </summary>
@@ -148,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
148 TestHelpers.InMethod(); 97 TestHelpers.InMethod();
149// TestHelpers.EnableLogging(); 98// TestHelpers.EnableLogging();
150 99
151 AddUdpServer(); 100 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene);
152 101
153 UUID myAgentUuid = TestHelpers.ParseTail(0x1); 102 UUID myAgentUuid = TestHelpers.ParseTail(0x1);
154 UUID mySessionUuid = TestHelpers.ParseTail(0x2); 103 UUID mySessionUuid = TestHelpers.ParseTail(0x2);
@@ -169,7 +118,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
169 upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. 118 upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
170 Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); 119 Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
171 120
172 m_udpServer.PacketReceived(upb); 121 udpServer.PacketReceived(upb);
173 122
174 // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet 123 // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
175 Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); 124 Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
@@ -180,15 +129,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
180 129
181 m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); 130 m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
182 131
183 m_udpServer.PacketReceived(upb); 132 udpServer.PacketReceived(upb);
184 133
185 // Should succeed now 134 // Should succeed now
186 ScenePresence sp = m_scene.GetScenePresence(myAgentUuid); 135 ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
187 Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); 136 Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
188 137
189 Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1)); 138 Assert.That(udpServer.PacketsSent.Count, Is.EqualTo(1));
190 139
191 Packet packet = m_udpServer.PacketsSent[0]; 140 Packet packet = udpServer.PacketsSent[0];
192 Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); 141 Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
193 142
194 PacketAckPacket ackPacket = packet as PacketAckPacket; 143 PacketAckPacket ackPacket = packet as PacketAckPacket;
@@ -200,15 +149,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
200 public void TestLogoutClientDueToAck() 149 public void TestLogoutClientDueToAck()
201 { 150 {
202 TestHelpers.InMethod(); 151 TestHelpers.InMethod();
203 TestHelpers.EnableLogging(); 152// TestHelpers.EnableLogging();
204 153
205 IniConfigSource ics = new IniConfigSource(); 154 IniConfigSource ics = new IniConfigSource();
206 IConfig config = ics.AddConfig("ClientStack.LindenUDP"); 155 IConfig config = ics.AddConfig("ClientStack.LindenUDP");
207 config.Set("AckTimeout", -1); 156 config.Set("AckTimeout", -1);
208 AddUdpServer(ics); 157 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene, ics);
158
159 ScenePresence sp
160 = ClientStackHelpers.AddChildClient(
161 m_scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
209 162
210 ScenePresence sp = AddClient(); 163 udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
211 m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
212 164
213 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); 165 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
214 Assert.That(spAfterAckTimeout, Is.Null); 166 Assert.That(spAfterAckTimeout, Is.Null);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
index 575e54c..6c57e6d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Agent.TextureSender; 39using OpenSim.Region.CoreModules.Agent.TextureSender;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.ClientStack.LindenUDP.Tests 43namespace OpenSim.Region.ClientStack.LindenUDP.Tests
45{ 44{
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
deleted file mode 100644
index 39d1875..0000000
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Net;
29using OpenMetaverse;
30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes;
32using GridRegion = OpenSim.Services.Interfaces.GridRegion;
33
34namespace OpenSim.Region.ClientStack.LindenUDP.Tests
35{
36 /// <summary>
37 /// Mock scene for unit tests
38 /// </summary>
39 public class MockScene : SceneBase
40 {
41 public int ObjectNameCallsReceived
42 {
43 get { return m_objectNameCallsReceived; }
44 }
45 protected int m_objectNameCallsReceived;
46
47 public MockScene() : base(new RegionInfo(1000, 1000, null, null))
48 {
49 m_regStatus = RegionStatus.Up;
50 }
51
52 public override bool Update(int frames) { return true; }
53 public override void LoadWorldMap() {}
54
55 public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
56 {
57 client.OnObjectName += RecordObjectNameCall;
58
59 // FIXME
60 return null;
61 }
62
63 public override bool CloseAgent(UUID agentID, bool force) { return true; }
64
65 public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; }
66
67 public override void OtherRegionUp(GridRegion otherRegion) { }
68
69 public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; }
70
71 /// <summary>
72 /// Doesn't really matter what the call is - we're using this to test that a packet has actually been received
73 /// </summary>
74 protected void RecordObjectNameCall(IClientAPI remoteClient, uint localID, string message)
75 {
76 m_objectNameCallsReceived++;
77 }
78 }
79}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs
index 5f73a94..92f1fc3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs
@@ -30,7 +30,6 @@ using NUnit.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets; 31using OpenMetaverse.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Tests.Common.Mock;
34using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
35 34
36namespace OpenSim.Region.ClientStack.LindenUDP.Tests 35namespace OpenSim.Region.ClientStack.LindenUDP.Tests
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
new file mode 100644
index 0000000..0560b9b
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
@@ -0,0 +1,425 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using NUnit.Framework;
31using OpenMetaverse.Packets;
32using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Tests.Common;
35
36namespace OpenSim.Region.ClientStack.LindenUDP.Tests
37{
38 [TestFixture]
39 public class ThrottleTests : OpenSimTestCase
40 {
41 [TestFixtureSetUp]
42 public void FixtureInit()
43 {
44 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
45 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
46 }
47
48 [TestFixtureTearDown]
49 public void TearDown()
50 {
51 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
52 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
53 // tests really shouldn't).
54 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
55 }
56
57 [Test]
58 public void TestSetRequestDripRate()
59 {
60 TestHelpers.InMethod();
61
62 TokenBucket tb = new TokenBucket("tb", null, 5000, 0);
63 AssertRates(tb, 5000, 0, 5000, 0);
64
65 tb.RequestedDripRate = 4000;
66 AssertRates(tb, 4000, 0, 4000, 0);
67
68 tb.RequestedDripRate = 6000;
69 AssertRates(tb, 6000, 0, 6000, 0);
70 }
71
72 [Test]
73 public void TestSetRequestDripRateWithMax()
74 {
75 TestHelpers.InMethod();
76
77 TokenBucket tb = new TokenBucket("tb", null, 5000, 10000);
78 AssertRates(tb, 5000, 0, 5000, 10000);
79
80 tb.RequestedDripRate = 4000;
81 AssertRates(tb, 4000, 0, 4000, 10000);
82
83 tb.RequestedDripRate = 6000;
84 AssertRates(tb, 6000, 0, 6000, 10000);
85
86 tb.RequestedDripRate = 12000;
87 AssertRates(tb, 10000, 0, 10000, 10000);
88 }
89
90 [Test]
91 public void TestSetRequestDripRateWithChildren()
92 {
93 TestHelpers.InMethod();
94
95 TokenBucket tbParent = new TokenBucket("tbParent", null, 0, 0);
96 TokenBucket tbChild1 = new TokenBucket("tbChild1", tbParent, 3000, 0);
97 TokenBucket tbChild2 = new TokenBucket("tbChild2", tbParent, 5000, 0);
98
99 AssertRates(tbParent, 8000, 8000, 8000, 0);
100 AssertRates(tbChild1, 3000, 0, 3000, 0);
101 AssertRates(tbChild2, 5000, 0, 5000, 0);
102
103 // Test: Setting a parent request greater than total children requests.
104 tbParent.RequestedDripRate = 10000;
105
106 AssertRates(tbParent, 10000, 8000, 8000, 0);
107 AssertRates(tbChild1, 3000, 0, 3000, 0);
108 AssertRates(tbChild2, 5000, 0, 5000, 0);
109
110 // Test: Setting a parent request lower than total children requests.
111 tbParent.RequestedDripRate = 6000;
112
113 AssertRates(tbParent, 6000, 8000, 6000, 0);
114 AssertRates(tbChild1, 3000, 0, 6000 / 8 * 3, 0);
115 AssertRates(tbChild2, 5000, 0, 6000 / 8 * 5, 0);
116 }
117
118 private void AssertRates(
119 TokenBucket tb, double requestedDripRate, double totalDripRequest, double dripRate, double maxDripRate)
120 {
121 Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate, "Requested drip rate");
122 Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest, "Total drip request");
123 Assert.AreEqual((int)dripRate, tb.DripRate, "Drip rate");
124 Assert.AreEqual((int)maxDripRate, tb.MaxDripRate, "Max drip rate");
125 }
126
127 [Test]
128 public void TestClientThrottleSetNoLimit()
129 {
130 TestHelpers.InMethod();
131// TestHelpers.EnableLogging();
132
133 Scene scene = new SceneHelpers().SetupScene();
134 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
135
136 ScenePresence sp
137 = ClientStackHelpers.AddChildClient(
138 scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
139
140 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
141
142 udpServer.Throttle.DebugLevel = 1;
143 udpClient.ThrottleDebugLevel = 1;
144
145 int resendBytes = 1000;
146 int landBytes = 2000;
147 int windBytes = 3000;
148 int cloudBytes = 4000;
149 int taskBytes = 5000;
150 int textureBytes = 6000;
151 int assetBytes = 7000;
152
153 SetThrottles(
154 udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
155
156 // We expect this to be lower because of the minimum bound set by MTU
157 int totalBytes = LLUDPServer.MTU + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes;
158
159 AssertThrottles(
160 udpClient,
161 LLUDPServer.MTU, landBytes, windBytes, cloudBytes, taskBytes,
162 textureBytes, assetBytes, totalBytes, 0, 0);
163 }
164
165 [Test]
166 public void TestClientThrottleAdaptiveNoLimit()
167 {
168 TestHelpers.InMethod();
169// TestHelpers.EnableLogging();
170
171 Scene scene = new SceneHelpers().SetupScene();
172
173 IniConfigSource ics = new IniConfigSource();
174 IConfig config = ics.AddConfig("ClientStack.LindenUDP");
175 config.Set("enable_adaptive_throttles", true);
176 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene, ics);
177
178 ScenePresence sp
179 = ClientStackHelpers.AddChildClient(
180 scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
181
182 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
183
184 udpServer.Throttle.DebugLevel = 1;
185 udpClient.ThrottleDebugLevel = 1;
186
187 // Total is 280000
188 int resendBytes = 10000;
189 int landBytes = 20000;
190 int windBytes = 30000;
191 int cloudBytes = 40000;
192 int taskBytes = 50000;
193 int textureBytes = 60000;
194 int assetBytes = 70000;
195 int totalBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes;
196
197 SetThrottles(
198 udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
199
200 // Ratio of current adaptive drip rate to requested bytes
201 // XXX: Should hard code this as below so we don't rely on values given by tested code to construct
202 // expected values.
203 double commitRatio = (double)udpClient.FlowThrottle.AdjustedDripRate / udpClient.FlowThrottle.TargetDripRate;
204
205 AssertThrottles(
206 udpClient,
207 LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio,
208 textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0);
209
210 // Test an increase in target throttle
211 udpClient.FlowThrottle.AcknowledgePackets(35000);
212 commitRatio = 0.2;
213
214 AssertThrottles(
215 udpClient,
216 resendBytes * commitRatio, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio,
217 textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0);
218
219 // Test a decrease in target throttle
220 udpClient.FlowThrottle.ExpirePackets(1);
221 commitRatio = 0.1;
222
223 AssertThrottles(
224 udpClient,
225 LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio,
226 textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0);
227 }
228
229 /// <summary>
230 /// Test throttle setttings where max client throttle has been limited server side.
231 /// </summary>
232 [Test]
233 public void TestSingleClientThrottleRegionLimited()
234 {
235 TestHelpers.InMethod();
236 // TestHelpers.EnableLogging();
237
238 int resendBytes = 6000;
239 int landBytes = 8000;
240 int windBytes = 10000;
241 int cloudBytes = 12000;
242 int taskBytes = 14000;
243 int textureBytes = 16000;
244 int assetBytes = 18000;
245 int totalBytes
246 = (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
247
248 Scene scene = new SceneHelpers().SetupScene();
249 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
250 udpServer.Throttle.RequestedDripRate = totalBytes;
251
252 ScenePresence sp1
253 = ClientStackHelpers.AddChildClient(
254 scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
255
256 LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient;
257
258 SetThrottles(
259 udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
260
261 AssertThrottles(
262 udpClient1,
263 resendBytes / 2, landBytes / 2, windBytes / 2, cloudBytes / 2, taskBytes / 2,
264 textureBytes / 2, assetBytes / 2, totalBytes, 0, 0);
265
266 // Test: Now add another client
267 ScenePresence sp2
268 = ClientStackHelpers.AddChildClient(
269 scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457);
270
271 LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient;
272 // udpClient.ThrottleDebugLevel = 1;
273
274 SetThrottles(
275 udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
276
277 AssertThrottles(
278 udpClient1,
279 resendBytes / 4, landBytes / 4, windBytes / 4, cloudBytes / 4, taskBytes / 4,
280 textureBytes / 4, assetBytes / 4, totalBytes / 2, 0, 0);
281
282 AssertThrottles(
283 udpClient2,
284 resendBytes / 4, landBytes / 4, windBytes / 4, cloudBytes / 4, taskBytes / 4,
285 textureBytes / 4, assetBytes / 4, totalBytes / 2, 0, 0);
286 }
287
288 /// <summary>
289 /// Test throttle setttings where max client throttle has been limited server side.
290 /// </summary>
291 [Test]
292 public void TestClientThrottlePerClientLimited()
293 {
294 TestHelpers.InMethod();
295 // TestHelpers.EnableLogging();
296
297 int resendBytes = 4000;
298 int landBytes = 6000;
299 int windBytes = 8000;
300 int cloudBytes = 10000;
301 int taskBytes = 12000;
302 int textureBytes = 14000;
303 int assetBytes = 16000;
304 int totalBytes
305 = (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
306
307 Scene scene = new SceneHelpers().SetupScene();
308 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
309 udpServer.ThrottleRates.Total = totalBytes;
310
311 ScenePresence sp
312 = ClientStackHelpers.AddChildClient(
313 scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
314
315 LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
316 // udpClient.ThrottleDebugLevel = 1;
317
318 SetThrottles(
319 udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
320
321 AssertThrottles(
322 udpClient,
323 resendBytes / 2, landBytes / 2, windBytes / 2, cloudBytes / 2, taskBytes / 2,
324 textureBytes / 2, assetBytes / 2, totalBytes, 0, totalBytes);
325 }
326
327 [Test]
328 public void TestClientThrottlePerClientAndRegionLimited()
329 {
330 TestHelpers.InMethod();
331 //TestHelpers.EnableLogging();
332
333 int resendBytes = 4000;
334 int landBytes = 6000;
335 int windBytes = 8000;
336 int cloudBytes = 10000;
337 int taskBytes = 12000;
338 int textureBytes = 14000;
339 int assetBytes = 16000;
340
341 // current total 70000
342 int totalBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes;
343
344 Scene scene = new SceneHelpers().SetupScene();
345 TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
346 udpServer.ThrottleRates.Total = (int)(totalBytes * 1.1);
347 udpServer.Throttle.RequestedDripRate = (int)(totalBytes * 1.5);
348
349 ScenePresence sp1
350 = ClientStackHelpers.AddChildClient(
351 scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
352
353 LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient;
354 udpClient1.ThrottleDebugLevel = 1;
355
356 SetThrottles(
357 udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
358
359 AssertThrottles(
360 udpClient1,
361 resendBytes, landBytes, windBytes, cloudBytes, taskBytes,
362 textureBytes, assetBytes, totalBytes, 0, totalBytes * 1.1);
363
364 // Now add another client
365 ScenePresence sp2
366 = ClientStackHelpers.AddChildClient(
367 scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457);
368
369 LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient;
370 udpClient2.ThrottleDebugLevel = 1;
371
372 SetThrottles(
373 udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
374
375 AssertThrottles(
376 udpClient1,
377 resendBytes * 0.75, landBytes * 0.75, windBytes * 0.75, cloudBytes * 0.75, taskBytes * 0.75,
378 textureBytes * 0.75, assetBytes * 0.75, totalBytes * 0.75, 0, totalBytes * 1.1);
379
380 AssertThrottles(
381 udpClient2,
382 resendBytes * 0.75, landBytes * 0.75, windBytes * 0.75, cloudBytes * 0.75, taskBytes * 0.75,
383 textureBytes * 0.75, assetBytes * 0.75, totalBytes * 0.75, 0, totalBytes * 1.1);
384 }
385
386 private void AssertThrottles(
387 LLUDPClient udpClient,
388 double resendBytes, double landBytes, double windBytes, double cloudBytes, double taskBytes, double textureBytes, double assetBytes,
389 double totalBytes, double targetBytes, double maxBytes)
390 {
391 ClientInfo ci = udpClient.GetClientInfo();
392
393// Console.WriteLine(
394// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
395// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
396
397 Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend");
398 Assert.AreEqual((int)landBytes, ci.landThrottle, "Land");
399 Assert.AreEqual((int)windBytes, ci.windThrottle, "Wind");
400 Assert.AreEqual((int)cloudBytes, ci.cloudThrottle, "Cloud");
401 Assert.AreEqual((int)taskBytes, ci.taskThrottle, "Task");
402 Assert.AreEqual((int)textureBytes, ci.textureThrottle, "Texture");
403 Assert.AreEqual((int)assetBytes, ci.assetThrottle, "Asset");
404 Assert.AreEqual((int)totalBytes, ci.totalThrottle, "Total");
405 Assert.AreEqual((int)targetBytes, ci.targetThrottle, "Target");
406 Assert.AreEqual((int)maxBytes, ci.maxThrottle, "Max");
407 }
408
409 private void SetThrottles(
410 LLUDPClient udpClient, int resendBytes, int landBytes, int windBytes, int cloudBytes, int taskBytes, int textureBytes, int assetBytes)
411 {
412 byte[] throttles = new byte[28];
413
414 Array.Copy(BitConverter.GetBytes((float)resendBytes * 8), 0, throttles, 0, 4);
415 Array.Copy(BitConverter.GetBytes((float)landBytes * 8), 0, throttles, 4, 4);
416 Array.Copy(BitConverter.GetBytes((float)windBytes * 8), 0, throttles, 8, 4);
417 Array.Copy(BitConverter.GetBytes((float)cloudBytes * 8), 0, throttles, 12, 4);
418 Array.Copy(BitConverter.GetBytes((float)taskBytes * 8), 0, throttles, 16, 4);
419 Array.Copy(BitConverter.GetBytes((float)textureBytes * 8), 0, throttles, 20, 4);
420 Array.Copy(BitConverter.GetBytes((float)assetBytes * 8), 0, throttles, 24, 4);
421
422 udpClient.SetThrottles(throttles);
423 }
424 }
425} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
index e5bae6e..dd15cc7 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
@@ -72,6 +72,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 { 72 {
73 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; 73 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
74 74
75 // Current default total is 66750
75 Resend = throttleConfig.GetInt("resend_default", 6625); 76 Resend = throttleConfig.GetInt("resend_default", 6625);
76 Land = throttleConfig.GetInt("land_default", 9125); 77 Land = throttleConfig.GetInt("land_default", 9125);
77 Wind = throttleConfig.GetInt("wind_default", 1750); 78 Wind = throttleConfig.GetInt("wind_default", 1750);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 658d9bb..d215595 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -42,9 +42,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
42 public class TokenBucket 42 public class TokenBucket
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 private static Int32 m_counter = 0;
46
47 private LLUDPClient m_client;
48 45
49 public string Identifier { get; private set; } 46 public string Identifier { get; private set; }
50 47
@@ -79,20 +76,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
79 /// Map of children buckets and their requested maximum burst rate 76 /// Map of children buckets and their requested maximum burst rate
80 /// </summary> 77 /// </summary>
81 protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); 78 protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>();
82
83#region Properties
84 79
85 /// <summary> 80 /// <summary>
86 /// The parent bucket of this bucket, or null if this bucket has no 81 /// The parent bucket of this bucket, or null if this bucket has no
87 /// parent. The parent bucket will limit the aggregate bandwidth of all 82 /// parent. The parent bucket will limit the aggregate bandwidth of all
88 /// of its children buckets 83 /// of its children buckets
89 /// </summary> 84 /// </summary>
90 protected TokenBucket m_parent; 85 public TokenBucket Parent { get; protected set; }
91 public TokenBucket Parent
92 {
93 get { return m_parent; }
94 set { m_parent = value; }
95 }
96 86
97 /// <summary> 87 /// <summary>
98 /// Maximum burst rate in bytes per second. This is the maximum number 88 /// Maximum burst rate in bytes per second. This is the maximum number
@@ -118,53 +108,85 @@ namespace OpenSim.Region.ClientStack.LindenUDP
118 } 108 }
119 109
120 /// <summary> 110 /// <summary>
121 /// The speed limit of this bucket in bytes per second. This is the 111 /// The requested drip rate for this particular bucket.
122 /// number of tokens that are added to the bucket per quantum
123 /// </summary> 112 /// </summary>
124 /// <remarks>Tokens are added to the bucket any time 113 /// <remarks>
114 /// 0 then TotalDripRequest is used instead.
115 /// Can never be above MaxDripRate.
116 /// Tokens are added to the bucket at any time
125 /// <seealso cref="RemoveTokens"/> is called, at the granularity of 117 /// <seealso cref="RemoveTokens"/> is called, at the granularity of
126 /// the system tick interval (typically around 15-22ms)</remarks> 118 /// the system tick interval (typically around 15-22ms)
127 protected Int64 m_dripRate; 119 /// FIXME: It is extremely confusing to be able to set a RequestedDripRate of 0 and then receive a positive
120 /// number on get if TotalDripRequest is sent. This also stops us being able to retrieve the fact that
121 /// RequestedDripRate is set to 0. Really, this should always return m_dripRate and then we can get
122 /// (m_dripRate == 0 ? TotalDripRequest : m_dripRate) on some other properties.
123 /// </remarks>
128 public virtual Int64 RequestedDripRate 124 public virtual Int64 RequestedDripRate
129 { 125 {
130 get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); } 126 get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); }
131 set { 127 set
132 m_dripRate = (value < 0 ? 0 : value); 128 {
129 if (value <= 0)
130 m_dripRate = 0;
131 else if (MaxDripRate > 0 && value > MaxDripRate)
132 m_dripRate = MaxDripRate;
133 else
134 m_dripRate = value;
135
133 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); 136 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
134 m_totalDripRequest = m_dripRate; 137
135 if (m_parent != null) 138 if (Parent != null)
136 m_parent.RegisterRequest(this,m_dripRate); 139 Parent.RegisterRequest(this, m_dripRate);
137 } 140 }
138 } 141 }
139 142
143 /// <summary>
144 /// Gets the drip rate.
145 /// </summary>
146 /// <value>
147 /// DripRate can never be above max drip rate or below min drip rate.
148 /// If we are a child bucket then the drip rate return is modifed by the total load on the capacity of the
149 /// parent bucket.
150 /// </value>
140 public virtual Int64 DripRate 151 public virtual Int64 DripRate
141 { 152 {
142 get { 153 get
143 if (m_parent == null) 154 {
144 return Math.Min(RequestedDripRate,TotalDripRequest); 155 double rate;
145 156
146 double rate = (double)RequestedDripRate * m_parent.DripRateModifier(); 157 // FIXME: This doesn't properly work if we have a parent and children and a requested drip rate set
158 // on ourselves which is not equal to the child drip rates.
159 if (Parent == null)
160 {
161 if (TotalDripRequest > 0)
162 rate = Math.Min(RequestedDripRate, TotalDripRequest);
163 else
164 rate = RequestedDripRate;
165 }
166 else
167 {
168 rate = (double)RequestedDripRate * Parent.DripRateModifier();
169 }
170
147 if (rate < m_minimumDripRate) 171 if (rate < m_minimumDripRate)
148 rate = m_minimumDripRate; 172 rate = m_minimumDripRate;
173 else if (MaxDripRate > 0 && rate > MaxDripRate)
174 rate = MaxDripRate;
149 175
150 return (Int64)rate; 176 return (Int64)rate;
151 } 177 }
152 } 178 }
179 protected Int64 m_dripRate;
180
181 // <summary>
182 // The maximum rate for flow control. Drip rate can never be greater than this.
183 // </summary>
184 public Int64 MaxDripRate { get; set; }
153 185
154 /// <summary> 186 /// <summary>
155 /// The current total of the requested maximum burst rates of 187 /// The current total of the requested maximum burst rates of children buckets.
156 /// this bucket's children buckets.
157 /// </summary> 188 /// </summary>
158 protected Int64 m_totalDripRequest; 189 public Int64 TotalDripRequest { get; protected set; }
159 public Int64 TotalDripRequest
160 {
161 get { return m_totalDripRequest; }
162 set { m_totalDripRequest = value; }
163 }
164
165#endregion Properties
166
167#region Constructor
168 190
169 /// <summary> 191 /// <summary>
170 /// Default constructor 192 /// Default constructor
@@ -172,21 +194,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
172 /// <param name="identifier">Identifier for this token bucket</param> 194 /// <param name="identifier">Identifier for this token bucket</param>
173 /// <param name="parent">Parent bucket if this is a child bucket, or 195 /// <param name="parent">Parent bucket if this is a child bucket, or
174 /// null if this is a root bucket</param> 196 /// null if this is a root bucket</param>
175 /// <param name="dripRate">Rate that the bucket fills, in bytes per 197 /// <param name="requestedDripRate">
176 /// second. If zero, the bucket always remains full</param> 198 /// Requested rate that the bucket fills, in bytes per
177 public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate) 199 /// second. If zero, the bucket always remains full.
200 /// </param>
201 public TokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate)
178 { 202 {
179 Identifier = identifier; 203 Identifier = identifier;
180 204
181 Parent = parent; 205 Parent = parent;
182 RequestedDripRate = dripRate; 206 RequestedDripRate = requestedDripRate;
183 // TotalDripRequest = dripRate; // this will be overwritten when a child node registers 207 MaxDripRate = maxDripRate;
184 // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
185 m_lastDrip = Util.EnvironmentTickCount(); 208 m_lastDrip = Util.EnvironmentTickCount();
186 } 209 }
187 210
188#endregion Constructor
189
190 /// <summary> 211 /// <summary>
191 /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning 212 /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning
192 /// no modification if the requested bandwidth is less than the 213 /// no modification if the requested bandwidth is less than the
@@ -197,7 +218,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
197 protected double DripRateModifier() 218 protected double DripRateModifier()
198 { 219 {
199 Int64 driprate = DripRate; 220 Int64 driprate = DripRate;
200 return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest; 221 double modifier = driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest;
222
223// if (DebugLevel > 0)
224// m_log.DebugFormat(
225// "[TOKEN BUCKET]: Returning drip modifier {0}/{1} = {2} from {3}",
226// driprate, TotalDripRequest, modifier, Identifier);
227
228 return modifier;
201 } 229 }
202 230
203 /// <summary> 231 /// <summary>
@@ -219,16 +247,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
219 lock (m_children) 247 lock (m_children)
220 { 248 {
221 m_children[child] = request; 249 m_children[child] = request;
222 // m_totalDripRequest = m_children.Values.Sum();
223 250
224 m_totalDripRequest = 0; 251 TotalDripRequest = 0;
225 foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) 252 foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
226 m_totalDripRequest += cref.Value; 253 TotalDripRequest += cref.Value;
227 } 254 }
228 255
229 // Pass the new values up to the parent 256 // Pass the new values up to the parent
230 if (m_parent != null) 257 if (Parent != null)
231 m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); 258 {
259 Int64 effectiveDripRate;
260
261 if (RequestedDripRate > 0)
262 effectiveDripRate = Math.Min(RequestedDripRate, TotalDripRequest);
263 else
264 effectiveDripRate = TotalDripRequest;
265
266 Parent.RegisterRequest(this, effectiveDripRate);
267 }
232 } 268 }
233 269
234 /// <summary> 270 /// <summary>
@@ -240,17 +276,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
240 lock (m_children) 276 lock (m_children)
241 { 277 {
242 m_children.Remove(child); 278 m_children.Remove(child);
243 // m_totalDripRequest = m_children.Values.Sum();
244 279
245 m_totalDripRequest = 0; 280 TotalDripRequest = 0;
246 foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) 281 foreach (KeyValuePair<TokenBucket, Int64> cref in m_children)
247 m_totalDripRequest += cref.Value; 282 TotalDripRequest += cref.Value;
248 } 283 }
249
250 284
251 // Pass the new values up to the parent 285 // Pass the new values up to the parent
252 if (m_parent != null) 286 if (Parent != null)
253 m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); 287 Parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest));
254 } 288 }
255 289
256 /// <summary> 290 /// <summary>
@@ -323,64 +357,66 @@ namespace OpenSim.Region.ClientStack.LindenUDP
323 357
324 public class AdaptiveTokenBucket : TokenBucket 358 public class AdaptiveTokenBucket : TokenBucket
325 { 359 {
326 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 360 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
361
362 public bool AdaptiveEnabled { get; set; }
327 363
328 /// <summary> 364 /// <summary>
329 /// The minimum rate for flow control. Minimum drip rate is one 365 /// Target drip rate for this bucket.
330 /// packet per second. Open the throttle to 15 packets per second
331 /// or about 160kbps.
332 /// </summary> 366 /// </summary>
333 protected const Int64 m_minimumFlow = m_minimumDripRate * 15; 367 /// <remarks>Usually set by the client. If adaptive is enabled then throttles will increase until we reach this.</remarks>
334 368 public Int64 TargetDripRate
335 // <summary> 369 {
336 // The maximum rate for flow control. Drip rate can never be 370 get { return m_targetDripRate; }
337 // greater than this. 371 set
338 // </summary> 372 {
339 protected Int64 m_maxDripRate = 0; 373 m_targetDripRate = Math.Max(value, m_minimumFlow);
340 public Int64 MaxDripRate 374 }
341 {
342 get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
343 protected set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
344 } 375 }
376 protected Int64 m_targetDripRate;
345 377
346 public bool Enabled { get; private set; }
347
348 // <summary> 378 // <summary>
349 // 379 // Adjust drip rate in response to network conditions.
350 // </summary> 380 // </summary>
351 public virtual Int64 AdjustedDripRate 381 public virtual Int64 AdjustedDripRate
352 { 382 {
353 get { return m_dripRate; } 383 get { return m_dripRate; }
354 set { 384 set
355 m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value,m_minimumFlow,MaxDripRate); 385 {
386 m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value, m_minimumFlow, TargetDripRate);
356 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); 387 m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst);
357 if (m_parent != null) 388
358 m_parent.RegisterRequest(this,m_dripRate); 389 if (Parent != null)
390 Parent.RegisterRequest(this, m_dripRate);
359 } 391 }
360 } 392 }
393
394 /// <summary>
395 /// The minimum rate for flow control. Minimum drip rate is one
396 /// packet per second. Open the throttle to 15 packets per second
397 /// or about 160kbps.
398 /// </summary>
399 protected const Int64 m_minimumFlow = m_minimumDripRate * 15;
361 400
362 // <summary> 401 public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate, bool enabled)
363 // 402 : base(identifier, parent, requestedDripRate, maxDripRate)
364 // </summary>
365 public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled)
366 : base(identifier, parent, maxDripRate)
367 { 403 {
368 Enabled = enabled; 404 AdaptiveEnabled = enabled;
369 405
370 if (Enabled) 406 if (AdaptiveEnabled)
371 { 407 {
372// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); 408// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled");
373 MaxDripRate = maxDripRate; 409 TargetDripRate = m_minimumFlow;
374 AdjustedDripRate = m_minimumFlow; 410 AdjustedDripRate = m_minimumFlow;
375 } 411 }
376 } 412 }
377 413
378 // <summary> 414 // <summary>
379 // 415 // Reliable packets sent to the client for which we never received an ack adjust the drip rate down.
380 // </summary> 416 // </summary>
381 public void ExpirePackets(Int32 count) 417 public void ExpirePackets(Int32 count)
382 { 418 {
383 if (Enabled) 419 if (AdaptiveEnabled)
384 { 420 {
385 if (DebugLevel > 0) 421 if (DebugLevel > 0)
386 m_log.WarnFormat( 422 m_log.WarnFormat(
@@ -392,12 +428,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
392 } 428 }
393 429
394 // <summary> 430 // <summary>
395 // 431 // Reliable packets acked by the client adjust the drip rate up.
396 // </summary> 432 // </summary>
397 public void AcknowledgePackets(Int32 count) 433 public void AcknowledgePackets(Int32 count)
398 { 434 {
399 if (Enabled) 435 if (AdaptiveEnabled)
400 AdjustedDripRate = AdjustedDripRate + count; 436 AdjustedDripRate = AdjustedDripRate + count;
401 } 437 }
402 } 438 }
403} 439} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 5cdcab9..47dcbcd 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
167 167
168 // Do Decode! 168 // Do Decode!
169 if (decode) 169 if (decode)
170 Util.FireAndForget(delegate { Decode(assetID, j2kData); }); 170 Util.FireAndForget(delegate { Decode(assetID, j2kData); }, null, "J2KDecoderModule.BeginDecode");
171 } 171 }
172 } 172 }
173 173
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 9d6870f..fe9a17d 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -302,7 +302,7 @@ namespace OpenSim.Region.CoreModules.Asset
302 } 302 }
303 303
304 Util.FireAndForget( 304 Util.FireAndForget(
305 delegate { WriteFileCache(filename, asset); }); 305 delegate { WriteFileCache(filename, asset); }, null, "FlotsamAssetCache.UpdateFileCache");
306 } 306 }
307 } 307 }
308 catch (Exception e) 308 catch (Exception e)
@@ -964,11 +964,11 @@ namespace OpenSim.Region.CoreModules.Asset
964 case "assets": 964 case "assets":
965 con.Output("Ensuring assets are cached for all scenes."); 965 con.Output("Ensuring assets are cached for all scenes.");
966 966
967 Watchdog.RunInThread(delegate 967 WorkManager.RunInThread(delegate
968 { 968 {
969 int assetReferenceTotal = TouchAllSceneAssets(true); 969 int assetReferenceTotal = TouchAllSceneAssets(true);
970 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); 970 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
971 }, "TouchAllSceneAssets", null); 971 }, null, "TouchAllSceneAssets");
972 972
973 break; 973 break;
974 974
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index fd02b08..73e4431 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Framework;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.CoreModules.Asset.Tests 43namespace OpenSim.Region.CoreModules.Asset.Tests
45{ 44{
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 3bd7bee..5fb995b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Interfaces;
53using OpenSim.Region.ScriptEngine.XEngine; 53using OpenSim.Region.ScriptEngine.XEngine;
54using OpenSim.Services.Interfaces; 54using OpenSim.Services.Interfaces;
55using OpenSim.Tests.Common; 55using OpenSim.Tests.Common;
56using OpenSim.Tests.Common.Mock;
57 56
58namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests 57namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
59{ 58{
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index d8c159f..ea7481d 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -593,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
593 593
594 if (sendTime < now) 594 if (sendTime < now)
595 { 595 {
596 Util.FireAndForget(o => SendAppearance(avatarID)); 596 Util.FireAndForget(o => SendAppearance(avatarID), null, "AvatarFactoryModule.SendAppearance");
597 m_sendqueue.Remove(avatarID); 597 m_sendqueue.Remove(avatarID);
598 } 598 }
599 } 599 }
@@ -611,7 +611,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
611 611
612 if (sendTime < now) 612 if (sendTime < now)
613 { 613 {
614 Util.FireAndForget(o => SaveAppearance(avatarID)); 614 Util.FireAndForget(o => SaveAppearance(avatarID), null, "AvatarFactoryModule.SaveAppearance");
615 m_savequeue.Remove(avatarID); 615 m_savequeue.Remove(avatarID);
616 } 616 }
617 } 617 }
@@ -1038,7 +1038,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
1038 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1038 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1039 else 1039 else
1040 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1040 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1041 }); 1041 }, null, "AvatarFactoryModule.OnClientRequestWearables");
1042 } 1042 }
1043 1043
1044 /// <summary> 1044 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index de014ba..9513408 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Asset; 34using OpenSim.Region.CoreModules.Asset;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 38namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{ 39{
diff --git a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs
index 5725d67..5e35135 100644
--- a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs
@@ -187,7 +187,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
187 { 187 {
188 rc.Request(reqStream, m_Auth); 188 rc.Request(reqStream, m_Auth);
189 m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId); 189 m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId);
190 } 190 }, null, "XBakesModule.Store"
191 ); 191 );
192 } 192 }
193 } 193 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
index 7b8c418..3018d94 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs
@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
43using OpenSim.Tests.Common; 43using OpenSim.Tests.Common;
44using OpenSim.Tests.Common.Mock;
45 44
46namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests 45namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
47{ 46{
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 31bcded..7ab568e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -511,7 +511,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
511 511
512 // Notify about this user status 512 // Notify about this user status
513 StatusNotify(friendList, agentID, online); 513 StatusNotify(friendList, agentID, online);
514 } 514 }, null, "FriendsModule.StatusChange"
515 ); 515 );
516 } 516 }
517 } 517 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index be12935..27b7376 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -660,7 +660,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
660 FriendsService.Delete(friendUUI, agentID.ToString()); 660 FriendsService.Delete(friendUUI, agentID.ToString());
661 661
662 // notify the exfriend's service 662 // notify the exfriend's service
663 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); 663 Util.FireAndForget(
664 delegate { Delete(exfriendID, agentID, friendUUI); }, null, "HGFriendsModule.DeleteFriendshipForeignFriend");
664 665
665 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); 666 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
666 return true; 667 return true;
@@ -678,7 +679,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
678 FriendsService.Delete(agentUUI, exfriendID.ToString()); 679 FriendsService.Delete(agentUUI, exfriendID.ToString());
679 680
680 // notify the agent's service? 681 // notify the agent's service?
681 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); 682 Util.FireAndForget(
683 delegate { Delete(agentID, exfriendID, agentUUI); }, null, "HGFriendsModule.DeleteFriendshipLocalFriend");
682 684
683 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); 685 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
684 return true; 686 return true;
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index 961117e..e6fd54e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework;
35using OpenSim.Region.CoreModules.Avatar.Friends; 35using OpenSim.Region.CoreModules.Avatar.Friends;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests 39namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
41{ 40{
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index 6f3c80a..a1b918a 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -213,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
213 HandleUndeliverableMessage(im, result); 213 HandleUndeliverableMessage(im, result);
214 else 214 else
215 result(success); 215 result(success);
216 }); 216 }, null, "HGMessageTransferModule.SendInstantMessage");
217 217
218 return; 218 return;
219 } 219 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 9fb8aa5..6dab227 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -431,7 +431,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
431 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 431 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
432 options, ReceivedAllAssets); 432 options, ReceivedAllAssets);
433 433
434 Watchdog.RunInThread(o => ar.Execute(), string.Format("AssetsRequest ({0})", m_scene.Name), null); 434 WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name));
435 } 435 }
436 else 436 else
437 { 437 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
index 8d7de14..84f9f3f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
index 3f16a16..d5f3a22 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
index 4791a79..b614c18 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index e2d95da..4b015d7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 48{
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
index 162a0c3..d615cce 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests 43namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
45{ 44{
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 8337a2f..546a121 100644
--- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
@@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
194 Util.FireAndForget(delegate 194 Util.FireAndForget(delegate
195 { 195 {
196 GetImageAssets(((IScenePresence)obj).UUID); 196 GetImageAssets(((IScenePresence)obj).UUID);
197 }); 197 }, null, "UserProfileModule.GetImageAssets");
198 } 198 }
199 199
200 /// <summary> 200 /// <summary>
@@ -921,8 +921,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
921 object Pref = (object)pref; 921 object Pref = (object)pref;
922 if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString())) 922 if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString()))
923 { 923 {
924 m_log.InfoFormat("[PROFILES]: UserPreferences request error"); 924// m_log.InfoFormat("[PROFILES]: UserPreferences request error");
925 remoteClient.SendAgentAlertMessage("Error requesting preferences", false); 925// remoteClient.SendAgentAlertMessage("Error requesting preferences", false);
926 return; 926 return;
927 } 927 }
928 pref = (UserPreferences) Pref; 928 pref = (UserPreferences) Pref;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index c43633c..09e8204 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -804,8 +804,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
804 // once we reach here... 804 // once we reach here...
805 //avatar.Scene.RemoveCapsHandler(avatar.UUID); 805 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
806 806
807 string capsPath = String.Empty;
808
809 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 807 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
810 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); 808 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
811 agentCircuit.startpos = position; 809 agentCircuit.startpos = position;
@@ -2702,5 +2700,69 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2702 } 2700 }
2703 #endregion 2701 #endregion
2704 2702
2703 public virtual bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
2704 {
2705 // If the user is banned, we won't let any of their objects
2706 // enter. Period.
2707 //
2708 if (Scene.RegionInfo.EstateSettings.IsBanned(so.OwnerID))
2709 {
2710 m_log.DebugFormat(
2711 "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}",
2712 so.Name, so.UUID, Scene.Name, so.OwnerID);
2713
2714 return false;
2715 }
2716
2717 if (newPosition != Vector3.Zero)
2718 so.RootPart.GroupPosition = newPosition;
2719
2720 if (!Scene.AddSceneObject(so))
2721 {
2722 m_log.DebugFormat(
2723 "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ",
2724 so.Name, so.UUID, Scene.Name);
2725
2726 return false;
2727 }
2728
2729 if (!so.IsAttachment)
2730 {
2731 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2732 // it
2733 if (!Scene.Permissions.CanObjectEntry(so.UUID, true, so.AbsolutePosition))
2734 {
2735 // Deny non attachments based on parcel settings
2736 //
2737 m_log.Info("[ENTITY TRANSFER MODULE]: Denied prim crossing because of parcel settings");
2738
2739 Scene.DeleteSceneObject(so, false);
2740
2741 return false;
2742 }
2743
2744 // For attachments, we need to wait until the agent is root
2745 // before we restart the scripts, or else some functions won't work.
2746 so.RootPart.ParentGroup.CreateScriptInstances(
2747 0, false, Scene.DefaultScriptEngine, GetStateSource(so));
2748
2749 so.ResumeScripts();
2750
2751 if (so.RootPart.KeyframeMotion != null)
2752 so.RootPart.KeyframeMotion.UpdateSceneObject(so);
2753 }
2754
2755 return true;
2756 }
2757
2758 private int GetStateSource(SceneObjectGroup sog)
2759 {
2760 ScenePresence sp = Scene.GetScenePresence(sog.OwnerID);
2761
2762 if (sp != null)
2763 return sp.GetStateSource();
2764
2765 return 2; // StateSource.PrimCrossing
2766 }
2705 } 2767 }
2706} 2768}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 0c0cdf2..97267c1 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -110,6 +110,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
110 } 110 }
111 } 111 }
112 112
113 /// <summary>
114 /// Used for processing analysis of incoming attachments in a controlled fashion.
115 /// </summary>
116 private HGIncomingSceneObjectEngine m_incomingSceneObjectEngine;
117
113 #region ISharedRegionModule 118 #region ISharedRegionModule
114 119
115 public override string Name 120 public override string Name
@@ -153,33 +158,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
153 if (m_Enabled) 158 if (m_Enabled)
154 { 159 {
155 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); 160 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this);
156 scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject; 161 //scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject;
157 }
158 }
159 162
160 void OnIncomingSceneObject(SceneObjectGroup so) 163 m_incomingSceneObjectEngine = new HGIncomingSceneObjectEngine(scene.Name);
161 { 164 m_incomingSceneObjectEngine.Start();
162 if (!so.IsAttachment)
163 return;
164
165 if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
166 return;
167
168 // foreign user
169 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
170 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
171 {
172 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
173 {
174 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
175 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
176 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
177 HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
178 uuidGatherer.GatherAssetUuids(so, ids);
179
180 foreach (KeyValuePair<UUID, sbyte> kvp in ids)
181 uuidGatherer.FetchAsset(kvp.Key);
182 }
183 } 165 }
184 } 166 }
185 167
@@ -209,12 +191,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
209 base.RemoveRegion(scene); 191 base.RemoveRegion(scene);
210 192
211 if (m_Enabled) 193 if (m_Enabled)
194 {
212 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); 195 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
196 m_incomingSceneObjectEngine.Stop();
197 }
213 } 198 }
214 199
215 #endregion 200 #endregion
216 201
217 #region HG overrides of IEntiryTransferModule 202 #region HG overrides of IEntityTransferModule
218 203
219 protected override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) 204 protected override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
220 { 205 {
@@ -561,6 +546,132 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
561 } 546 }
562 } 547 }
563 548
549 private void RemoveIncomingSceneObjectJobs(string commonIdToRemove)
550 {
551 List<Job> jobsToReinsert = new List<Job>();
552 int jobsRemoved = 0;
553
554 Job job;
555 while ((job = m_incomingSceneObjectEngine.RemoveNextRequest()) != null)
556 {
557 if (job.CommonId != commonIdToRemove)
558 jobsToReinsert.Add(job);
559 else
560 jobsRemoved++;
561 }
562
563 m_log.DebugFormat(
564 "[HG ENTITY TRANSFER]: Removing {0} jobs with common ID {1} and reinserting {2} other jobs",
565 jobsRemoved, commonIdToRemove, jobsToReinsert.Count);
566
567 if (jobsToReinsert.Count > 0)
568 {
569 foreach (Job jobToReinsert in jobsToReinsert)
570 m_incomingSceneObjectEngine.QueueRequest(jobToReinsert);
571 }
572 }
573
574 public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
575 {
576 // FIXME: We must make it so that we can use SOG.IsAttachment here. At the moment it is always null!
577 if (!so.IsAttachmentCheckFull())
578 return base.HandleIncomingSceneObject(so, newPosition);
579
580 // Equally, we can't use so.AttachedAvatar here.
581 if (so.OwnerID == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.OwnerID))
582 return base.HandleIncomingSceneObject(so, newPosition);
583
584 // foreign user
585 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.OwnerID);
586 if (aCircuit != null)
587 {
588 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) == 0)
589 {
590 // We have already pulled the necessary attachments from the source grid.
591 base.HandleIncomingSceneObject(so, newPosition);
592 }
593 else
594 {
595 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
596 {
597 m_incomingSceneObjectEngine.QueueRequest(
598 string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
599 so.OwnerID.ToString(),
600 o =>
601 {
602 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
603 // m_log.DebugFormat(
604 // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
605 // so.Name, so.AttachedAvatar, url);
606
607 IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url);
608 uuidGatherer.RecordAssetUuids(so);
609
610 while (!uuidGatherer.Complete)
611 {
612 int tickStart = Util.EnvironmentTickCount();
613
614 UUID? nextUuid = uuidGatherer.NextUuidToInspect;
615 uuidGatherer.GatherNext();
616
617 // m_log.DebugFormat(
618 // "[HG ENTITY TRANSFER]: Gathered attachment asset uuid {0} for object {1} for HG user {2} took {3} ms with asset service {4}",
619 // nextUuid, so.Name, so.OwnerID, Util.EnvironmentTickCountSubtract(tickStart), url);
620
621 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
622
623 if (ticksElapsed > 30000)
624 {
625 m_log.WarnFormat(
626 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as gather of {1} from {2} took {3} ms to respond (> {4} ms)",
627 so.OwnerID, so.Name, url, ticksElapsed, 30000);
628
629 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
630
631 return;
632 }
633 }
634
635 IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids();
636
637 // m_log.DebugFormat(
638 // "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}",
639 // ids.Count, so.Name, so.OwnerID, url);
640
641 foreach (KeyValuePair<UUID, sbyte> kvp in ids)
642 {
643 int tickStart = Util.EnvironmentTickCount();
644
645 uuidGatherer.FetchAsset(kvp.Key);
646
647 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
648
649 if (ticksElapsed > 30000)
650 {
651 m_log.WarnFormat(
652 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as fetch of {1} from {2} took {3} ms to respond (> {4} ms)",
653 so.OwnerID, kvp.Key, url, ticksElapsed, 30000);
654
655 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
656
657 return;
658 }
659 }
660
661 base.HandleIncomingSceneObject(so, newPosition);
662
663 // m_log.DebugFormat(
664 // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}",
665 // so.Name, so.OwnerID, url);
666 },
667 null);
668 }
669 }
670 }
671
672 return true;
673 }
674
564 #endregion 675 #endregion
565 676
566 #region IUserAgentVerificationModule 677 #region IUserAgentVerificationModule
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
new file mode 100644
index 0000000..f62e7f4
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs
@@ -0,0 +1,344 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Concurrent;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Framework.Monitoring;
35using OpenSim.Region.Framework.Scenes;
36
37namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
38{
39 public class Job
40 {
41 public string Name { get; private set; }
42 public string CommonId { get; private set; }
43 public WaitCallback Callback { get; private set; }
44 public object O { get; private set; }
45
46 public Job(string name, string commonId, WaitCallback callback, object o)
47 {
48 Name = name;
49 CommonId = commonId;
50 Callback = callback;
51 O = o;
52 }
53 }
54
55 // TODO: These kinds of classes MUST be generalized with JobEngine, etc.
56 public class HGIncomingSceneObjectEngine
57 {
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 public int LogLevel { get; set; }
61
62 public bool IsRunning { get; private set; }
63
64 public string Name { get; set; }
65
66 /// <summary>
67 /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
68 /// </summary>
69 public int RequestProcessTimeoutOnStop { get; set; }
70
71 /// <summary>
72 /// Controls whether we need to warn in the log about exceeding the max queue size.
73 /// </summary>
74 /// <remarks>
75 /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
76 /// order to avoid spamming the log with lots of warnings.
77 /// </remarks>
78 private bool m_warnOverMaxQueue = true;
79
80 private BlockingCollection<Job> m_requestQueue;
81
82 private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
83
84 private Stat m_requestsWaitingStat;
85
86 private Job m_currentJob;
87
88 /// <summary>
89 /// Used to signal that we are ready to complete stop.
90 /// </summary>
91 private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
92
93 public HGIncomingSceneObjectEngine(string name)
94 {
95// LogLevel = 1;
96 Name = name;
97 RequestProcessTimeoutOnStop = 5000;
98
99// MainConsole.Instance.Commands.AddCommand(
100// "Debug",
101// false,
102// "debug jobengine",
103// "debug jobengine <start|stop|status>",
104// "Start, stop or get status of the job engine.",
105// "If stopped then all jobs are processed immediately.",
106// HandleControlCommand);
107 }
108
109 public void Start()
110 {
111 lock (this)
112 {
113 if (IsRunning)
114 return;
115
116 IsRunning = true;
117
118 m_finishedProcessingAfterStop.Reset();
119
120 m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
121
122 m_requestsWaitingStat =
123 new Stat(
124 "HGIncomingAttachmentsWaiting",
125 "Number of incoming attachments waiting for processing.",
126 "",
127 "",
128 "entitytransfer",
129 Name,
130 StatType.Pull,
131 MeasuresOfInterest.None,
132 stat => stat.Value = m_requestQueue.Count,
133 StatVerbosity.Debug);
134
135 StatsManager.RegisterStat(m_requestsWaitingStat);
136
137 WorkManager.StartThread(
138 ProcessRequests,
139 string.Format("HG Incoming Scene Object Engine Thread ({0})", Name),
140 ThreadPriority.Normal,
141 false,
142 true,
143 null,
144 int.MaxValue);
145 }
146 }
147
148 public void Stop()
149 {
150 lock (this)
151 {
152 try
153 {
154 if (!IsRunning)
155 return;
156
157 IsRunning = false;
158
159 int requestsLeft = m_requestQueue.Count;
160
161 if (requestsLeft <= 0)
162 {
163 m_cancelSource.Cancel();
164 }
165 else
166 {
167 m_log.InfoFormat("[HG INCOMING SCENE OBJECT ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
168
169 while (requestsLeft > 0)
170 {
171 if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
172 {
173 // After timeout no events have been written
174 if (requestsLeft == m_requestQueue.Count)
175 {
176 m_log.WarnFormat(
177 "[HG INCOMING SCENE OBJECT ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
178 RequestProcessTimeoutOnStop, requestsLeft);
179
180 break;
181 }
182 }
183
184 requestsLeft = m_requestQueue.Count;
185 }
186 }
187 }
188 finally
189 {
190 m_cancelSource.Dispose();
191 StatsManager.DeregisterStat(m_requestsWaitingStat);
192 m_requestsWaitingStat = null;
193 m_requestQueue = null;
194 }
195 }
196 }
197
198 public Job RemoveNextRequest()
199 {
200 Job nextRequest;
201 m_requestQueue.TryTake(out nextRequest);
202
203 return nextRequest;
204 }
205
206 public bool QueueRequest(string name, string commonId, WaitCallback req, object o)
207 {
208 return QueueRequest(new Job(name, commonId, req, o));
209 }
210
211 public bool QueueRequest(Job job)
212 {
213 if (LogLevel >= 1)
214 m_log.DebugFormat(
215 "[HG INCOMING SCENE OBJECT ENGINE]: Queued job {0}, common ID {1}", job.Name, job.CommonId);
216
217 if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
218 {
219 // m_log.DebugFormat(
220 // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
221 // categories, client.AgentID, m_udpServer.Scene.Name);
222
223 m_requestQueue.Add(job);
224
225 if (!m_warnOverMaxQueue)
226 m_warnOverMaxQueue = true;
227
228 return true;
229 }
230 else
231 {
232 if (m_warnOverMaxQueue)
233 {
234 // m_log.WarnFormat(
235 // "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
236 // client.AgentID, m_udpServer.Scene.Name);
237
238 m_log.WarnFormat("[HG INCOMING SCENE OBJECT ENGINE]: Request queue at maximum capacity, not recording job");
239
240 m_warnOverMaxQueue = false;
241 }
242
243 return false;
244 }
245 }
246
247 private void ProcessRequests()
248 {
249 try
250 {
251 while (IsRunning || m_requestQueue.Count > 0)
252 {
253 m_currentJob = m_requestQueue.Take(m_cancelSource.Token);
254
255 // QueueEmpty callback = req.Client.OnQueueEmpty;
256 //
257 // if (callback != null)
258 // {
259 // try
260 // {
261 // callback(req.Categories);
262 // }
263 // catch (Exception e)
264 // {
265 // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
266 // }
267 // }
268
269 if (LogLevel >= 1)
270 m_log.DebugFormat("[HG INCOMING SCENE OBJECT ENGINE]: Processing job {0}", m_currentJob.Name);
271
272 try
273 {
274 m_currentJob.Callback.Invoke(m_currentJob.O);
275 }
276 catch (Exception e)
277 {
278 m_log.Error(
279 string.Format(
280 "[HG INCOMING SCENE OBJECT ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e);
281 }
282
283 if (LogLevel >= 1)
284 m_log.DebugFormat("[HG INCOMING SCENE OBJECT ENGINE]: Processed job {0}", m_currentJob.Name);
285
286 m_currentJob = null;
287 }
288 }
289 catch (OperationCanceledException)
290 {
291 }
292
293 m_finishedProcessingAfterStop.Set();
294 }
295
296// private void HandleControlCommand(string module, string[] args)
297// {
298// // if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
299// // return;
300//
301// if (args.Length < 3)
302// {
303// MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>");
304// return;
305// }
306//
307// string subCommand = args[2];
308//
309// if (subCommand == "stop")
310// {
311// Stop();
312// MainConsole.Instance.OutputFormat("Stopped job engine.");
313// }
314// else if (subCommand == "start")
315// {
316// Start();
317// MainConsole.Instance.OutputFormat("Started job engine.");
318// }
319// else if (subCommand == "status")
320// {
321// MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning);
322// MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none");
323// MainConsole.Instance.OutputFormat(
324// "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
325// MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel);
326// }
327//
328// else if (subCommand == "loglevel")
329// {
330// // int logLevel;
331// int logLevel = int.Parse(args[3]);
332// // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
333// // {
334// LogLevel = logLevel;
335// MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel);
336// // }
337// }
338// else
339// {
340// MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
341// }
342// }
343 }
344}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index 04615a9..2ac1517 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -189,50 +189,203 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
189 return Utils.StringToBytes(RewriteSOP(xml)); 189 return Utils.StringToBytes(RewriteSOP(xml));
190 } 190 }
191 191
192 protected string RewriteSOP(string xml) 192 protected void TransformXml(XmlReader reader, XmlWriter writer)
193 { 193 {
194 XmlDocument doc = new XmlDocument(); 194// m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML");
195 doc.LoadXml(xml);
196 XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
197 195
198 foreach (XmlNode sop in sops) 196 int sopDepth = -1;
197 UserAccount creator = null;
198 bool hasCreatorData = false;
199
200 while (reader.Read())
199 { 201 {
200 UserAccount creator = null; 202 //Console.WriteLine("Depth: {0}", reader.Depth);
201 bool hasCreatorData = false; 203
202 XmlNodeList nodes = sop.ChildNodes; 204 switch (reader.NodeType)
203 foreach (XmlNode node in nodes)
204 { 205 {
205 if (node.Name == "CreatorID") 206 case XmlNodeType.Attribute:
207 writer.WriteAttributeString(reader.Prefix, reader.Name, reader.NamespaceURI, reader.Value);
208 break;
209
210 case XmlNodeType.CDATA:
211 writer.WriteCData(reader.Value);
212 break;
213
214 case XmlNodeType.Comment:
215 writer.WriteComment(reader.Value);
216 break;
217
218 case XmlNodeType.DocumentType:
219 writer.WriteDocType(reader.Name, reader.Value, null, null);
220 break;
221
222 case XmlNodeType.Element:
223// m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name);
224
225 writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
226
227 if (reader.LocalName == "SceneObjectPart")
206 { 228 {
207 UUID uuid = UUID.Zero; 229 if (sopDepth < 0)
208 UUID.TryParse(node.InnerText, out uuid); 230 {
209 creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 231 sopDepth = reader.Depth;
232// m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth);
233 }
234 }
235 else
236 {
237 if (sopDepth >= 0 && reader.Depth == sopDepth + 1)
238 {
239 if (reader.Name == "CreatorID")
240 {
241 reader.Read();
242 if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID")
243 {
244 reader.Read();
245
246 if (reader.NodeType == XmlNodeType.Text)
247 {
248 UUID uuid = UUID.Zero;
249 UUID.TryParse(reader.Value, out uuid);
250 creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
251 writer.WriteElementString("UUID", reader.Value);
252 reader.Read();
253 }
254 else
255 {
256 // If we unexpected run across mixed content in this node, still carry on
257 // transforming the subtree (this replicates earlier behaviour).
258 TransformXml(reader, writer);
259 }
260 }
261 else
262 {
263 // If we unexpected run across mixed content in this node, still carry on
264 // transforming the subtree (this replicates earlier behaviour).
265 TransformXml(reader, writer);
266 }
267 }
268 else if (reader.Name == "CreatorData")
269 {
270 reader.Read();
271 if (reader.NodeType == XmlNodeType.Text)
272 {
273 hasCreatorData = true;
274 writer.WriteString(reader.Value);
275 }
276 else
277 {
278 // If we unexpected run across mixed content in this node, still carry on
279 // transforming the subtree (this replicates earlier behaviour).
280 TransformXml(reader, writer);
281 }
282 }
283 }
284 }
285
286 if (reader.IsEmptyElement)
287 {
288// m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name);
289 writer.WriteEndElement();
210 } 290 }
211 if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
212 hasCreatorData = true;
213
214 //if (node.Name == "OwnerID")
215 //{
216 // UserAccount owner = GetUser(node.InnerText);
217 // if (owner != null)
218 // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
219 //}
220 }
221 291
222 if (!hasCreatorData && creator != null) 292 break;
223 { 293
224 XmlElement creatorData = doc.CreateElement("CreatorData"); 294 case XmlNodeType.EndElement:
225 creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; 295// m_log.DebugFormat("Depth {0} at EndElement", reader.Depth);
226 sop.AppendChild(creatorData); 296 if (sopDepth == reader.Depth)
297 {
298 if (!hasCreatorData && creator != null)
299 writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", m_HomeURI, creator.FirstName, creator.LastName));
300
301// m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth");
302 sopDepth = -1;
303 creator = null;
304 hasCreatorData = false;
305 }
306 writer.WriteEndElement();
307 break;
308
309 case XmlNodeType.EntityReference:
310 writer.WriteEntityRef(reader.Name);
311 break;
312
313 case XmlNodeType.ProcessingInstruction:
314 writer.WriteProcessingInstruction(reader.Name, reader.Value);
315 break;
316
317 case XmlNodeType.Text:
318 writer.WriteString(reader.Value);
319 break;
320
321 default:
322 m_log.WarnFormat("[HG ASSET MAPPER]: Unrecognized node in asset XML transform in {0}", m_scene.Name);
323 break;
227 } 324 }
228 } 325 }
326 }
327
328 protected string RewriteSOP(string xmlData)
329 {
330// Console.WriteLine("Input XML [{0}]", xmlData);
229 331
230 using (StringWriter wr = new StringWriter()) 332 using (StringWriter sw = new StringWriter())
333 using (XmlTextWriter writer = new XmlTextWriter(sw))
334 using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null))
335 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
231 { 336 {
232 doc.Save(wr); 337 TransformXml(reader, writer);
233 return wr.ToString(); 338
339 writer.WriteEndDocument();
340
341// Console.WriteLine("Output: [{0}]", sw.ToString());
342
343 return sw.ToString();
234 } 344 }
235 345
346 // We are now taking the more complex streaming approach above because some assets can be very large
347 // and can trigger higher CPU use or possibly memory problems.
348// XmlDocument doc = new XmlDocument();
349// doc.LoadXml(xml);
350// XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
351//
352// foreach (XmlNode sop in sops)
353// {
354// UserAccount creator = null;
355// bool hasCreatorData = false;
356// XmlNodeList nodes = sop.ChildNodes;
357// foreach (XmlNode node in nodes)
358// {
359// if (node.Name == "CreatorID")
360// {
361// UUID uuid = UUID.Zero;
362// UUID.TryParse(node.InnerText, out uuid);
363// creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
364// }
365// if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
366// hasCreatorData = true;
367//
368// //if (node.Name == "OwnerID")
369// //{
370// // UserAccount owner = GetUser(node.InnerText);
371// // if (owner != null)
372// // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
373// //}
374// }
375//
376// if (!hasCreatorData && creator != null)
377// {
378// XmlElement creatorData = doc.CreateElement("CreatorData");
379// creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
380// sop.AppendChild(creatorData);
381// }
382// }
383//
384// using (StringWriter wr = new StringWriter())
385// {
386// doc.Save(wr);
387// return wr.ToString();
388// }
236 } 389 }
237 390
238 // TODO: unused 391 // TODO: unused
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
new file mode 100644
index 0000000..779da43
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Xml;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.CoreModules.Framework.InventoryAccess;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces;
36using OpenSim.Tests.Common;
37
38namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
39{
40 [TestFixture]
41 public class HGAssetMapperTests : OpenSimTestCase
42 {
43 [Test]
44 public void TestPostAssetRewrite()
45 {
46 TestHelpers.InMethod();
47// TestHelpers.EnableLogging();
48
49 string homeUrl = "http://hg.HomeTestPostAssetRewriteGrid.com";
50 string foreignUrl = "http://hg.ForeignTestPostAssetRewriteGrid.com";
51 UUID assetId = TestHelpers.ParseTail(0x1);
52 UUID userId = TestHelpers.ParseTail(0x10);
53 string userFirstName = "TestPostAsset";
54 string userLastName = "Rewrite";
55 int soPartsCount = 3;
56
57 Scene scene = new SceneHelpers().SetupScene();
58 HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl);
59 UserAccount ua
60 = UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password");
61
62 //AssetBase ncAssetSet = AssetHelpers.CreateNotecardAsset(assetId, "TestPostAssetRewriteNotecard");
63 SceneObjectGroup so = SceneHelpers.CreateSceneObject(soPartsCount, ua.PrincipalID);
64 AssetBase ncAssetSet = AssetHelpers.CreateAsset(assetId, so);
65 ncAssetSet.CreatorID = foreignUrl;
66 hgam.PostAsset(foreignUrl, ncAssetSet);
67
68 AssetBase ncAssetGet = scene.AssetService.Get(assetId.ToString());
69 Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID);
70 string xmlData = Utils.BytesToString(ncAssetGet.Data);
71 XmlDocument ncAssetGetXmlDoc = new XmlDocument();
72 ncAssetGetXmlDoc.LoadXml(xmlData);
73 XmlNodeList creatorDataNodes = ncAssetGetXmlDoc.GetElementsByTagName("CreatorData");
74
75 Assert.AreEqual(soPartsCount, creatorDataNodes.Count);
76 //Console.WriteLine("creatorDataNodes {0}", creatorDataNodes.Count);
77
78 foreach (XmlNode creatorDataNode in creatorDataNodes)
79 {
80 Assert.AreEqual(
81 string.Format("{0};{1} {2}", homeUrl, ua.FirstName, ua.LastName), creatorDataNode.InnerText);
82 }
83 }
84 }
85} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 80b9c0a..c64ab44 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization; 44using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48 47
49namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests 48namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
50{ 49{
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
index a70261e..3abacbd 100644
--- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.Framework
67 m_timer.Elapsed += ProcessQueue; 67 m_timer.Elapsed += ProcessQueue;
68 m_timer.Start(); 68 m_timer.Start();
69 69
70 //Watchdog.StartThread( 70 //WorkManager.StartThread(
71 // ProcessQueue, 71 // ProcessQueue,
72 // "GridServiceRequestThread", 72 // "GridServiceRequestThread",
73 // ThreadPriority.BelowNormal, 73 // ThreadPriority.BelowNormal,
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
index 9d36aa5..4e3b7e5 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
@@ -32,7 +32,6 @@ using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.CoreModules.Framework.UserManagement; 33using OpenSim.Region.CoreModules.Framework.UserManagement;
34using OpenSim.Tests.Common; 34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36 35
37namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests 36namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests
38{ 37{
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
index e812d81..4d8b591 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs
@@ -41,7 +41,6 @@ using OpenSim.Framework;
41using OpenSim.Region.CoreModules.Scripting.HttpRequest; 41using OpenSim.Region.CoreModules.Scripting.HttpRequest;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Tests.Common; 43using OpenSim.Tests.Common;
44using OpenSim.Tests.Common.Mock;
45 44
46namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests 45namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests
47{ 46{
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 7119137..ed255bf 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.Scripting.VectorRender;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Scenes.Serialization; 41using OpenSim.Region.Framework.Scenes.Serialization;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 44namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 45{
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index d7ea906..af3700b 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
658 public void Process() 658 public void Process()
659 { 659 {
660 _finished = false; 660 _finished = false;
661 Watchdog.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); 661 WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false);
662 } 662 }
663 663
664 /* 664 /*
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
index 38862ca..7fcfc74 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
@@ -69,6 +69,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
69 get { return "HGAssetBroker"; } 69 get { return "HGAssetBroker"; }
70 } 70 }
71 71
72 public HGAssetBroker() {}
73
74 public HGAssetBroker(IConfigSource config)
75 {
76 Initialise(config);
77 }
78
72 public void Initialise(IConfigSource source) 79 public void Initialise(IConfigSource source)
73 { 80 {
74 IConfig moduleConfig = source.Configs["Modules"]; 81 IConfig moduleConfig = source.Configs["Modules"];
@@ -288,7 +295,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
288 295
289 if (asset != null) 296 if (asset != null)
290 { 297 {
291 Util.FireAndForget(delegate { handler(id, sender, asset); }); 298 Util.FireAndForget(delegate { handler(id, sender, asset); }, null, "HGAssetBroker.GotFromCache");
292 return true; 299 return true;
293 } 300 }
294 301
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index 97b7559..5f34450 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -236,7 +236,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
236 236
237 if (asset != null) 237 if (asset != null)
238 { 238 {
239 Util.FireAndForget(delegate { handler(id, sender, asset); }); 239 Util.FireAndForget(
240 o => handler(id, sender, asset), null, "LocalAssetServiceConnector.GotFromCacheCallback");
240 return true; 241 return true;
241 } 242 }
242 } 243 }
@@ -249,7 +250,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
249// if (null == a) 250// if (null == a)
250// m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id); 251// m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id);
251 252
252 Util.FireAndForget(delegate { handler(assetID, s, a); }); 253 Util.FireAndForget(
254 o => handler(assetID, s, a), null, "LocalAssetServiceConnector.GotFromServiceCallback");
253 }); 255 });
254 } 256 }
255 257
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 8e995db..4661c21 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -198,8 +198,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 198 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
199 { 199 {
200 GridRegion region = null; 200 GridRegion region = null;
201 uint regionX = Util.WorldToRegionLoc((uint)x); 201// uint regionX = Util.WorldToRegionLoc((uint)x);
202 uint regionY = Util.WorldToRegionLoc((uint)y); 202// uint regionY = Util.WorldToRegionLoc((uint)y);
203 203
204 // First see if it's a neighbour, even if it isn't on this sim. 204 // First see if it's a neighbour, even if it isn't on this sim.
205 // Neighbour data is cached in memory, so this is fast 205 // Neighbour data is cached in memory, so this is fast
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 470ef02..cbe0e37 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -184,12 +184,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
184 // Protect ourselves against the caller subsequently modifying the items list 184 // Protect ourselves against the caller subsequently modifying the items list
185 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); 185 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
186 186
187 Watchdog.RunInThread(delegate 187 WorkManager.RunInThread(delegate
188 { 188 {
189 foreach (InventoryItemBase item in items) 189 foreach (InventoryItemBase item in items)
190 if (!string.IsNullOrEmpty(item.CreatorData)) 190 if (!string.IsNullOrEmpty(item.CreatorData))
191 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 191 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
192 }, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID), null); 192 }, null, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID));
193 } 193 }
194 194
195 return invCol; 195 return invCol;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 3e0c9f3..9c6706f 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -372,7 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so 372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
373 // that users can enter the scene. If we allow the scripts to start in the loop above 373 // that users can enter the scene. If we allow the scripts to start in the loop above
374 // then they significantly increase the time until the OAR finishes loading. 374 // then they significantly increase the time until the OAR finishes loading.
375 Watchdog.RunInThread(o => 375 WorkManager.RunInThread(o =>
376 { 376 {
377 Thread.Sleep(15000); 377 Thread.Sleep(15000);
378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); 378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
@@ -387,7 +387,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
387 387
388 sceneContext.SceneObjects.Clear(); 388 sceneContext.SceneObjects.Clear();
389 } 389 }
390 }, string.Format("ReadArchiveStartScripts (request {0})", m_requestId), null); 390 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
391 391
392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
393 393
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index 924b999..b7d7c26 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
200 m_rootScene.AssetService, m_rootScene.UserAccountService, 200 m_rootScene.AssetService, m_rootScene.UserAccountService,
201 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); 201 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
202 202
203 Watchdog.RunInThread(o => ar.Execute(), "Archive Assets Request", null); 203 WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request");
204 204
205 // CloseArchive() will be called from ReceivedAllAssets() 205 // CloseArchive() will be called from ReceivedAllAssets()
206 } 206 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index ec39bc0..4d99a6e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -227,7 +227,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
227 finally 227 finally
228 { 228 {
229 if (timedOut) 229 if (timedOut)
230 Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", true); 230 WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
231 } 231 }
232 } 232 }
233 233
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
296 296
297 // We want to stop using the asset cache thread asap 297 // We want to stop using the asset cache thread asap
298 // as we now need to do the work of producing the rest of the archive 298 // as we now need to do the work of producing the rest of the archive
299 Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", false); 299 WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
300 } 300 }
301 else 301 else
302 { 302 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index b31257d..9f197f5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Scenes.Serialization; 45using OpenSim.Region.Framework.Scenes.Serialization;
46using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 46using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; 48using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
50using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; 49using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
51using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; 50using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
index 6d0253d..4ed67f3 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs
@@ -31,7 +31,6 @@ using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Tests.Common; 33using OpenSim.Tests.Common;
34using OpenSim.Tests.Common.Mock;
35 34
36namespace OpenSim.Region.CoreModules.World.Land.Tests 35namespace OpenSim.Region.CoreModules.World.Land.Tests
37{ 36{
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index 0945b43..949acb6 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -36,7 +36,6 @@ using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40 39
41namespace OpenSim.Region.CoreModules.World.Land.Tests 40namespace OpenSim.Region.CoreModules.World.Land.Tests
42{ 41{
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
index 03a96a4..ee57aed 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Region.CoreModules.World.Media.Moap;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests 43namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
45{ 44{
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 78fbefe..767f75f 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -381,7 +381,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
381 381
382// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); 382// m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread");
383 383
384 Watchdog.StartThread( 384 WorkManager.StartThread(
385 process, 385 process,
386 string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), 386 string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName),
387 ThreadPriority.BelowNormal, 387 ThreadPriority.BelowNormal,
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 5d07a5f..1ebef90 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -98,6 +98,8 @@ namespace OpenSim.Region.Framework.Interfaces
98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
99 99
100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); 100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
101
102 bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition);
101 } 103 }
102 104
103 public interface IUserAgentVerificationModule 105 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0399a52..f7c12d6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -6,7 +6,7 @@
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
@@ -360,19 +360,41 @@ namespace OpenSim.Region.Framework.Scenes
360 public uint MaintenanceRun { get; private set; } 360 public uint MaintenanceRun { get; private set; }
361 361
362 /// <summary> 362 /// <summary>
363 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 363 /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we
364 /// will sleep for the remaining period. 364 /// will sleep for the remaining period.
365 /// </summary> 365 /// </summary>
366 /// <remarks> 366 /// <remarks>
367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations 367 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
368 /// occur too quickly (viewer 1) or with even more slide (viewer 2). 368 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
369 /// </remarks> 369 /// </remarks>
370 public float MinFrameTime { get; private set; } 370 public int MinFrameTicks
371 {
372 get { return m_minFrameTicks; }
373 private set
374 {
375 m_minFrameTicks = value;
376 MinFrameSeconds = (float)m_minFrameTicks / 1000;
377 }
378 }
379 private int m_minFrameTicks;
371 380
372 /// <summary> 381 /// <summary>
373 /// The minimum length of time in seconds that will be taken for a maintenance run. 382 /// The minimum length of time in seconds that will be taken for a scene frame.
374 /// </summary> 383 /// </summary>
375 public float MinMaintenanceTime { get; private set; } 384 /// <remarks>
385 /// Always derived from MinFrameTicks.
386 /// </remarks>
387 public float MinFrameSeconds { get; private set; }
388
389 /// <summary>
390 /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we
391 /// will sleep for the remaining period.
392 /// </summary>
393 /// <remarks>
394 /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations
395 /// occur too quickly (viewer 1) or with even more slide (viewer 2).
396 /// </remarks>
397 public int MinMaintenanceTicks { get; set; }
376 398
377 private int m_update_physics = 1; 399 private int m_update_physics = 1;
378 private int m_update_entitymovement = 1; 400 private int m_update_entitymovement = 1;
@@ -412,8 +434,16 @@ namespace OpenSim.Region.Framework.Scenes
412 /// asynchronously from the update loop. 434 /// asynchronously from the update loop.
413 /// </summary> 435 /// </summary>
414 private bool m_cleaningTemps = false; 436 private bool m_cleaningTemps = false;
437
438 /// <summary>
439 /// Used to control main scene thread looping time when not updating via timer.
440 /// </summary>
441 private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false);
415 442
416// private Object m_heartbeatLock = new Object(); 443 /// <summary>
444 /// Used to control maintenance thread runs.
445 /// </summary>
446 private ManualResetEvent m_maintenanceWaitEvent = new ManualResetEvent(false);
417 447
418 // TODO: Possibly stop other classes being able to manipulate this directly. 448 // TODO: Possibly stop other classes being able to manipulate this directly.
419 private SceneGraph m_sceneGraph; 449 private SceneGraph m_sceneGraph;
@@ -782,8 +812,8 @@ namespace OpenSim.Region.Framework.Scenes
782 : this(regInfo, physicsScene) 812 : this(regInfo, physicsScene)
783 { 813 {
784 m_config = config; 814 m_config = config;
785 MinFrameTime = 0.089f; 815 MinFrameTicks = 89;
786 MinMaintenanceTime = 1; 816 MinMaintenanceTicks = 1000;
787 SeeIntoRegion = true; 817 SeeIntoRegion = true;
788 818
789 Random random = new Random(); 819 Random random = new Random();
@@ -1005,7 +1035,9 @@ namespace OpenSim.Region.Framework.Scenes
1005 } 1035 }
1006 } 1036 }
1007 1037
1008 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); 1038 if (startupConfig.Contains("MinFrameTime"))
1039 MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000);
1040
1009 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); 1041 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
1010 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 1042 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
1011 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); 1043 m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement);
@@ -1396,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes
1396 } 1428 }
1397 1429
1398 m_heartbeatThread 1430 m_heartbeatThread
1399 = Watchdog.StartThread( 1431 = WorkManager.StartThread(
1400 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); 1432 Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
1401 1433
1402 StartScripts(); 1434 StartScripts();
@@ -1437,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes
1437 // alarms for scenes with many objects. 1469 // alarms for scenes with many objects.
1438 Update(1); 1470 Update(1);
1439 1471
1440 Watchdog.StartThread( 1472 WorkManager.StartThread(
1441 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); 1473 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1442 1474
1443 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1475 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
@@ -1445,13 +1477,14 @@ namespace OpenSim.Region.Framework.Scenes
1445 1477
1446 if (UpdateOnTimer) 1478 if (UpdateOnTimer)
1447 { 1479 {
1448 m_sceneUpdateTimer = new Timer(MinFrameTime * 1000); 1480 m_sceneUpdateTimer = new Timer(MinFrameTicks);
1449 m_sceneUpdateTimer.AutoReset = true; 1481 m_sceneUpdateTimer.AutoReset = true;
1450 m_sceneUpdateTimer.Elapsed += Update; 1482 m_sceneUpdateTimer.Elapsed += Update;
1451 m_sceneUpdateTimer.Start(); 1483 m_sceneUpdateTimer.Start();
1452 } 1484 }
1453 else 1485 else
1454 { 1486 {
1487 Thread.CurrentThread.Priority = ThreadPriority.Highest;
1455 Update(-1); 1488 Update(-1);
1456 Watchdog.RemoveThread(); 1489 Watchdog.RemoveThread();
1457 m_isRunning = false; 1490 m_isRunning = false;
@@ -1535,10 +1568,10 @@ namespace OpenSim.Region.Framework.Scenes
1535 tmpMS = Util.EnvironmentTickCount(); 1568 tmpMS = Util.EnvironmentTickCount();
1536 m_cleaningTemps = true; 1569 m_cleaningTemps = true;
1537 1570
1538 Watchdog.RunInThread( 1571 WorkManager.RunInThread(
1539 delegate { CleanTempObjects(); m_cleaningTemps = false; }, 1572 delegate { CleanTempObjects(); m_cleaningTemps = false; },
1540 string.Format("CleanTempObjects ({0})", Name), 1573 null,
1541 null); 1574 string.Format("CleanTempObjects ({0})", Name));
1542 1575
1543 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); 1576 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1544 } 1577 }
@@ -1548,19 +1581,19 @@ namespace OpenSim.Region.Framework.Scenes
1548 previousMaintenanceTick = m_lastMaintenanceTick; 1581 previousMaintenanceTick = m_lastMaintenanceTick;
1549 m_lastMaintenanceTick = Util.EnvironmentTickCount(); 1582 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1550 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); 1583 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1551 runtc = (int)(MinMaintenanceTime * 1000) - runtc; 1584 runtc = MinMaintenanceTicks - runtc;
1552 1585
1553 if (runtc > 0) 1586 if (runtc > 0)
1554 Thread.Sleep(runtc); 1587 m_maintenanceWaitEvent.WaitOne(runtc);
1555 1588
1556 // Optionally warn if a frame takes double the amount of time that it should. 1589 // Optionally warn if a frame takes double the amount of time that it should.
1557 if (DebugUpdates 1590 if (DebugUpdates
1558 && Util.EnvironmentTickCountSubtract( 1591 && Util.EnvironmentTickCountSubtract(
1559 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) 1592 m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2)
1560 m_log.WarnFormat( 1593 m_log.WarnFormat(
1561 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", 1594 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1562 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), 1595 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1563 MinMaintenanceTime * 1000, 1596 MinMaintenanceTicks,
1564 RegionInfo.RegionName); 1597 RegionInfo.RegionName);
1565 } 1598 }
1566 } 1599 }
@@ -1612,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes
1612 if (Frame % m_update_physics == 0) 1645 if (Frame % m_update_physics == 0)
1613 { 1646 {
1614 if (PhysicsEnabled) 1647 if (PhysicsEnabled)
1615 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); 1648 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds);
1616 1649
1617 if (SynchronizeScene != null) 1650 if (SynchronizeScene != null)
1618 SynchronizeScene(this); 1651 SynchronizeScene(this);
@@ -1710,18 +1743,16 @@ namespace OpenSim.Region.Framework.Scenes
1710 { 1743 {
1711 Watchdog.UpdateThread(); 1744 Watchdog.UpdateThread();
1712 1745
1713 tmpMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(), m_lastFrameTick); 1746 spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick);
1714 tmpMS = (int)(MinFrameTime * 1000) - tmpMS;
1715 1747
1716 if (tmpMS > 0) 1748 if (spareMS > 0)
1717 { 1749 m_updateWaitEvent.WaitOne(spareMS);
1718 spareMS = tmpMS; 1750 else
1719 Thread.Sleep(tmpMS); 1751 spareMS = 0;
1720 }
1721 } 1752 }
1722 else 1753 else
1723 { 1754 {
1724 spareMS = Math.Max(0, (int)(MinFrameTime * 1000) - physicsMS2 - agentMS - physicsMS -otherMS); 1755 spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS);
1725 } 1756 }
1726 1757
1727 previousFrameTick = m_lastFrameTick; 1758 previousFrameTick = m_lastFrameTick;
@@ -1744,11 +1775,11 @@ namespace OpenSim.Region.Framework.Scenes
1744 // Optionally warn if a frame takes double the amount of time that it should. 1775 // Optionally warn if a frame takes double the amount of time that it should.
1745 if (DebugUpdates 1776 if (DebugUpdates
1746 && Util.EnvironmentTickCountSubtract( 1777 && Util.EnvironmentTickCountSubtract(
1747 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) 1778 m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2)
1748 m_log.WarnFormat( 1779 m_log.WarnFormat(
1749 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1780 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1750 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), 1781 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1751 MinFrameTime * 1000, 1782 MinFrameTicks,
1752 RegionInfo.RegionName); 1783 RegionInfo.RegionName);
1753 } 1784 }
1754 1785
@@ -1812,7 +1843,7 @@ namespace OpenSim.Region.Framework.Scenes
1812 if (!m_backingup) 1843 if (!m_backingup)
1813 { 1844 {
1814 m_backingup = true; 1845 m_backingup = true;
1815 Watchdog.RunInThread(o => Backup(false), string.Format("BackupWaitCallback ({0})", Name), null); 1846 WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name));
1816 } 1847 }
1817 } 1848 }
1818 1849
@@ -2592,48 +2623,8 @@ namespace OpenSim.Region.Framework.Scenes
2592 return false; 2623 return false;
2593 } 2624 }
2594 2625
2595 // If the user is banned, we won't let any of their objects 2626 if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition))
2596 // enter. Period. 2627 return false;
2597 //
2598 if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID))
2599 {
2600 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
2601 return false;
2602 }
2603
2604 if (newPosition != Vector3.Zero)
2605 newObject.RootPart.GroupPosition = newPosition;
2606
2607 if (!AddSceneObject(newObject))
2608 {
2609 m_log.DebugFormat(
2610 "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
2611 return false;
2612 }
2613
2614 if (!newObject.IsAttachment)
2615 {
2616 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2617 // it
2618 if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
2619 {
2620 // Deny non attachments based on parcel settings
2621 //
2622 m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2623
2624 DeleteSceneObject(newObject, false);
2625
2626 return false;
2627 }
2628
2629 // For attachments, we need to wait until the agent is root
2630 // before we restart the scripts, or else some functions won't work.
2631 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2632 newObject.ResumeScripts();
2633
2634 if (newObject.RootPart.KeyframeMotion != null)
2635 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2636 }
2637 2628
2638 // Do this as late as possible so that listeners have full access to the incoming object 2629 // Do this as late as possible so that listeners have full access to the incoming object
2639 EventManager.TriggerOnIncomingSceneObject(newObject); 2630 EventManager.TriggerOnIncomingSceneObject(newObject);
@@ -2702,16 +2693,6 @@ namespace OpenSim.Region.Framework.Scenes
2702 return true; 2693 return true;
2703 } 2694 }
2704 2695
2705 private int GetStateSource(SceneObjectGroup sog)
2706 {
2707 ScenePresence sp = GetScenePresence(sog.OwnerID);
2708
2709 if (sp != null)
2710 return sp.GetStateSource();
2711
2712 return 2; // StateSource.PrimCrossing
2713 }
2714
2715 #endregion 2696 #endregion
2716 2697
2717 #region Add/Remove Avatar Methods 2698 #region Add/Remove Avatar Methods
@@ -2758,29 +2739,41 @@ namespace OpenSim.Region.Framework.Scenes
2758 m_log.DebugFormat( 2739 m_log.DebugFormat(
2759 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", 2740 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2760 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); 2741 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2761 2742
2743 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2744
2745 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2746 // client is for a root or child agent.
2747 // We must also set this before adding the client to the client manager so that an exception later on
2748 // does not leave a client manager entry without the scene agent set, which will cause other code
2749 // to fail since any entry in the client manager should have a ScenePresence
2750 //
2751 // XXX: This may be better set for a new client before that client is added to the client manager.
2752 // But need to know what happens in the case where a ScenePresence is already present (and if this
2753 // actually occurs).
2754 client.SceneAgent = sp;
2755
2762 m_clientManager.Add(client); 2756 m_clientManager.Add(client);
2763 SubscribeToClientEvents(client); 2757 SubscribeToClientEvents(client);
2764
2765 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2766 m_eventManager.TriggerOnNewPresence(sp); 2758 m_eventManager.TriggerOnNewPresence(sp);
2767 2759
2768 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; 2760 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2769 } 2761 }
2770 else 2762 else
2771 { 2763 {
2764 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2765 // client is for a root or child agent.
2766 // XXX: This may be better set for a new client before that client is added to the client manager.
2767 // But need to know what happens in the case where a ScenePresence is already present (and if this
2768 // actually occurs).
2769 client.SceneAgent = sp;
2770
2772 m_log.WarnFormat( 2771 m_log.WarnFormat(
2773 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 2772 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2774 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 2773 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
2774
2775 reallyNew = false; 2775 reallyNew = false;
2776 } 2776 }
2777
2778 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
2779 // client is for a root or child agent.
2780 // XXX: This may be better set for a new client before that client is added to the client manager.
2781 // But need to know what happens in the case where a ScenePresence is already present (and if this
2782 // actually occurs).
2783 client.SceneAgent = sp;
2784 2777
2785 // This is currently also being done earlier in NewUserConnection for real users to see if this 2778 // This is currently also being done earlier in NewUserConnection for real users to see if this
2786 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other 2779 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index bfa3b9a..9db5309 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -226,7 +226,10 @@ namespace OpenSim.Region.Framework.Scenes
226 // We must take a copy here since handle is acts like a reference when used in an iterator. 226 // We must take a copy here since handle is acts like a reference when used in an iterator.
227 // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. 227 // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region.
228 ulong handleCopy = handle; 228 ulong handleCopy = handle;
229 Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); 229 Util.FireAndForget(
230 o => SendCloseChildAgent(agentID, handleCopy, auth_code),
231 null,
232 "SceneCommunicationService.SendCloseChildAgentConnections");
230 } 233 }
231 } 234 }
232 235
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 87063c6..5a35aff 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1228,10 +1228,11 @@ namespace OpenSim.Region.Framework.Scenes
1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call. 1228 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1229 if (Scene.AttachmentsModule != null) 1229 if (Scene.AttachmentsModule != null)
1230 { 1230 {
1231 Util.FireAndForget(o => 1231 WorkManager.RunJob(
1232 { 1232 "RezAttachments",
1233 Scene.AttachmentsModule.RezAttachments(this); 1233 o => Scene.AttachmentsModule.RezAttachments(this),
1234 }); 1234 null,
1235 string.Format("Rez attachments for {0} in {1}", Name, Scene.Name));
1235 } 1236 }
1236 } 1237 }
1237 else 1238 else
@@ -1241,11 +1242,6 @@ namespace OpenSim.Region.Framework.Scenes
1241 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1242 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1242 // not transporting the required data. 1243 // not transporting the required data.
1243 // 1244 //
1244 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1245 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1246 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1247 // not transporting the required data.
1248 //
1249 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 1245 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1250 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here 1246 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1251 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. 1247 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
@@ -1254,23 +1250,16 @@ namespace OpenSim.Region.Framework.Scenes
1254 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing 1250 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1255 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the 1251 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1256 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. 1252 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1257 //
1258 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1259 // be locked, allowing race conditions if other code changes the attachments list.
1260 List<SceneObjectGroup> attachments = GetAttachments(); 1253 List<SceneObjectGroup> attachments = GetAttachments();
1261 1254
1262 if (attachments.Count > 0) 1255 if (attachments.Count > 0)
1263 { 1256 {
1264 m_log.DebugFormat( 1257 WorkManager.RunJob(
1265 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1258 "StartAttachmentScripts",
1266 1259 o => RestartAttachmentScripts(attachments),
1267 // Resume scripts 1260 null,
1268 foreach (SceneObjectGroup sog in attachments) 1261 string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
1269 { 1262 true);
1270 sog.ScheduleGroupForFullUpdate();
1271 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1272 sog.ResumeScripts();
1273 }
1274 } 1263 }
1275 } 1264 }
1276 1265
@@ -1294,6 +1283,20 @@ namespace OpenSim.Region.Framework.Scenes
1294 return true; 1283 return true;
1295 } 1284 }
1296 1285
1286 private void RestartAttachmentScripts(List<SceneObjectGroup> attachments)
1287 {
1288 m_log.DebugFormat(
1289 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1290
1291 // Resume scripts
1292 foreach (SceneObjectGroup sog in attachments)
1293 {
1294 sog.ScheduleGroupForFullUpdate();
1295 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1296 sog.ResumeScripts();
1297 }
1298 }
1299
1297 private static bool IsRealLogin(TeleportFlags teleportFlags) 1300 private static bool IsRealLogin(TeleportFlags teleportFlags)
1298 { 1301 {
1299 return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); 1302 return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0);
@@ -1326,7 +1329,7 @@ namespace OpenSim.Region.Framework.Scenes
1326 1329
1327 UseFakeGroupTitle = false; 1330 UseFakeGroupTitle = false;
1328 SendAvatarDataToAllClients(false); 1331 SendAvatarDataToAllClients(false);
1329 }); 1332 }, null, "Scenepresence.ForceViewersUpdateName");
1330 } 1333 }
1331 1334
1332 public int GetStateSource() 1335 public int GetStateSource()
@@ -1809,14 +1812,15 @@ namespace OpenSim.Region.Framework.Scenes
1809 1812
1810 } 1813 }
1811 1814
1812 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1815 // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region
1813 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. 1816 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work.
1814 // This may be due to viewer code or it may be something we're not doing properly simulator side. 1817 // This may be due to viewer code or it may be something we're not doing properly simulator side.
1815 lock (m_attachments) 1818 WorkManager.RunJob(
1816 { 1819 "ScheduleAttachmentsForFullUpdate",
1817 foreach (SceneObjectGroup sog in m_attachments) 1820 o => ScheduleAttachmentsForFullUpdate(),
1818 sog.ScheduleGroupForFullUpdate(); 1821 null,
1819 } 1822 string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name),
1823 true);
1820 1824
1821 // m_log.DebugFormat( 1825 // m_log.DebugFormat(
1822 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1826 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
@@ -1828,6 +1832,15 @@ namespace OpenSim.Region.Framework.Scenes
1828 } 1832 }
1829 } 1833 }
1830 1834
1835 private void ScheduleAttachmentsForFullUpdate()
1836 {
1837 lock (m_attachments)
1838 {
1839 foreach (SceneObjectGroup sog in m_attachments)
1840 sog.ScheduleGroupForFullUpdate();
1841 }
1842 }
1843
1831 /// <summary> 1844 /// <summary>
1832 /// Callback for the Camera view block check. Gets called with the results of the camera view block test 1845 /// Callback for the Camera view block check. Gets called with the results of the camera view block test
1833 /// hitYN is true when there's something in the way. 1846 /// hitYN is true when there's something in the way.
@@ -3362,7 +3375,7 @@ namespace OpenSim.Region.Framework.Scenes
3362 SentInitialDataToClient = true; 3375 SentInitialDataToClient = true;
3363 3376
3364 // Send all scene object to the new client 3377 // Send all scene object to the new client
3365 Watchdog.RunInThread(delegate 3378 WorkManager.RunJob("SendInitialDataToClient", delegate
3366 { 3379 {
3367// m_log.DebugFormat( 3380// m_log.DebugFormat(
3368// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}", 3381// "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}",
@@ -3380,7 +3393,7 @@ namespace OpenSim.Region.Framework.Scenes
3380 if (e != null && e is SceneObjectGroup) 3393 if (e != null && e is SceneObjectGroup)
3381 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 3394 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
3382 } 3395 }
3383 }, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), null); 3396 }, null, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), false, true);
3384 } 3397 }
3385 3398
3386 /// <summary> 3399 /// <summary>
@@ -3617,7 +3630,8 @@ namespace OpenSim.Region.Framework.Scenes
3617 agentpos.CopyFrom(cadu, ControllingClient.SessionId); 3630 agentpos.CopyFrom(cadu, ControllingClient.SessionId);
3618 3631
3619 // Let's get this out of the update loop 3632 // Let's get this out of the update loop
3620 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); 3633 Util.FireAndForget(
3634 o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates");
3621 } 3635 }
3622 } 3636 }
3623 3637
@@ -4035,9 +4049,23 @@ namespace OpenSim.Region.Framework.Scenes
4035 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); 4049 Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
4036 4050
4037 if (Scene.AttachmentsModule != null) 4051 if (Scene.AttachmentsModule != null)
4038 Scene.AttachmentsModule.CopyAttachments(cAgent, this); 4052 {
4039 4053 // If the JobEngine is running we can schedule this job now and continue rather than waiting for all
4040 // This must occur after attachments are copied, as it releases the CompleteMovement() calling thread 4054 // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory
4055 // graph is inspected for each attachments and assets possibly fetched.
4056 //
4057 // We don't need to worry about a race condition as the job to later start the scripts is also
4058 // JobEngine scheduled and so will always occur after this task.
4059 // XXX: This will not be true if JobEngine ever gets more than one thread.
4060 WorkManager.RunJob(
4061 "CopyAttachments",
4062 o => Scene.AttachmentsModule.CopyAttachments(cAgent, this),
4063 null,
4064 string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name),
4065 true);
4066 }
4067
4068 // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread
4041 // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart 4069 // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart
4042 // script attachments can outrace this thread. 4070 // script attachments can outrace this thread.
4043 lock (m_originRegionIDAccessLock) 4071 lock (m_originRegionIDAccessLock)
@@ -4471,7 +4499,7 @@ namespace OpenSim.Region.Framework.Scenes
4471 } 4499 }
4472 } 4500 }
4473 } 4501 }
4474 }); 4502 }, null, "ScenePresence.SendScriptEventToAttachments");
4475 } 4503 }
4476 4504
4477 /// <summary> 4505 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 95f9caf..8f1e345 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -224,7 +224,7 @@ namespace OpenSim.Region.Framework.Scenes
224 public SimStatsReporter(Scene scene) 224 public SimStatsReporter(Scene scene)
225 { 225 {
226 m_scene = scene; 226 m_scene = scene;
227 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; 227 m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps;
228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); 228 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
229 ReportingRegion = scene.RegionInfo; 229 ReportingRegion = scene.RegionInfo;
230 230
@@ -239,7 +239,7 @@ namespace OpenSim.Region.Framework.Scenes
239 239
240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit 240 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
241 /// longer than ideal (which in itself is a concern). 241 /// longer than ideal (which in itself is a concern).
242 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2); 242 SlowFramesStatReportThreshold = (int)Math.Ceiling(scene.MinFrameTicks * 1.2);
243 243
244 SlowFramesStat 244 SlowFramesStat
245 = new Stat( 245 = new Stat(
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 575a081..b6b3344 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
41{ 40{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
index 2d831fa..6118004 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs
@@ -36,7 +36,6 @@ using OpenSim.Framework.Communications;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40 39
41namespace OpenSim.Region.Framework.Scenes.Tests 40namespace OpenSim.Region.Framework.Scenes.Tests
42{ 41{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index a07d64c..bdf0700 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
index 969f73d..5635c20 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
37using OpenSim.Region.CoreModules.World.Land; 37using OpenSim.Region.CoreModules.World.Land;
38using OpenSim.Region.OptionalModules; 38using OpenSim.Region.OptionalModules;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 5b5fb92..558ba2c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.World.Permissions;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.Framework.Scenes.Tests 44namespace OpenSim.Region.Framework.Scenes.Tests
46{ 45{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index 0aefcbd..c2e0ae3 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38using log4net; 37using log4net;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
index c264433..11e9084 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Framework.Communications; 33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
index a58e735..fdbe7ae 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
@@ -35,7 +35,6 @@ using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39 38
40namespace OpenSim.Region.Framework.Scenes.Tests 39namespace OpenSim.Region.Framework.Scenes.Tests
41{ 40{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
index abaa1d1..974529a 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 6985766..5ba754c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
index 4883ae7..cdebe25 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Framework.Communications; 33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index 2b79271..fd49c88 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 40using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Region.Framework.Scenes.Tests 43namespace OpenSim.Region.Framework.Scenes.Tests
45{ 44{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index e2ed9c8..06e6423 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
44using OpenSim.Region.CoreModules.World.Serialiser; 44using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48using GridRegion = OpenSim.Services.Interfaces.GridRegion; 47using GridRegion = OpenSim.Services.Interfaces.GridRegion;
49 48
50namespace OpenSim.Region.Framework.Scenes.Tests 49namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
index 1cd8ae9..42cfa1b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.Physics.Manager; 44using OpenSim.Region.Physics.Manager;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.Framework.Scenes.Tests 47namespace OpenSim.Region.Framework.Scenes.Tests
49{ 48{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index d80afd3..c6e3b8b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.Framework.Scenes.Tests 41namespace OpenSim.Region.Framework.Scenes.Tests
43{ 42{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
index 4fdfc74..cca30db 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Interfaces; 48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Tests.Common; 49using OpenSim.Tests.Common;
50using OpenSim.Tests.Common.Mock;
51using GridRegion = OpenSim.Services.Interfaces.GridRegion; 50using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52 51
53namespace OpenSim.Region.Framework.Scenes.Tests 52namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
index cf211a1..e14da8b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Region.CoreModules.World.Permissions; 41using OpenSim.Region.CoreModules.World.Permissions;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.Framework.Scenes.Tests 44namespace OpenSim.Region.Framework.Scenes.Tests
46{ 45{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
index 2b84364..b775178 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Framework.Servers;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41using System.Threading; 40using System.Threading;
42 41
43namespace OpenSim.Region.Framework.Scenes.Tests 42namespace OpenSim.Region.Framework.Scenes.Tests
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index 8c25dbc..da93d44 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Region.CoreModules.World.Permissions; 44using OpenSim.Region.CoreModules.World.Permissions;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.Framework.Scenes.Tests 47namespace OpenSim.Region.Framework.Scenes.Tests
49{ 48{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
index 1667002..2d36214 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
@@ -34,7 +34,6 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Region.Framework.Scenes.Tests 38namespace OpenSim.Region.Framework.Scenes.Tests
40{ 39{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
index 9a97acc..584a03c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs
@@ -32,7 +32,6 @@ using OpenSim.Region.Framework.Scenes;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Services.Interfaces; 33using OpenSim.Services.Interfaces;
34using OpenSim.Tests.Common; 34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36 35
37namespace OpenSim.Region.Framework.Scenes.Tests 36namespace OpenSim.Region.Framework.Scenes.Tests
38{ 37{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 52e4362..33ef83b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -42,7 +42,6 @@ using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.CoreModules.World.Serialiser; 42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock;
46 45
47namespace OpenSim.Region.Framework.Scenes.Tests 46namespace OpenSim.Region.Framework.Scenes.Tests
48{ 47{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index f809267..9655d19 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.Framework.Tests 49namespace OpenSim.Region.Framework.Tests
51{ 50{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 0736278..edc0a52 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser;
45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 45using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.Framework.Tests 49namespace OpenSim.Region.Framework.Tests
51{ 50{
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index 1e59e3f..a12b170 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -33,7 +33,6 @@ using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
35using OpenSim.Tests.Common; 35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37 36
38namespace OpenSim.Region.Framework.Scenes.Tests 37namespace OpenSim.Region.Framework.Scenes.Tests
39{ 38{
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index d07cc6a..2450cdb 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -57,22 +57,83 @@ namespace OpenSim.Region.Framework.Scenes
57 57
58 protected IAssetService m_assetService; 58 protected IAssetService m_assetService;
59 59
60// /// <summary> 60 // /// <summary>
61// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate 61 // /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
62// /// asset was found by the asset service. 62 // /// asset was found by the asset service.
63// /// </summary> 63 // /// </summary>
64// private AssetBase m_requestedObjectAsset; 64 // private AssetBase m_requestedObjectAsset;
65// 65 //
66// /// <summary> 66 // /// <summary>
67// /// Signal whether we are currently waiting for the asset service to deliver an asset. 67 // /// Signal whether we are currently waiting for the asset service to deliver an asset.
68// /// </summary> 68 // /// </summary>
69// private bool m_waitingForObjectAsset; 69 // private bool m_waitingForObjectAsset;
70 70
71 public UuidGatherer(IAssetService assetService) 71 public UuidGatherer(IAssetService assetService)
72 { 72 {
73 m_assetService = assetService; 73 m_assetService = assetService;
74 } 74 }
75 75
76 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary>
79 /// <remarks>
80 /// This includes both those directly associated with
81 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
82 /// within this object).
83 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
84 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
85 /// is of a type which is known not to reference any other assets
86 /// </remarks>
87 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
88 /// <param name="assetUuids">The assets gathered</param>
89 public void GatherAssetUuids(UUID assetUuid, IDictionary<UUID, sbyte> assetUuids)
90 {
91 // avoid infinite loops
92 if (assetUuids.ContainsKey(assetUuid))
93 return;
94
95 try
96 {
97 AssetBase assetBase = GetAsset(assetUuid);
98
99 if (null != assetBase)
100 {
101 sbyte assetType = assetBase.Type;
102 assetUuids[assetUuid] = assetType;
103
104 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
105 {
106 GetWearableAssetUuids(assetBase, assetUuids);
107 }
108 else if ((sbyte)AssetType.Gesture == assetType)
109 {
110 GetGestureAssetUuids(assetBase, assetUuids);
111 }
112 else if ((sbyte)AssetType.Notecard == assetType)
113 {
114 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
115 }
116 else if ((sbyte)AssetType.LSLText == assetType)
117 {
118 GetTextEmbeddedAssetUuids(assetBase, assetUuids);
119 }
120 else if ((sbyte)OpenSimAssetType.Material == assetType)
121 {
122 GetMaterialAssetUuids(assetBase, assetUuids);
123 }
124 else if ((sbyte)AssetType.Object == assetType)
125 {
126 GetSceneObjectAssetUuids(assetBase, assetUuids);
127 }
128 }
129 }
130 catch (Exception)
131 {
132 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
133 throw;
134 }
135 }
136
76 /// <summary> 137 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid 138 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary> 139 /// </summary>
@@ -93,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
93 try 154 try
94 { 155 {
95 assetUuids[assetUuid] = assetType; 156 assetUuids[assetUuid] = assetType;
96 157
97 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 158 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
98 { 159 {
99 GetWearableAssetUuids(assetUuid, assetUuids); 160 GetWearableAssetUuids(assetUuid, assetUuids);
@@ -143,16 +204,16 @@ namespace OpenSim.Region.Framework.Scenes
143 /// </param> 204 /// </param>
144 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids) 205 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids)
145 { 206 {
146// m_log.DebugFormat( 207 // m_log.DebugFormat(
147// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); 208 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
148 209
149 SceneObjectPart[] parts = sceneObject.Parts; 210 SceneObjectPart[] parts = sceneObject.Parts;
150 for (int i = 0; i < parts.Length; i++) 211 for (int i = 0; i < parts.Length; i++)
151 { 212 {
152 SceneObjectPart part = parts[i]; 213 SceneObjectPart part = parts[i];
153 214
154// m_log.DebugFormat( 215 // m_log.DebugFormat(
155// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); 216 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
156 217
157 try 218 try
158 { 219 {
@@ -173,7 +234,7 @@ namespace OpenSim.Region.Framework.Scenes
173 } 234 }
174 } 235 }
175 } 236 }
176 237
177 // If the prim is a sculpt then preserve this information too 238 // If the prim is a sculpt then preserve this information too
178 if (part.Shape.SculptTexture != UUID.Zero) 239 if (part.Shape.SculptTexture != UUID.Zero)
179 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; 240 assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
@@ -201,13 +262,13 @@ namespace OpenSim.Region.Framework.Scenes
201 } 262 }
202 263
203 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 264 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
204 265
205 // Now analyze this prim's inventory items to preserve all the uuids that they reference 266 // Now analyze this prim's inventory items to preserve all the uuids that they reference
206 foreach (TaskInventoryItem tii in taskDictionary.Values) 267 foreach (TaskInventoryItem tii in taskDictionary.Values)
207 { 268 {
208// m_log.DebugFormat( 269 // m_log.DebugFormat(
209// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", 270 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
210// tii.Name, tii.Type, part.Name, part.UUID); 271 // tii.Name, tii.Type, part.Name, part.UUID);
211 272
212 if (!assetUuids.ContainsKey(tii.AssetID)) 273 if (!assetUuids.ContainsKey(tii.AssetID))
213 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids); 274 GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids);
@@ -217,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes
217 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and 278 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
218 // inventory transfer. There needs to be a way for a module to register a method without assuming a 279 // inventory transfer. There needs to be a way for a module to register a method without assuming a
219 // Scene.EventManager is present. 280 // Scene.EventManager is present.
220// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); 281 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
221 282
222 283
223 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs 284 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
@@ -246,19 +307,6 @@ namespace OpenSim.Region.Framework.Scenes
246 } 307 }
247 } 308 }
248 309
249// /// <summary>
250// /// The callback made when we request the asset for an object from the asset service.
251// /// </summary>
252// private void AssetReceived(string id, Object sender, AssetBase asset)
253// {
254// lock (this)
255// {
256// m_requestedObjectAsset = asset;
257// m_waitingForObjectAsset = false;
258// Monitor.Pulse(this);
259// }
260// }
261
262 /// <summary> 310 /// <summary>
263 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps 311 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
264 /// stored in legacy format in part.DynAttrs 312 /// stored in legacy format in part.DynAttrs
@@ -327,7 +375,7 @@ namespace OpenSim.Region.Framework.Scenes
327 } 375 }
328 } 376 }
329 } 377 }
330 378
331 /// <summary> 379 /// <summary>
332 /// Get an asset synchronously, potentially using an asynchronous callback. If the 380 /// Get an asset synchronously, potentially using an asynchronous callback. If the
333 /// asynchronous callback is used, we will wait for it to complete. 381 /// asynchronous callback is used, we will wait for it to complete.
@@ -340,54 +388,64 @@ namespace OpenSim.Region.Framework.Scenes
340 388
341 // XXX: Switching to do this synchronously where the call was async before but we always waited for it 389 // XXX: Switching to do this synchronously where the call was async before but we always waited for it
342 // to complete anyway! 390 // to complete anyway!
343// m_waitingForObjectAsset = true; 391 // m_waitingForObjectAsset = true;
344// m_assetCache.Get(uuid.ToString(), this, AssetReceived); 392 // m_assetCache.Get(uuid.ToString(), this, AssetReceived);
345// 393 //
346// // The asset cache callback can either 394 // // The asset cache callback can either
347// // 395 // //
348// // 1. Complete on the same thread (if the asset is already in the cache) or 396 // // 1. Complete on the same thread (if the asset is already in the cache) or
349// // 2. Come in via a different thread (if we need to go fetch it). 397 // // 2. Come in via a different thread (if we need to go fetch it).
350// // 398 // //
351// // The code below handles both these alternatives. 399 // // The code below handles both these alternatives.
352// lock (this) 400 // lock (this)
353// { 401 // {
354// if (m_waitingForObjectAsset) 402 // if (m_waitingForObjectAsset)
355// { 403 // {
356// Monitor.Wait(this); 404 // Monitor.Wait(this);
357// m_waitingForObjectAsset = false; 405 // m_waitingForObjectAsset = false;
358// } 406 // }
359// } 407 // }
360// 408 //
361// return m_requestedObjectAsset; 409 // return m_requestedObjectAsset;
362 } 410 }
363 411
364 /// <summary> 412 /// <summary>
365 /// Record the asset uuids embedded within the given script. 413 /// Record the asset uuids embedded within the given text (e.g. a script).
366 /// </summary> 414 /// </summary>
367 /// <param name="scriptUuid"></param> 415 /// <param name="textAssetUuid"></param>
368 /// <param name="assetUuids">Dictionary in which to record the references</param> 416 /// <param name="assetUuids">Dictionary in which to record the references</param>
369 private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids) 417 private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids)
370 { 418 {
371// m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); 419 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
372 420
373 AssetBase embeddingAsset = GetAsset(embeddingAssetId); 421 AssetBase textAsset = GetAsset(textAssetUuid);
374 422
375 if (null != embeddingAsset) 423 if (null != textAsset)
376 { 424 GetTextEmbeddedAssetUuids(textAsset, assetUuids);
377 string script = Utils.BytesToString(embeddingAsset.Data); 425 }
378// m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
379 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
380// m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
381 426
382 foreach (Match uuidMatch in uuidMatches) 427 /// <summary>
383 { 428 /// Record the asset uuids embedded within the given text (e.g. a script).
384 UUID uuid = new UUID(uuidMatch.Value); 429 /// </summary>
385// m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); 430 /// <param name="textAsset"></param>
431 /// <param name="assetUuids">Dictionary in which to record the references</param>
432 private void GetTextEmbeddedAssetUuids(AssetBase textAsset, IDictionary<UUID, sbyte> assetUuids)
433 {
434 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
386 435
387 // Embedded asset references (if not false positives) could be for many types of asset, so we will 436 string script = Utils.BytesToString(textAsset.Data);
388 // label these as unknown. 437 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
389 assetUuids[uuid] = (sbyte)AssetType.Unknown; 438 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
390 } 439 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
440
441 foreach (Match uuidMatch in uuidMatches)
442 {
443 UUID uuid = new UUID(uuidMatch.Value);
444 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
445
446 // Embedded asset references (if not false positives) could be for many types of asset, so we will
447 // label these as unknown.
448 assetUuids[uuid] = (sbyte)AssetType.Unknown;
391 } 449 }
392 } 450 }
393 451
@@ -401,18 +459,26 @@ namespace OpenSim.Region.Framework.Scenes
401 AssetBase assetBase = GetAsset(wearableAssetUuid); 459 AssetBase assetBase = GetAsset(wearableAssetUuid);
402 460
403 if (null != assetBase) 461 if (null != assetBase)
462 GetWearableAssetUuids(assetBase, assetUuids);
463 }
464
465 /// <summary>
466 /// Record the uuids referenced by the given wearable asset
467 /// </summary>
468 /// <param name="assetBase"></param>
469 /// <param name="assetUuids">Dictionary in which to record the references</param>
470 private void GetWearableAssetUuids(AssetBase assetBase, IDictionary<UUID, sbyte> assetUuids)
471 {
472 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data));
473 AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data);
474 wearableAsset.Decode();
475
476 //m_log.DebugFormat(
477 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
478
479 foreach (UUID uuid in wearableAsset.Textures.Values)
404 { 480 {
405 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); 481 assetUuids[uuid] = (sbyte)AssetType.Texture;
406 AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data);
407 wearableAsset.Decode();
408
409 //m_log.DebugFormat(
410 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
411
412 foreach (UUID uuid in wearableAsset.Textures.Values)
413 {
414 assetUuids[uuid] = (sbyte)AssetType.Texture;
415 }
416 } 482 }
417 } 483 }
418 484
@@ -425,25 +491,35 @@ namespace OpenSim.Region.Framework.Scenes
425 /// <param name="assetUuids"></param> 491 /// <param name="assetUuids"></param>
426 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) 492 private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids)
427 { 493 {
428 AssetBase objectAsset = GetAsset(sceneObjectUuid); 494 AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid);
495
496 if (null != sceneObjectAsset)
497 GetSceneObjectAssetUuids(sceneObjectAsset, assetUuids);
498 }
499
500 /// <summary>
501 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
502 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
503 /// within this object).
504 /// </summary>
505 /// <param name="sceneObjectAsset"></param>
506 /// <param name="assetUuids"></param>
507 private void GetSceneObjectAssetUuids(AssetBase sceneObjectAsset, IDictionary<UUID, sbyte> assetUuids)
508 {
509 string xml = Utils.BytesToString(sceneObjectAsset.Data);
429 510
430 if (null != objectAsset) 511 CoalescedSceneObjects coa;
512 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
431 { 513 {
432 string xml = Utils.BytesToString(objectAsset.Data); 514 foreach (SceneObjectGroup sog in coa.Objects)
433 515 GatherAssetUuids(sog, assetUuids);
434 CoalescedSceneObjects coa; 516 }
435 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) 517 else
436 { 518 {
437 foreach (SceneObjectGroup sog in coa.Objects) 519 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
438 GatherAssetUuids(sog, assetUuids); 520
439 } 521 if (null != sog)
440 else 522 GatherAssetUuids(sog, assetUuids);
441 {
442 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
443
444 if (null != sog)
445 GatherAssetUuids(sog, assetUuids);
446 }
447 } 523 }
448 } 524 }
449 525
@@ -454,12 +530,22 @@ namespace OpenSim.Region.Framework.Scenes
454 /// <param name="assetUuids"></param> 530 /// <param name="assetUuids"></param>
455 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) 531 private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids)
456 { 532 {
457 AssetBase assetBase = GetAsset(gestureUuid); 533 AssetBase gestureAsset = GetAsset(gestureUuid);
458 if (null == assetBase) 534 if (null == gestureAsset)
459 return; 535 return;
460 536
461 using (MemoryStream ms = new MemoryStream(assetBase.Data)) 537 GetGestureAssetUuids(gestureAsset, assetUuids);
462 using (StreamReader sr = new StreamReader(ms)) 538 }
539
540 /// <summary>
541 /// Get the asset uuid associated with a gesture
542 /// </summary>
543 /// <param name="gestureAsset"></param>
544 /// <param name="assetUuids"></param>
545 private void GetGestureAssetUuids(AssetBase gestureAsset, IDictionary<UUID, sbyte> assetUuids)
546 {
547 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
548 using (StreamReader sr = new StreamReader(ms))
463 { 549 {
464 sr.ReadLine(); // Unknown (Version?) 550 sr.ReadLine(); // Unknown (Version?)
465 sr.ReadLine(); // Unknown 551 sr.ReadLine(); // Unknown
@@ -500,7 +586,15 @@ namespace OpenSim.Region.Framework.Scenes
500 if (null == assetBase) 586 if (null == assetBase)
501 return; 587 return;
502 588
503 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data); 589 GetMaterialAssetUuids(assetBase, assetUuids);
590 }
591
592 /// <summary>
593 /// Get the asset uuid's referenced in a material.
594 /// </summary>
595 private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids)
596 {
597 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
504 598
505 UUID normMap = mat["NormMap"].AsUUID(); 599 UUID normMap = mat["NormMap"].AsUUID();
506 if (normMap != UUID.Zero) 600 if (normMap != UUID.Zero)
@@ -536,7 +630,541 @@ namespace OpenSim.Region.Framework.Scenes
536 630
537 public AssetBase FetchAsset(UUID assetID) 631 public AssetBase FetchAsset(UUID assetID)
538 { 632 {
633 // Test if it's already here
634 AssetBase asset = m_assetService.Get(assetID.ToString());
635 if (asset == null)
636 {
637 // It's not, so fetch it from abroad
638 asset = m_assetService.Get(m_assetServerURL + assetID.ToString());
639 if (asset != null)
640 m_log.DebugFormat("[HGUUIDGatherer]: Copied asset {0} from {1} to local asset server", assetID, m_assetServerURL);
641 else
642 m_log.DebugFormat("[HGUUIDGatherer]: Failed to fetch asset {0} from {1}", assetID, m_assetServerURL);
643 }
644 //else
645 // m_log.DebugFormat("[HGUUIDGatherer]: Asset {0} from {1} was already here", assetID, m_assetServerURL);
646
647 return asset;
648 }
649 }
650
651 public class IteratingUuidGatherer
652 {
653 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
654
655 /// <summary>
656 /// Is gathering complete?
657 /// </summary>
658 public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } }
659
660 /// <summary>
661 /// Gets the next UUID to inspect.
662 /// </summary>
663 /// <value>If there is no next UUID then returns null</value>
664 public UUID? NextUuidToInspect
665 {
666 get
667 {
668 if (Complete)
669 return null;
670 else
671 return m_assetUuidsToInspect.Peek();
672 }
673 }
674
675 protected IAssetService m_assetService;
676
677 protected IDictionary<UUID, sbyte> m_gatheredAssetUuids;
678
679 protected Queue<UUID> m_assetUuidsToInspect;
680
681 public IteratingUuidGatherer(IAssetService assetService)
682 {
683 m_assetService = assetService;
684 m_gatheredAssetUuids = new Dictionary<UUID, sbyte>();
685
686 // FIXME: Not efficient for searching, can improve.
687 m_assetUuidsToInspect = new Queue<UUID>();
688 }
689
690 public IDictionary<UUID, sbyte> GetGatheredUuids()
691 {
692 return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids);
693 }
694
695 public bool AddAssetUuidToInspect(UUID uuid)
696 {
697 if (m_assetUuidsToInspect.Contains(uuid))
698 return false;
699
700 m_assetUuidsToInspect.Enqueue(uuid);
701
702 return true;
703 }
704
705 /// <summary>
706 /// Gathers the next set of assets returned by the next uuid to get from the asset service.
707 /// </summary>
708 /// <returns>false if gathering is already complete, true otherwise</returns>
709 public bool GatherNext()
710 {
711 if (Complete)
712 return false;
713
714 GetAssetUuids(m_assetUuidsToInspect.Dequeue());
715
716 return true;
717 }
718
719 /// <summary>
720 /// Gathers all remaining asset UUIDS no matter how many calls are required to the asset service.
721 /// </summary>
722 /// <returns>false if gathering is already complete, true otherwise</returns>
723 public bool GatherAll()
724 {
725 if (Complete)
726 return false;
727
728 while (GatherNext());
729
730 return true;
731 }
732
733 /// <summary>
734 /// Gather all the asset uuids associated with the asset referenced by a given uuid
735 /// </summary>
736 /// <remarks>
737 /// This includes both those directly associated with
738 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
739 /// within this object).
740 /// This method assumes that the asset type associated with this asset in persistent storage is correct (which
741 /// should always be the case). So with this method we always need to retrieve asset data even if the asset
742 /// is of a type which is known not to reference any other assets
743 /// </remarks>
744 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
745 private void GetAssetUuids(UUID assetUuid)
746 {
747 // avoid infinite loops
748 if (m_gatheredAssetUuids.ContainsKey(assetUuid))
749 return;
750
751 try
752 {
753 AssetBase assetBase = GetAsset(assetUuid);
754
755 if (null != assetBase)
756 {
757 sbyte assetType = assetBase.Type;
758 m_gatheredAssetUuids[assetUuid] = assetType;
759
760 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
761 {
762 RecordWearableAssetUuids(assetBase);
763 }
764 else if ((sbyte)AssetType.Gesture == assetType)
765 {
766 RecordGestureAssetUuids(assetBase);
767 }
768 else if ((sbyte)AssetType.Notecard == assetType)
769 {
770 RecordTextEmbeddedAssetUuids(assetBase);
771 }
772 else if ((sbyte)AssetType.LSLText == assetType)
773 {
774 RecordTextEmbeddedAssetUuids(assetBase);
775 }
776 else if ((sbyte)OpenSimAssetType.Material == assetType)
777 {
778 RecordMaterialAssetUuids(assetBase);
779 }
780 else if ((sbyte)AssetType.Object == assetType)
781 {
782 RecordSceneObjectAssetUuids(assetBase);
783 }
784 }
785 }
786 catch (Exception)
787 {
788 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid);
789 throw;
790 }
791 }
792
793 private void RecordAssetUuids(UUID assetUuid, sbyte assetType)
794 {
795 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
796 try
797 {
798 m_gatheredAssetUuids[assetUuid] = assetType;
799
800 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
801 {
802 AddAssetUuidToInspect(assetUuid);
803 }
804 else if ((sbyte)AssetType.Gesture == assetType)
805 {
806 AddAssetUuidToInspect(assetUuid);
807 }
808 else if ((sbyte)AssetType.Notecard == assetType)
809 {
810 AddAssetUuidToInspect(assetUuid);
811 }
812 else if ((sbyte)AssetType.LSLText == assetType)
813 {
814 AddAssetUuidToInspect(assetUuid);
815 }
816 else if ((sbyte)OpenSimAssetType.Material == assetType)
817 {
818 AddAssetUuidToInspect(assetUuid);
819 }
820 else if ((sbyte)AssetType.Object == assetType)
821 {
822 AddAssetUuidToInspect(assetUuid);
823 }
824 }
825 catch (Exception)
826 {
827 m_log.ErrorFormat(
828 "[ITERATABLE UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
829 assetUuid, assetType);
830 throw;
831 }
832 }
833
834 /// <summary>
835 /// Gather all the asset uuids associated with a given object.
836 /// </summary>
837 /// <remarks>
838 /// This includes both those directly associated with
839 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
840 /// within this object).
841 /// </remarks>
842 /// <param name="sceneObject">The scene object for which to gather assets</param>
843 public void RecordAssetUuids(SceneObjectGroup sceneObject)
844 {
845 // m_log.DebugFormat(
846 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
539 847
848 SceneObjectPart[] parts = sceneObject.Parts;
849 for (int i = 0; i < parts.Length; i++)
850 {
851 SceneObjectPart part = parts[i];
852
853 // m_log.DebugFormat(
854 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
855
856 try
857 {
858 Primitive.TextureEntry textureEntry = part.Shape.Textures;
859 if (textureEntry != null)
860 {
861 // Get the prim's default texture. This will be used for faces which don't have their own texture
862 if (textureEntry.DefaultTexture != null)
863 RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
864
865 if (textureEntry.FaceTextures != null)
866 {
867 // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
868 foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
869 {
870 if (texture != null)
871 RecordTextureEntryAssetUuids(texture);
872 }
873 }
874 }
875
876 // If the prim is a sculpt then preserve this information too
877 if (part.Shape.SculptTexture != UUID.Zero)
878 m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
879
880 if (part.Shape.ProjectionTextureUUID != UUID.Zero)
881 m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
882
883 if (part.CollisionSound != UUID.Zero)
884 m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
885
886 if (part.ParticleSystem.Length > 0)
887 {
888 try
889 {
890 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
891 if (ps.Texture != UUID.Zero)
892 m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
893 }
894 catch (Exception)
895 {
896 m_log.WarnFormat(
897 "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
898 part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
899 }
900 }
901
902 TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
903
904 // Now analyze this prim's inventory items to preserve all the uuids that they reference
905 foreach (TaskInventoryItem tii in taskDictionary.Values)
906 {
907 // m_log.DebugFormat(
908 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
909 // tii.Name, tii.Type, part.Name, part.UUID);
910
911 if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
912 RecordAssetUuids(tii.AssetID, (sbyte)tii.Type);
913 }
914
915 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
916 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
917 // inventory transfer. There needs to be a way for a module to register a method without assuming a
918 // Scene.EventManager is present.
919 // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
920
921
922 // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
923 RecordMaterialsUuids(part);
924 }
925 catch (Exception e)
926 {
927 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
928 m_log.DebugFormat(
929 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
930 part.Shape.TextureEntry.Length);
931 }
932 }
933 }
934
935 /// <summary>
936 /// Collect all the asset uuids found in one face of a Texture Entry.
937 /// </summary>
938 private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture)
939 {
940 m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
941
942 if (texture.MaterialID != UUID.Zero)
943 AddAssetUuidToInspect(texture.MaterialID);
944 }
945
946 /// <summary>
947 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
948 /// stored in legacy format in part.DynAttrs
949 /// </summary>
950 /// <param name="part"></param>
951 public void RecordMaterialsUuids(SceneObjectPart part)
952 {
953 // scan thru the dynAttrs map of this part for any textures used as materials
954 OSD osdMaterials = null;
955
956 lock (part.DynAttrs)
957 {
958 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
959 {
960 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
961
962 if (materialsStore == null)
963 return;
964
965 materialsStore.TryGetValue("Materials", out osdMaterials);
966 }
967
968 if (osdMaterials != null)
969 {
970 //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
971
972 if (osdMaterials is OSDArray)
973 {
974 OSDArray matsArr = osdMaterials as OSDArray;
975 foreach (OSDMap matMap in matsArr)
976 {
977 try
978 {
979 if (matMap.ContainsKey("Material"))
980 {
981 OSDMap mat = matMap["Material"] as OSDMap;
982 if (mat.ContainsKey("NormMap"))
983 {
984 UUID normalMapId = mat["NormMap"].AsUUID();
985 if (normalMapId != UUID.Zero)
986 {
987 m_gatheredAssetUuids[normalMapId] = (sbyte)AssetType.Texture;
988 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
989 }
990 }
991 if (mat.ContainsKey("SpecMap"))
992 {
993 UUID specularMapId = mat["SpecMap"].AsUUID();
994 if (specularMapId != UUID.Zero)
995 {
996 m_gatheredAssetUuids[specularMapId] = (sbyte)AssetType.Texture;
997 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
998 }
999 }
1000 }
1001
1002 }
1003 catch (Exception e)
1004 {
1005 m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message);
1006 }
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013 /// <summary>
1014 /// Get an asset synchronously, potentially using an asynchronous callback. If the
1015 /// asynchronous callback is used, we will wait for it to complete.
1016 /// </summary>
1017 /// <param name="uuid"></param>
1018 /// <returns></returns>
1019 protected virtual AssetBase GetAsset(UUID uuid)
1020 {
1021 return m_assetService.Get(uuid.ToString());
1022 }
1023
1024 /// <summary>
1025 /// Record the asset uuids embedded within the given text (e.g. a script).
1026 /// </summary>
1027 /// <param name="textAsset"></param>
1028 private void RecordTextEmbeddedAssetUuids(AssetBase textAsset)
1029 {
1030 // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId);
1031
1032 string script = Utils.BytesToString(textAsset.Data);
1033 // m_log.DebugFormat("[ARCHIVER]: Script {0}", script);
1034 MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script);
1035 // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count);
1036
1037 foreach (Match uuidMatch in uuidMatches)
1038 {
1039 UUID uuid = new UUID(uuidMatch.Value);
1040 // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
1041
1042 AddAssetUuidToInspect(uuid);
1043 }
1044 }
1045
1046 /// <summary>
1047 /// Record the uuids referenced by the given wearable asset
1048 /// </summary>
1049 /// <param name="assetBase"></param>
1050 private void RecordWearableAssetUuids(AssetBase assetBase)
1051 {
1052 //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data));
1053 AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data);
1054 wearableAsset.Decode();
1055
1056 //m_log.DebugFormat(
1057 // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count);
1058
1059 foreach (UUID uuid in wearableAsset.Textures.Values)
1060 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Texture;
1061 }
1062
1063 /// <summary>
1064 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
1065 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
1066 /// within this object).
1067 /// </summary>
1068 /// <param name="sceneObjectAsset"></param>
1069 private void RecordSceneObjectAssetUuids(AssetBase sceneObjectAsset)
1070 {
1071 string xml = Utils.BytesToString(sceneObjectAsset.Data);
1072
1073 CoalescedSceneObjects coa;
1074 if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
1075 {
1076 foreach (SceneObjectGroup sog in coa.Objects)
1077 RecordAssetUuids(sog);
1078 }
1079 else
1080 {
1081 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
1082
1083 if (null != sog)
1084 RecordAssetUuids(sog);
1085 }
1086 }
1087
1088 /// <summary>
1089 /// Get the asset uuid associated with a gesture
1090 /// </summary>
1091 /// <param name="gestureAsset"></param>
1092 private void RecordGestureAssetUuids(AssetBase gestureAsset)
1093 {
1094 using (MemoryStream ms = new MemoryStream(gestureAsset.Data))
1095 using (StreamReader sr = new StreamReader(ms))
1096 {
1097 sr.ReadLine(); // Unknown (Version?)
1098 sr.ReadLine(); // Unknown
1099 sr.ReadLine(); // Unknown
1100 sr.ReadLine(); // Name
1101 sr.ReadLine(); // Comment ?
1102 int count = Convert.ToInt32(sr.ReadLine()); // Item count
1103
1104 for (int i = 0 ; i < count ; i++)
1105 {
1106 string type = sr.ReadLine();
1107 if (type == null)
1108 break;
1109 string name = sr.ReadLine();
1110 if (name == null)
1111 break;
1112 string id = sr.ReadLine();
1113 if (id == null)
1114 break;
1115 string unknown = sr.ReadLine();
1116 if (unknown == null)
1117 break;
1118
1119 // If it can be parsed as a UUID, it is an asset ID
1120 UUID uuid;
1121 if (UUID.TryParse(id, out uuid))
1122 m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important
1123 }
1124 }
1125 }
1126
1127 /// <summary>
1128 /// Get the asset uuid's referenced in a material.
1129 /// </summary>
1130 private void RecordMaterialAssetUuids(AssetBase materialAsset)
1131 {
1132 OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data);
1133
1134 UUID normMap = mat["NormMap"].AsUUID();
1135 if (normMap != UUID.Zero)
1136 m_gatheredAssetUuids[normMap] = (sbyte)AssetType.Texture;
1137
1138 UUID specMap = mat["SpecMap"].AsUUID();
1139 if (specMap != UUID.Zero)
1140 m_gatheredAssetUuids[specMap] = (sbyte)AssetType.Texture;
1141 }
1142 }
1143
1144 public class IteratingHGUuidGatherer : IteratingUuidGatherer
1145 {
1146 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1147
1148 protected string m_assetServerURL;
1149
1150 public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL)
1151 : base(assetService)
1152 {
1153 m_assetServerURL = assetServerURL;
1154 if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
1155 m_assetServerURL = m_assetServerURL + "/";
1156 }
1157
1158 protected override AssetBase GetAsset(UUID uuid)
1159 {
1160 if (string.Empty == m_assetServerURL)
1161 return base.GetAsset(uuid);
1162 else
1163 return FetchAsset(uuid);
1164 }
1165
1166 public AssetBase FetchAsset(UUID assetID)
1167 {
540 // Test if it's already here 1168 // Test if it's already here
541 AssetBase asset = m_assetService.Get(assetID.ToString()); 1169 AssetBase asset = m_assetService.Get(assetID.ToString());
542 if (asset == null) 1170 if (asset == null)
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index e1aaf18..6fe86b2 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
71 m_client = client; 71 m_client = client;
72 m_scene = scene; 72 m_scene = scene;
73 73
74 Watchdog.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); 74 WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true);
75 } 75 }
76 76
77 private void SendServerCommand(string command) 77 private void SendServerCommand(string command)
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
index 9d27386..a1682d2 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
58 58
59 m_listener.Start(50); 59 m_listener.Start(50);
60 60
61 Watchdog.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true); 61 WorkManager.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true);
62 m_baseScene = baseScene; 62 m_baseScene = baseScene;
63 } 63 }
64 64
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index 2ef3c4c..08d0fbf 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -487,9 +487,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
487 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); 487 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
488 488
489 report.AppendFormat( 489 report.AppendFormat(
490 "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n", 490 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
491 "Max", 491 "Max",
492 "Total", 492 "Target",
493 "Actual",
493 "Resend", 494 "Resend",
494 "Land", 495 "Land",
495 "Wind", 496 "Wind",
@@ -500,7 +501,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
500 501
501 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); 502 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
502 report.AppendFormat( 503 report.AppendFormat(
503 "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n", 504 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
505 "kb/s",
504 "kb/s", 506 "kb/s",
505 "kb/s", 507 "kb/s",
506 "kb/s", 508 "kb/s",
@@ -513,8 +515,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
513 515
514 report.AppendLine(); 516 report.AppendLine();
515 517
516 bool firstClient = true;
517
518 lock (m_scenes) 518 lock (m_scenes)
519 { 519 {
520 foreach (Scene scene in m_scenes.Values) 520 foreach (Scene scene in m_scenes.Values)
@@ -526,12 +526,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
526 { 526 {
527 LLClientView llClient = client as LLClientView; 527 LLClientView llClient = client as LLClientView;
528 528
529 if (firstClient)
530 {
531 report.AppendLine(GetServerThrottlesReport(llClient.UDPServer));
532 firstClient = false;
533 }
534
535 bool isChild = client.SceneAgent.IsChildAgent; 529 bool isChild = client.SceneAgent.IsChildAgent;
536 if (isChild && !showChildren) 530 if (isChild && !showChildren)
537 return; 531 return;
@@ -550,8 +544,11 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
550 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); 544 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
551 545
552 report.AppendFormat( 546 report.AppendFormat(
553 "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}", 547 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
554 (ci.maxThrottle * 8) / 1000, 548 ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-",
549 llUdpClient.FlowThrottle.AdaptiveEnabled
550 ? ((ci.targetThrottle * 8) / 1000).ToString()
551 : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(),
555 (ci.totalThrottle * 8) / 1000, 552 (ci.totalThrottle * 8) / 1000,
556 (ci.resendThrottle * 8) / 1000, 553 (ci.resendThrottle * 8) / 1000,
557 (ci.landThrottle * 8) / 1000, 554 (ci.landThrottle * 8) / 1000,
@@ -559,9 +556,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
559 (ci.cloudThrottle * 8) / 1000, 556 (ci.cloudThrottle * 8) / 1000,
560 (ci.taskThrottle * 8) / 1000, 557 (ci.taskThrottle * 8) / 1000,
561 (ci.textureThrottle * 8) / 1000, 558 (ci.textureThrottle * 8) / 1000,
562 (ci.assetThrottle * 8) / 1000); 559 (ci.assetThrottle * 8) / 1000);
563
564 report.AppendLine();
565 } 560 }
566 }); 561 });
567 } 562 }
@@ -569,37 +564,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
569 564
570 return report.ToString(); 565 return report.ToString();
571 } 566 }
572
573 protected string GetServerThrottlesReport(LLUDPServer udpServer)
574 {
575 StringBuilder report = new StringBuilder();
576
577 int columnPadding = 2;
578 int maxNameLength = 18;
579 int maxRegionNameLength = 14;
580 int maxTypeLength = 4;
581
582 string name = "SERVER AGENT RATES";
583
584 report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
585 report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding));
586 report.Append(GetColumnEntry("-", maxTypeLength, columnPadding));
587
588 ThrottleRates throttleRates = udpServer.ThrottleRates;
589 report.AppendFormat(
590 "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}",
591 "-",
592 (throttleRates.Total * 8) / 1000,
593 (throttleRates.Resend * 8) / 1000,
594 (throttleRates.Land * 8) / 1000,
595 (throttleRates.Wind * 8) / 1000,
596 (throttleRates.Cloud * 8) / 1000,
597 (throttleRates.Task * 8) / 1000,
598 (throttleRates.Texture * 8) / 1000,
599 (throttleRates.Asset * 8) / 1000);
600
601 return report.ToString();
602 }
603 567
604 /// <summary> 568 /// <summary>
605 /// Show client stats data 569 /// Show client stats data
@@ -641,7 +605,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
641 string.Format( 605 string.Format(
642 "{0} ({1:0.00}%)", 606 "{0} ({1:0.00}%)",
643 llClient.TotalAgentUpdates, 607 llClient.TotalAgentUpdates,
644 (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100)); 608 cinfo.SyncRequests.ContainsKey("AgentUpdate")
609 ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100
610 : 0));
645 } 611 }
646 }); 612 });
647 } 613 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index fa35f0f..f67f613 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
51 { 51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 54 private List<Scene> m_scenes = new List<Scene>();
55
55// private IAvatarFactoryModule m_avatarFactory; 56// private IAvatarFactoryModule m_avatarFactory;
56 57
57 public string Name { get { return "Appearance Information Module"; } } 58 public string Name { get { return "Appearance Information Module"; } }
@@ -83,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
83// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 84// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
84 85
85 lock (m_scenes) 86 lock (m_scenes)
86 m_scenes.Remove(scene.RegionInfo.RegionID); 87 m_scenes.Remove(scene);
87 } 88 }
88 89
89 public void RegionLoaded(Scene scene) 90 public void RegionLoaded(Scene scene)
@@ -91,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
91// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 92// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
92 93
93 lock (m_scenes) 94 lock (m_scenes)
94 m_scenes[scene.RegionInfo.RegionID] = scene; 95 m_scenes.Add(scene);
95 96
96 scene.AddCommand( 97 scene.AddCommand(
97 "Users", this, "show appearance", 98 "Users", this, "show appearance",
@@ -102,7 +103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
102 scene.AddCommand( 103 scene.AddCommand(
103 "Users", this, "appearance show", 104 "Users", this, "appearance show",
104 "appearance show [<first-name> <last-name>]", 105 "appearance show [<first-name> <last-name>]",
105 "Show appearance information for each avatar in the simulator.", 106 "Show appearance information for avatars.",
106 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " 107 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. "
107 + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." 108 + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud."
108 + "\nOptionally, you can view just a particular avatar's appearance information." 109 + "\nOptionally, you can view just a particular avatar's appearance information."
@@ -132,6 +133,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
132 "Find out which avatar uses the given asset as a baked texture, if any.", 133 "Find out which avatar uses the given asset as a baked texture, if any.",
133 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", 134 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",
134 HandleFindAppearanceCommand); 135 HandleFindAppearanceCommand);
136
137 scene.AddCommand(
138 "Users", this, "wearables show",
139 "wearables show [<first-name> <last-name>]",
140 "Show information about wearables for avatars.",
141 "If no avatar name is given then a general summary for all avatars in the scene is shown.\n"
142 + "If an avatar name is given then specific information about current wearables is shown.",
143 HandleShowWearablesCommand);
144
145 scene.AddCommand(
146 "Users", this, "wearables check",
147 "wearables check <first-name> <last-name>",
148 "Check that the wearables of a given avatar in the scene are valid.",
149 "This currently checks that the wearable assets themselves and any assets referenced by them exist.",
150 HandleCheckWearablesCommand);
135 } 151 }
136 152
137 private void HandleSendAppearanceCommand(string module, string[] cmd) 153 private void HandleSendAppearanceCommand(string module, string[] cmd)
@@ -155,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
155 171
156 lock (m_scenes) 172 lock (m_scenes)
157 { 173 {
158 foreach (Scene scene in m_scenes.Values) 174 foreach (Scene scene in m_scenes)
159 { 175 {
160 if (targetNameSupplied) 176 if (targetNameSupplied)
161 { 177 {
@@ -186,7 +202,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
186 } 202 }
187 } 203 }
188 204
189 protected void HandleShowAppearanceCommand(string module, string[] cmd) 205 private void HandleShowAppearanceCommand(string module, string[] cmd)
190 { 206 {
191 if (cmd.Length != 2 && cmd.Length < 4) 207 if (cmd.Length != 2 && cmd.Length < 4)
192 { 208 {
@@ -207,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
207 223
208 lock (m_scenes) 224 lock (m_scenes)
209 { 225 {
210 foreach (Scene scene in m_scenes.Values) 226 foreach (Scene scene in m_scenes)
211 { 227 {
212 if (targetNameSupplied) 228 if (targetNameSupplied)
213 { 229 {
@@ -243,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
243 259
244 lock (m_scenes) 260 lock (m_scenes)
245 { 261 {
246 foreach (Scene scene in m_scenes.Values) 262 foreach (Scene scene in m_scenes)
247 { 263 {
248 ScenePresence sp = scene.GetScenePresence(firstname, lastname); 264 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
249 if (sp != null && !sp.IsChildAgent) 265 if (sp != null && !sp.IsChildAgent)
@@ -263,7 +279,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
263 } 279 }
264 } 280 }
265 281
266 protected void HandleFindAppearanceCommand(string module, string[] cmd) 282 private void HandleFindAppearanceCommand(string module, string[] cmd)
267 { 283 {
268 if (cmd.Length != 3) 284 if (cmd.Length != 3)
269 { 285 {
@@ -277,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
277 293
278 lock (m_scenes) 294 lock (m_scenes)
279 { 295 {
280 foreach (Scene scene in m_scenes.Values) 296 foreach (Scene scene in m_scenes)
281 { 297 {
282 scene.ForEachRootScenePresence( 298 scene.ForEachRootScenePresence(
283 sp => 299 sp =>
@@ -304,5 +320,161 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
304 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray())); 320 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray()));
305 } 321 }
306 } 322 }
323
324 protected void HandleShowWearablesCommand(string module, string[] cmd)
325 {
326 if (cmd.Length != 2 && cmd.Length < 4)
327 {
328 MainConsole.Instance.OutputFormat("Usage: wearables show [<first-name> <last-name>]");
329 return;
330 }
331
332 bool targetNameSupplied = false;
333 string optionalTargetFirstName = null;
334 string optionalTargetLastName = null;
335
336 if (cmd.Length >= 4)
337 {
338 targetNameSupplied = true;
339 optionalTargetFirstName = cmd[2];
340 optionalTargetLastName = cmd[3];
341 }
342
343 StringBuilder sb = new StringBuilder();
344
345 if (targetNameSupplied)
346 {
347 lock (m_scenes)
348 {
349 foreach (Scene scene in m_scenes)
350 {
351 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
352 if (sp != null && !sp.IsChildAgent)
353 AppendWearablesDetailReport(sp, sb);
354 }
355 }
356 }
357 else
358 {
359 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
360 cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize);
361 cdt.AddColumn("Wearables", 2);
362
363 lock (m_scenes)
364 {
365 foreach (Scene scene in m_scenes)
366 {
367 scene.ForEachRootScenePresence(
368 sp =>
369 {
370 int count = 0;
371
372 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
373 count += sp.Appearance.Wearables[i].Count;
374
375 cdt.AddRow(sp.Name, count);
376 }
377 );
378 }
379 }
380
381 sb.Append(cdt.ToString());
382 }
383
384 MainConsole.Instance.Output(sb.ToString());
385 }
386
387 private void HandleCheckWearablesCommand(string module, string[] cmd)
388 {
389 if (cmd.Length != 4)
390 {
391 MainConsole.Instance.OutputFormat("Usage: wearables check <first-name> <last-name>");
392 return;
393 }
394
395 string firstname = cmd[2];
396 string lastname = cmd[3];
397
398 StringBuilder sb = new StringBuilder();
399 UuidGatherer uuidGatherer = new UuidGatherer(m_scenes[0].AssetService);
400
401 lock (m_scenes)
402 {
403 foreach (Scene scene in m_scenes)
404 {
405 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
406 if (sp != null && !sp.IsChildAgent)
407 {
408 sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name);
409
410 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
411 {
412 AvatarWearable aw = sp.Appearance.Wearables[i];
413
414 if (aw.Count > 0)
415 {
416 sb.Append(Enum.GetName(typeof(WearableType), i));
417 sb.Append("\n");
418
419 for (int j = 0; j < aw.Count; j++)
420 {
421 WearableItem wi = aw[j];
422
423 ConsoleDisplayList cdl = new ConsoleDisplayList();
424 cdl.Indent = 2;
425 cdl.AddRow("Item UUID", wi.ItemID);
426 cdl.AddRow("Assets", "");
427 sb.Append(cdl.ToString());
428
429 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>();
430 uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids);
431 string[] assetStrings
432 = Array.ConvertAll<UUID, string>(assetUuids.Keys.ToArray(), u => u.ToString());
433
434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings);
435
436 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
437 cdt.Indent = 4;
438 cdt.AddColumn("Type", 10);
439 cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize);
440 cdt.AddColumn("Found", 5);
441
442 for (int k = 0; k < existChecks.Length; k++)
443 cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no");
444
445 sb.Append(cdt.ToString());
446 sb.Append("\n");
447 }
448 }
449 }
450 }
451 }
452 }
453
454 MainConsole.Instance.Output(sb.ToString());
455 }
456
457 private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb)
458 {
459 sb.AppendFormat("\nWearables for {0}\n", sp.Name);
460
461 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
462 cdt.AddColumn("Type", 10);
463 cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize);
464 cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize);
465
466 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
467 {
468 AvatarWearable aw = sp.Appearance.Wearables[i];
469
470 for (int j = 0; j < aw.Count; j++)
471 {
472 WearableItem wi = aw[j];
473 cdt.AddRow(Enum.GetName(typeof(WearableType), i), wi.ItemID, wi.AssetID);
474 }
475 }
476
477 sb.Append(cdt.ToString());
478 }
307 } 479 }
308} \ No newline at end of file 480} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
index bdd07e0..6985371 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -359,7 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
359 359
360 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 360 m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port);
361 361
362 Watchdog.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); 362 WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false);
363 363
364 // This is the message order recommended by RFC 2812 364 // This is the message order recommended by RFC 2812
365 if (m_password != null) 365 if (m_password != null)
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index d944087..e03e71d 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -46,7 +46,6 @@ using OpenSim.Region.CoreModules.Framework;
46using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 47using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
48using OpenSim.Tests.Common; 48using OpenSim.Tests.Common;
49using OpenSim.Tests.Common.Mock;
50 49
51namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests 50namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
52{ 51{
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index a6c12fd..b69676b 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -323,7 +323,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
323 public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param) 323 public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param)
324 { 324 {
325 UUID reqID = UUID.Random(); 325 UUID reqID = UUID.Random();
326 Util.FireAndForget(o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param)); 326 Util.FireAndForget(
327 o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param), null, "JsonStoreScriptModule.DoJsonRezObject");
327 return reqID; 328 return reqID;
328 } 329 }
329 330
@@ -336,7 +337,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
336 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) 337 public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier)
337 { 338 {
338 UUID reqID = UUID.Random(); 339 UUID reqID = UUID.Random();
339 Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier)); 340 Util.FireAndForget(
341 o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard");
340 return reqID; 342 return reqID;
341 } 343 }
342 344
@@ -349,7 +351,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
349 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) 351 public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
350 { 352 {
351 UUID reqID = UUID.Random(); 353 UUID reqID = UUID.Random();
352 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); 354 Util.FireAndForget(
355 o => DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name), null, "JsonStoreScriptModule.DoJsonWriteNotecard");
353 return reqID; 356 return reqID;
354 } 357 }
355 358
@@ -464,7 +467,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
464 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) 467 public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
465 { 468 {
466 UUID reqID = UUID.Random(); 469 UUID reqID = UUID.Random();
467 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); 470 Util.FireAndForget(
471 o => DoJsonTakeValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonTakeValue");
468 return reqID; 472 return reqID;
469 } 473 }
470 474
@@ -472,7 +476,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
472 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 476 public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
473 { 477 {
474 UUID reqID = UUID.Random(); 478 UUID reqID = UUID.Random();
475 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); 479 Util.FireAndForget(
480 o => DoJsonTakeValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonTakeValueJson");
476 return reqID; 481 return reqID;
477 } 482 }
478 483
@@ -485,7 +490,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
485 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) 490 public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
486 { 491 {
487 UUID reqID = UUID.Random(); 492 UUID reqID = UUID.Random();
488 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); 493 Util.FireAndForget(
494 o => DoJsonReadValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonReadValue");
489 return reqID; 495 return reqID;
490 } 496 }
491 497
@@ -493,7 +499,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
493 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) 499 public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
494 { 500 {
495 UUID reqID = UUID.Random(); 501 UUID reqID = UUID.Random();
496 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); 502 Util.FireAndForget(
503 o => DoJsonReadValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonReadValueJson");
497 return reqID; 504 return reqID;
498 } 505 }
499 506
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index 21e2758..99a7076 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api; 40using OpenSim.Region.ScriptEngine.Shared.Api;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests 44namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
46{ 45{
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
index 6e0a80a..d37369c 100644
--- a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
@@ -294,7 +294,8 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport
294 for (int i = 0 ; i < selection.Count ; i++) 294 for (int i = 0 ; i < selection.Count ; i++)
295 sel.Add(selection[i].AsUInteger()); 295 sel.Add(selection[i].AsUInteger());
296 296
297 Util.FireAndForget(x => { m_module.HandleMenuSelection(action, m_agentID, sel); }); 297 Util.FireAndForget(
298 x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection");
298 299
299 Encoding encoding = Encoding.UTF8; 300 Encoding encoding = Encoding.UTF8;
300 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); 301 return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD()));
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index e82351e..0bebb58 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.AvatarService; 44using OpenSim.Services.AvatarService;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Region.OptionalModules.World.NPC.Tests 47namespace OpenSim.Region.OptionalModules.World.NPC.Tests
49{ 48{
@@ -300,7 +299,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
300 public void TestMove() 299 public void TestMove()
301 { 300 {
302 TestHelpers.InMethod(); 301 TestHelpers.InMethod();
303// log4net.Config.XmlConfigurator.Configure(); 302// TestHelpers.EnableLogging();
304 303
305 SetUpScene(); 304 SetUpScene();
306 305
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index a303972..4c54f9f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -174,15 +174,19 @@ public sealed class BSCharacter : BSPhysObject
174 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); 174 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
175 175
176 // Do this after the object has been added to the world 176 // Do this after the object has been added to the world
177 PhysBody.collisionType = CollisionType.Avatar; 177 if (BSParam.AvatarToAvatarCollisionsByDefault)
178 PhysBody.collisionType = CollisionType.Avatar;
179 else
180 PhysBody.collisionType = CollisionType.PhantomToOthersAvatar;
181
178 PhysBody.ApplyCollisionMask(PhysScene); 182 PhysBody.ApplyCollisionMask(PhysScene);
179 } 183 }
180 184
181
182 public override void RequestPhysicsterseUpdate() 185 public override void RequestPhysicsterseUpdate()
183 { 186 {
184 base.RequestPhysicsterseUpdate(); 187 base.RequestPhysicsterseUpdate();
185 } 188 }
189
186 // No one calls this method so I don't know what it could possibly mean 190 // No one calls this method so I don't know what it could possibly mean
187 public override bool Stopped { get { return false; } } 191 public override bool Stopped { get { return false; } }
188 192
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 867d6ff..e7f4def 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -132,6 +132,7 @@ public static class BSParam
132 public static float PhysicsUnmanLoggingFrames { get; private set; } 132 public static float PhysicsUnmanLoggingFrames { get; private set; }
133 133
134 // Avatar parameters 134 // Avatar parameters
135 public static bool AvatarToAvatarCollisionsByDefault { get; private set; }
135 public static float AvatarFriction { get; private set; } 136 public static float AvatarFriction { get; private set; }
136 public static float AvatarStandingFriction { get; private set; } 137 public static float AvatarStandingFriction { get; private set; }
137 public static float AvatarAlwaysRunFactor { get; private set; } 138 public static float AvatarAlwaysRunFactor { get; private set; }
@@ -571,6 +572,8 @@ public static class BSParam
571 new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" , 572 new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" ,
572 0.04f ), 573 0.04f ),
573 574
575 new ParameterDefn<bool>("AvatarToAvatarCollisionsByDefault", "Should avatars collide with other avatars by default?",
576 true),
574 new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 577 new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
575 0.2f ), 578 0.2f ),
576 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 579 new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index a46c241..0f79a10 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -130,6 +130,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
130 internal int m_maxUpdatesPerFrame; 130 internal int m_maxUpdatesPerFrame;
131 internal EntityProperties[] m_updateArray; 131 internal EntityProperties[] m_updateArray;
132 132
133 /// <summary>
134 /// Used to control physics simulation timing if Bullet is running on its own thread.
135 /// </summary>
136 private ManualResetEvent m_updateWaitEvent;
137
133 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 138 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
134 public const uint GROUNDPLANE_ID = 1; 139 public const uint GROUNDPLANE_ID = 1;
135 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here 140 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
@@ -288,7 +293,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
288 { 293 {
289 // The physics simulation should happen independently of the heartbeat loop 294 // The physics simulation should happen independently of the heartbeat loop
290 m_physicsThread 295 m_physicsThread
291 = Watchdog.StartThread( 296 = WorkManager.StartThread(
292 BulletSPluginPhysicsThread, 297 BulletSPluginPhysicsThread,
293 string.Format("{0} ({1})", BulletEngineName, RegionName), 298 string.Format("{0} ({1})", BulletEngineName, RegionName),
294 ThreadPriority.Normal, 299 ThreadPriority.Normal,
@@ -838,6 +843,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
838 843
839 public void BulletSPluginPhysicsThread() 844 public void BulletSPluginPhysicsThread()
840 { 845 {
846 Thread.CurrentThread.Priority = ThreadPriority.Highest;
847 m_updateWaitEvent = new ManualResetEvent(false);
848
841 while (m_initialized) 849 while (m_initialized)
842 { 850 {
843 int beginSimulationRealtimeMS = Util.EnvironmentTickCount(); 851 int beginSimulationRealtimeMS = Util.EnvironmentTickCount();
@@ -851,8 +859,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
851 if (simulationTimeVsRealtimeDifferenceMS > 0) 859 if (simulationTimeVsRealtimeDifferenceMS > 0)
852 { 860 {
853 // The simulation of the time interval took less than realtime. 861 // The simulation of the time interval took less than realtime.
854 // Do a sleep for the rest of realtime. 862 // Do a wait for the rest of realtime.
855 Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); 863 m_updateWaitEvent.WaitOne(simulationTimeVsRealtimeDifferenceMS);
864 //Thread.Sleep(simulationTimeVsRealtimeDifferenceMS);
856 } 865 }
857 else 866 else
858 { 867 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
index 3425d9e..5932461 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs
@@ -190,6 +190,7 @@ public class BulletHMapInfo
190public enum CollisionType 190public enum CollisionType
191{ 191{
192 Avatar, 192 Avatar,
193 PhantomToOthersAvatar, // An avatar that it phantom to other avatars but not to anything else
193 Groundplane, 194 Groundplane,
194 Terrain, 195 Terrain,
195 Static, 196 Static,
@@ -231,7 +232,12 @@ public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeM
231 { CollisionType.Avatar, 232 { CollisionType.Avatar,
232 new CollisionTypeFilterGroup(CollisionType.Avatar, 233 new CollisionTypeFilterGroup(CollisionType.Avatar,
233 (uint)CollisionFilterGroups.BCharacterGroup, 234 (uint)CollisionFilterGroups.BCharacterGroup,
234 (uint)CollisionFilterGroups.BAllGroup) 235 (uint)(CollisionFilterGroups.BAllGroup))
236 },
237 { CollisionType.PhantomToOthersAvatar,
238 new CollisionTypeFilterGroup(CollisionType.PhantomToOthersAvatar,
239 (uint)CollisionFilterGroups.BCharacterGroup,
240 (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BCharacterGroup))
235 }, 241 },
236 { CollisionType.Groundplane, 242 { CollisionType.Groundplane,
237 new CollisionTypeFilterGroup(CollisionType.Groundplane, 243 new CollisionTypeFilterGroup(CollisionType.Groundplane,
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index e347fdc..f5a25d6 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -3343,7 +3343,7 @@ Console.WriteLine(" JointCreateFixed");
3343 RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod; 3343 RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod;
3344 if (assetProvider != null) 3344 if (assetProvider != null)
3345 assetProvider(_pbs.SculptTexture, MeshAssetReceived); 3345 assetProvider(_pbs.SculptTexture, MeshAssetReceived);
3346 }); 3346 }, null, "ODEPrim.CheckMeshAsset");
3347 } 3347 }
3348 } 3348 }
3349 3349
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 40a05cf..036cb5d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -182,7 +182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
182 { 182 {
183 // Start the thread that will be doing the work 183 // Start the thread that will be doing the work
184 cmdHandlerThread 184 cmdHandlerThread
185 = Watchdog.StartThread( 185 = WorkManager.StartThread(
186 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); 186 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true);
187 } 187 }
188 } 188 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index e7ba7a4..97e3eeb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2979,7 +2979,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2979 2979
2980 money.ObjectGiveMoney( 2980 money.ObjectGiveMoney(
2981 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 2981 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
2982 }); 2982 }, null, "LSL_Api.llGiveMoney");
2983 } 2983 }
2984 2984
2985 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2985 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -3075,7 +3075,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3075 } 3075 }
3076 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3076 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3077 } 3077 }
3078 }); 3078 }, null, "LSL_Api.llRezAtRoot");
3079 3079
3080 //ScriptSleep((int)((groupmass * velmag) / 10)); 3080 //ScriptSleep((int)((groupmass * velmag) / 10));
3081 ScriptSleep(100); 3081 ScriptSleep(100);
@@ -3270,7 +3270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3270 /// </remarks> 3270 /// </remarks>
3271 public void DetachFromAvatar() 3271 public void DetachFromAvatar()
3272 { 3272 {
3273 Util.FireAndForget(DetachWrapper, m_host); 3273 Util.FireAndForget(DetachWrapper, m_host, "LSL_Api.DetachFromAvatar");
3274 } 3274 }
3275 3275
3276 private void DetachWrapper(object o) 3276 private void DetachWrapper(object o)
@@ -12421,7 +12421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12421 new LSL_String(replydata) }, 12421 new LSL_String(replydata) },
12422 new DetectParams[0])); 12422 new DetectParams[0]));
12423 } 12423 }
12424 }); 12424 }, null, "LSL_Api.llTransferLindenDollars");
12425 12425
12426 return txn.ToString(); 12426 return txn.ToString();
12427 } 12427 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 704ff15..10ddf14 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -790,9 +790,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
790 790
791 // We will launch the teleport on a new thread so that when the script threads are terminated 791 // We will launch the teleport on a new thread so that when the script threads are terminated
792 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 792 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
793 Util.FireAndForget(o => World.RequestTeleportLocation( 793 Util.FireAndForget(
794 presence.ControllingClient, regionName, position, 794 o => World.RequestTeleportLocation(
795 lookat, (uint)TPFlags.ViaLocation)); 795 presence.ControllingClient, regionName, position,
796 lookat, (uint)TPFlags.ViaLocation),
797 null, "OSSL_Api.TeleportAgentByRegionCoords");
796 798
797 ScriptSleep(5000); 799 ScriptSleep(5000);
798 800
@@ -836,9 +838,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
836 838
837 // We will launch the teleport on a new thread so that when the script threads are terminated 839 // We will launch the teleport on a new thread so that when the script threads are terminated
838 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 840 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
839 Util.FireAndForget(o => World.RequestTeleportLocation( 841 Util.FireAndForget(
840 presence.ControllingClient, regionHandle, 842 o => World.RequestTeleportLocation(
841 position, lookat, (uint)TPFlags.ViaLocation)); 843 presence.ControllingClient, regionHandle,
844 position, lookat, (uint)TPFlags.ViaLocation),
845 null, "OSSL_Api.TeleportAgentByRegionName");
842 846
843 ScriptSleep(5000); 847 ScriptSleep(5000);
844 848
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
index ac822c6..1fff6ba 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.ScriptEngine.XEngine; 38using OpenSim.Region.ScriptEngine.XEngine;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests 41namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
43{ 42{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs
index 1415925..8170e9b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51 50
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
index ab44e38..14e45ff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.ScriptEngine.Shared.Tests 49namespace OpenSim.Region.ScriptEngine.Shared.Tests
51{ 50{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
index 1ad0a99..9fd8532 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance; 44using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48using PermissionMask = OpenSim.Framework.PermissionMask; 47using PermissionMask = OpenSim.Framework.PermissionMask;
49 48
50namespace OpenSim.Region.ScriptEngine.Shared.Tests 49namespace OpenSim.Region.ScriptEngine.Shared.Tests
@@ -248,15 +247,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
248 UUID user1Id = TestHelpers.ParseTail(0x1); 247 UUID user1Id = TestHelpers.ParseTail(0x1);
249 UUID user2Id = TestHelpers.ParseTail(0x2); 248 UUID user2Id = TestHelpers.ParseTail(0x2);
250 249
251 SceneObjectGroup sourceSo = SceneHelpers.AddSceneObject(m_scene, 1, user1Id, "sourceSo", 0x10); 250 SceneObjectGroup sourceSo = SceneHelpers.AddSceneObject(m_scene, "sourceSo", user1Id);
252 m_scene.AddSceneObject(sourceSo); 251 m_scene.AddSceneObject(sourceSo);
253 LSL_Api api = new LSL_Api(); 252 LSL_Api api = new LSL_Api();
254 api.Initialize(m_engine, sourceSo.RootPart, null, null); 253 api.Initialize(m_engine, sourceSo.RootPart, null, null);
255 TaskInventoryHelpers.AddScript(m_scene, sourceSo.RootPart, "script", "Hello World"); 254 TaskInventoryHelpers.AddScript(m_scene, sourceSo.RootPart, "script", "Hello World");
256 255
257 SceneObjectGroup targetSo = SceneHelpers.AddSceneObject(m_scene, 1, user1Id, "targetSo", 0x20); 256 SceneObjectGroup targetSo = SceneHelpers.AddSceneObject(m_scene, "targetSo", user1Id);
258 SceneObjectGroup otherOwnedTargetSo 257 SceneObjectGroup otherOwnedTargetSo = SceneHelpers.AddSceneObject(m_scene, "otherOwnedTargetSo", user2Id);
259 = SceneHelpers.AddSceneObject(m_scene, 1, user2Id, "otherOwnedTargetSo", 0x30);
260 258
261 // Test that we cannot load a script when the target pin has never been set (i.e. it is zero) 259 // Test that we cannot load a script when the target pin has never been set (i.e. it is zero)
262 api.llRemoteLoadScriptPin(targetSo.UUID.ToString(), "script", 0, 0, 0); 260 api.llRemoteLoadScriptPin(targetSo.UUID.ToString(), "script", 0, 0, 0);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
index 4c5a501..f347869 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Region.ScriptEngine.Shared.Tests 49namespace OpenSim.Region.ScriptEngine.Shared.Tests
51{ 50{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
index 60de5cb..0b1ae60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
@@ -37,7 +37,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
37using OpenSim.Region.ScriptEngine.Shared.Instance; 37using OpenSim.Region.ScriptEngine.Shared.Instance;
38using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 38using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
39using OpenMetaverse; 39using OpenMetaverse;
40using OpenSim.Tests.Common.Mock;
41 40
42using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 41using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
43using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 42using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs
index 42d1b3b..b9028ab 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs
@@ -18,7 +18,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
18using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 18using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
19using OpenSim.Services.Interfaces; 19using OpenSim.Services.Interfaces;
20using OpenSim.Tests.Common; 20using OpenSim.Tests.Common;
21using OpenSim.Tests.Common.Mock;
22 21
23namespace OpenSim.Region.ScriptEngine.Shared.Tests 22namespace OpenSim.Region.ScriptEngine.Shared.Tests
24{ 23{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs
index ed61dc0..d7651e3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 45using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
46using OpenSim.Services.Interfaces; 46using OpenSim.Services.Interfaces;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51 50
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 7e3726a..1b7aa63 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -37,7 +37,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
37using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 37using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
38using OpenMetaverse; 38using OpenMetaverse;
39using System; 39using System;
40using OpenSim.Tests.Common.Mock;
41 40
42namespace OpenSim.Region.ScriptEngine.Shared.Tests 41namespace OpenSim.Region.ScriptEngine.Shared.Tests
43{ 42{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index c88bad5..4c31969 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance; 44using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48 47
49namespace OpenSim.Region.ScriptEngine.Shared.Tests 48namespace OpenSim.Region.ScriptEngine.Shared.Tests
50{ 49{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
index e422f5b..caba4a4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.Instance; 44using OpenSim.Region.ScriptEngine.Shared.Instance;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48 47
49namespace OpenSim.Region.ScriptEngine.Shared.Tests 48namespace OpenSim.Region.ScriptEngine.Shared.Tests
50{ 49{
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 495e684..398ccbe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -46,7 +46,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
46using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 46using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
47using OpenSim.Services.Interfaces; 47using OpenSim.Services.Interfaces;
48using OpenSim.Tests.Common; 48using OpenSim.Tests.Common;
49using OpenSim.Tests.Common.Mock;
50 49
51namespace OpenSim.Region.ScriptEngine.Shared.Tests 50namespace OpenSim.Region.ScriptEngine.Shared.Tests
52{ 51{
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
index bafcdd8..fe15157 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs
@@ -36,7 +36,6 @@ using OpenSim.Region.CoreModules.Scripting.WorldComm;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40 39
41namespace OpenSim.Region.ScriptEngine.XEngine.Tests 40namespace OpenSim.Region.ScriptEngine.XEngine.Tests
42{ 41{
diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs
index 954783c..44ef124 100644
--- a/OpenSim/Server/Base/HttpServerBase.cs
+++ b/OpenSim/Server/Base/HttpServerBase.cs
@@ -56,15 +56,16 @@ namespace OpenSim.Server.Base
56 56
57 if (networkConfig == null) 57 if (networkConfig == null)
58 { 58 {
59 System.Console.WriteLine("Section 'Network' not found, server can't start"); 59 System.Console.WriteLine("ERROR: Section [Network] not found, server can't start");
60 Thread.CurrentThread.Abort(); 60 Environment.Exit(1);
61 } 61 }
62 62
63 uint port = (uint)networkConfig.GetInt("port", 0); 63 uint port = (uint)networkConfig.GetInt("port", 0);
64 64
65 if (port == 0) 65 if (port == 0)
66 { 66 {
67 Thread.CurrentThread.Abort(); 67 System.Console.WriteLine("ERROR: No 'port' entry found in [Network]. Server can't start");
68 Environment.Exit(1);
68 } 69 }
69 70
70 bool ssl_main = networkConfig.GetBoolean("https_main",false); 71 bool ssl_main = networkConfig.GetBoolean("https_main",false);
@@ -83,23 +84,24 @@ namespace OpenSim.Server.Base
83 // Then, check for https settings and ADD a server to 84 // Then, check for https settings and ADD a server to
84 // m_Servers 85 // m_Servers
85 // 86 //
86 if ( !ssl_main ) 87 if (!ssl_main)
87 { 88 {
88 httpServer = new BaseHttpServer(port); 89 httpServer = new BaseHttpServer(port);
89 } 90 }
90 else 91 else
91 { 92 {
92 string cert_path = networkConfig.GetString("cert_path",String.Empty); 93 string cert_path = networkConfig.GetString("cert_path",String.Empty);
93 if ( cert_path == String.Empty ) 94 if (cert_path == String.Empty)
94 { 95 {
95 System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); 96 System.Console.WriteLine("ERROR: Path to X509 certificate is missing, server can't start.");
96 Thread.CurrentThread.Abort(); 97 Environment.Exit(1);
97 } 98 }
99
98 string cert_pass = networkConfig.GetString("cert_pass",String.Empty); 100 string cert_pass = networkConfig.GetString("cert_pass",String.Empty);
99 if ( cert_pass == String.Empty ) 101 if (cert_pass == String.Empty)
100 { 102 {
101 System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); 103 System.Console.WriteLine("ERROR: Password for X509 certificate is missing, server can't start.");
102 Thread.CurrentThread.Abort(); 104 Environment.Exit(1);
103 } 105 }
104 106
105 httpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); 107 httpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass);
@@ -109,21 +111,22 @@ namespace OpenSim.Server.Base
109 MainServer.Instance = httpServer; 111 MainServer.Instance = httpServer;
110 112
111 // If https_listener = true, then add an ssl listener on the https_port... 113 // If https_listener = true, then add an ssl listener on the https_port...
112 if ( ssl_listener == true ) { 114 if (ssl_listener == true)
113 115 {
114 uint https_port = (uint)networkConfig.GetInt("https_port", 0); 116 uint https_port = (uint)networkConfig.GetInt("https_port", 0);
115 117
116 string cert_path = networkConfig.GetString("cert_path",String.Empty); 118 string cert_path = networkConfig.GetString("cert_path",String.Empty);
117 if ( cert_path == String.Empty ) 119 if (cert_path == String.Empty)
118 { 120 {
119 System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); 121 System.Console.WriteLine("ERROR: Path to X509 certificate is missing, server can't start.");
120 Thread.CurrentThread.Abort(); 122 Environment.Exit(1);
121 } 123 }
124
122 string cert_pass = networkConfig.GetString("cert_pass",String.Empty); 125 string cert_pass = networkConfig.GetString("cert_pass",String.Empty);
123 if ( cert_pass == String.Empty ) 126 if (cert_pass == String.Empty)
124 { 127 {
125 System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); 128 System.Console.WriteLine("ERROR: Password for X509 certificate is missing, server can't start.");
126 Thread.CurrentThread.Abort(); 129 Environment.Exit(1);
127 } 130 }
128 131
129 MainServer.AddHttpServer(new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); 132 MainServer.AddHttpServer(new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass));
diff --git a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs
index 427fa16..faa6fb7 100644
--- a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs
+++ b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs
@@ -39,7 +39,6 @@ using OpenSim.Server.Handlers.Asset;
39using OpenSim.Services.AssetService; 39using OpenSim.Services.AssetService;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43 42
44namespace OpenSim.Server.Handlers.Asset.Test 43namespace OpenSim.Server.Handlers.Asset.Test
45{ 44{
diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs b/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs
index 9e703f1..3c61673 100644
--- a/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs
+++ b/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Server.Handlers.BakedTextures
45{ 45{
46 public class BakesServerGetHandler : BaseStreamHandler 46 public class BakesServerGetHandler : BaseStreamHandler
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private IBakedTextureService m_BakesService; 50 private IBakedTextureService m_BakesService;
51 private System.Text.UTF8Encoding utf8 = 51 private System.Text.UTF8Encoding utf8 =
diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs
index 1aacbc9..e38543b 100644
--- a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs
+++ b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs
@@ -45,13 +45,10 @@ namespace OpenSim.Server.Handlers.BakedTextures
45{ 45{
46 public class BakesServerPostHandler : BaseStreamHandler 46 public class BakesServerPostHandler : BaseStreamHandler
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private IBakedTextureService m_BakesService; 50 private IBakedTextureService m_BakesService;
51 51
52 private System.Text.UTF8Encoding utf8 =
53 new System.Text.UTF8Encoding();
54
55 public BakesServerPostHandler(IBakedTextureService service, IServiceAuth auth) : 52 public BakesServerPostHandler(IBakedTextureService service, IServiceAuth auth) :
56 base("POST", "/bakes", auth) 53 base("POST", "/bakes", auth)
57 { 54 {
@@ -76,4 +73,4 @@ namespace OpenSim.Server.Handlers.BakedTextures
76 return new byte[0]; 73 return new byte[0];
77 } 74 }
78 } 75 }
79} 76} \ No newline at end of file
diff --git a/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
index f8f1d00..49aa8ba 100644
--- a/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
+++ b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs
@@ -263,8 +263,7 @@ namespace OpenSim.Server.Handlers
263 m_log.DebugFormat ("Avatar Notes Request"); 263 m_log.DebugFormat ("Avatar Notes Request");
264 return false; 264 return false;
265 } 265 }
266 266
267 string result = string.Empty;
268 UserProfileNotes note = new UserProfileNotes(); 267 UserProfileNotes note = new UserProfileNotes();
269 object Note = (object)note; 268 object Note = (object)note;
270 OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]); 269 OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]);
@@ -403,7 +402,7 @@ namespace OpenSim.Server.Handlers
403 402
404 response.Error.Code = ErrorCode.InternalError; 403 response.Error.Code = ErrorCode.InternalError;
405 response.Error.Message = string.Format("{0}", result); 404 response.Error.Message = string.Format("{0}", result);
406 m_log.InfoFormat("[PROFILES]: User preferences request error - {0}", response.Error.Message); 405// m_log.InfoFormat("[PROFILES]: User preferences request error - {0}", response.Error.Message);
407 return false; 406 return false;
408 } 407 }
409 408
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
index da2bfeb..81c9df2 100644
--- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
@@ -182,7 +182,8 @@ namespace OpenSim.Server.Handlers.Simulation
182 if (action.Equals("release")) 182 if (action.Equals("release"))
183 ReleaseAgent(regionID, id); 183 ReleaseAgent(regionID, id);
184 else 184 else
185 Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id, auth_token); }); 185 Util.FireAndForget(
186 o => m_SimulationService.CloseAgent(destination, id, auth_token), null, "AgentHandler.DoAgentDelete");
186 187
187 responsedata["int_response_code"] = HttpStatusCode.OK; 188 responsedata["int_response_code"] = HttpStatusCode.OK;
188 responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); 189 responsedata["str_response_string"] = "OpenSim agent " + id.ToString();
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
index 95e4bab..cd4781d 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
69 Util.FireAndForget(delegate(object o) 69 Util.FireAndForget(delegate(object o)
70 { 70 {
71 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 71 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
72 }); 72 }, null, "SimianActivityDetector.SetLastPositionOnMakeRootAgent");
73 } 73 }
74 74
75 public void OnNewClient(IClientAPI client) 75 public void OnNewClient(IClientAPI client)
@@ -94,7 +94,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
94 Util.FireAndForget(delegate(object o) 94 Util.FireAndForget(delegate(object o)
95 { 95 {
96 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 96 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
97 }); 97 }, null, "SimianActivityDetector.SetLastPositionOnEnteringNewParcel");
98 } 98 }
99 } 99 }
100} \ No newline at end of file 100} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
index 01cbf91..9ad4a7a 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
@@ -225,7 +225,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
225 { 225 {
226 AssetBase asset = SimianGetOperation(id); 226 AssetBase asset = SimianGetOperation(id);
227 handler(id, sender, asset); 227 handler(id, sender, asset);
228 } 228 }, null, "SimianAssetServiceConnector.GetFromService"
229 ); 229 );
230 230
231 return true; 231 return true;
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
index 5c804d4..b57f8d8 100644
--- a/OpenSim/Services/HypergridService/HGAssetService.cs
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -100,7 +100,7 @@ namespace OpenSim.Services.HypergridService
100 return null; 100 return null;
101 101
102 if (asset.Metadata.Type == (sbyte)AssetType.Object) 102 if (asset.Metadata.Type == (sbyte)AssetType.Object)
103 asset.Data = AdjustIdentifiers(asset.Data); ; 103 asset.Data = AdjustIdentifiers(asset.Data);
104 104
105 AdjustIdentifiers(asset.Metadata); 105 AdjustIdentifiers(asset.Metadata);
106 106
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
index a8bcfb2..6e35a88 100644
--- a/OpenSim/Services/HypergridService/HGFriendsService.cs
+++ b/OpenSim/Services/HypergridService/HGFriendsService.cs
@@ -198,7 +198,8 @@ namespace OpenSim.Services.HypergridService
198 // So let's send back the call, but start a thread to continue 198 // So let's send back the call, but start a thread to continue
199 // with the verification and the actual action. 199 // with the verification and the actual action.
200 200
201 Util.FireAndForget(delegate { ProcessFriendshipOffered(fromID, fromName, toID, message); }); 201 Util.FireAndForget(
202 o => ProcessFriendshipOffered(fromID, fromName, toID, message), null, "HGFriendsService.ProcessFriendshipOffered");
202 203
203 return true; 204 return true;
204 } 205 }
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index c45ea76..ce50ab0 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Services.Interfaces
126 126
127 public class GridRegion 127 public class GridRegion
128 { 128 {
129 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 129// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
130 130
131#pragma warning disable 414 131#pragma warning disable 414
132 private static readonly string LogHeader = "[GRID REGION]"; 132 private static readonly string LogHeader = "[GRID REGION]";
@@ -135,12 +135,7 @@ namespace OpenSim.Services.Interfaces
135 /// <summary> 135 /// <summary>
136 /// The port by which http communication occurs with the region 136 /// The port by which http communication occurs with the region
137 /// </summary> 137 /// </summary>
138 public uint HttpPort 138 public uint HttpPort { get; set; }
139 {
140 get { return m_httpPort; }
141 set { m_httpPort = value; }
142 }
143 protected uint m_httpPort;
144 139
145 /// <summary> 140 /// <summary>
146 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) 141 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
@@ -151,10 +146,10 @@ namespace OpenSim.Services.Interfaces
151 if (!String.IsNullOrEmpty(m_serverURI)) { 146 if (!String.IsNullOrEmpty(m_serverURI)) {
152 return m_serverURI; 147 return m_serverURI;
153 } else { 148 } else {
154 if (m_httpPort == 0) 149 if (HttpPort == 0)
155 return "http://" + m_externalHostName + "/"; 150 return "http://" + m_externalHostName + "/";
156 else 151 else
157 return "http://" + m_externalHostName + ":" + m_httpPort + "/"; 152 return "http://" + m_externalHostName + ":" + HttpPort + "/";
158 } 153 }
159 } 154 }
160 set { 155 set {
@@ -290,7 +285,7 @@ namespace OpenSim.Services.Interfaces
290 RegionSizeY = (int)ConvertFrom.RegionSizeY; 285 RegionSizeY = (int)ConvertFrom.RegionSizeY;
291 m_internalEndPoint = ConvertFrom.InternalEndPoint; 286 m_internalEndPoint = ConvertFrom.InternalEndPoint;
292 m_externalHostName = ConvertFrom.ExternalHostName; 287 m_externalHostName = ConvertFrom.ExternalHostName;
293 m_httpPort = ConvertFrom.HttpPort; 288 HttpPort = ConvertFrom.HttpPort;
294 RegionID = ConvertFrom.RegionID; 289 RegionID = ConvertFrom.RegionID;
295 ServerURI = ConvertFrom.ServerURI; 290 ServerURI = ConvertFrom.ServerURI;
296 TerrainImage = ConvertFrom.RegionSettings.TerrainImageID; 291 TerrainImage = ConvertFrom.RegionSettings.TerrainImageID;
@@ -310,7 +305,7 @@ namespace OpenSim.Services.Interfaces
310 RegionSizeY = ConvertFrom.RegionSizeY; 305 RegionSizeY = ConvertFrom.RegionSizeY;
311 m_internalEndPoint = ConvertFrom.InternalEndPoint; 306 m_internalEndPoint = ConvertFrom.InternalEndPoint;
312 m_externalHostName = ConvertFrom.ExternalHostName; 307 m_externalHostName = ConvertFrom.ExternalHostName;
313 m_httpPort = ConvertFrom.HttpPort; 308 HttpPort = ConvertFrom.HttpPort;
314 RegionID = ConvertFrom.RegionID; 309 RegionID = ConvertFrom.RegionID;
315 ServerURI = ConvertFrom.ServerURI; 310 ServerURI = ConvertFrom.ServerURI;
316 TerrainImage = ConvertFrom.TerrainImage; 311 TerrainImage = ConvertFrom.TerrainImage;
diff --git a/OpenSim/Services/Interfaces/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs
index e601ebe..bda8151 100644
--- a/OpenSim/Services/Interfaces/OpenProfileClient.cs
+++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Services.UserProfilesService
48 /// </remarks> 48 /// </remarks>
49 public class OpenProfileClient 49 public class OpenProfileClient
50 { 50 {
51 static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 private string m_serverURI; 53 private string m_serverURI;
54 54
@@ -60,8 +60,7 @@ namespace OpenSim.Services.UserProfilesService
60 { 60 {
61 m_serverURI = serverURI; 61 m_serverURI = serverURI;
62 } 62 }
63 63
64
65 /// <summary> 64 /// <summary>
66 /// Gets an avatar's profile using the OpenProfile protocol. 65 /// Gets an avatar's profile using the OpenProfile protocol.
67 /// </summary> 66 /// </summary>
@@ -132,4 +131,4 @@ namespace OpenSim.Services.UserProfilesService
132 return true; 131 return true;
133 } 132 }
134 } 133 }
135} 134} \ No newline at end of file
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
index c07e034..a816411 100644
--- a/OpenSim/Services/MapImageService/MapImageService.cs
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -166,7 +166,8 @@ namespace OpenSim.Services.MapImageService
166 // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y); 166 // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y);
167 multiRezToBuild.Enqueue(new mapToMultiRez(x, y)); 167 multiRezToBuild.Enqueue(new mapToMultiRez(x, y));
168 if (multiRezToBuild.Count == 1) 168 if (multiRezToBuild.Count == 1)
169 Util.FireAndForget(DoUpdateMultiResolutionFilesAsync); 169 Util.FireAndForget(
170 DoUpdateMultiResolutionFilesAsync, null, "MapImageService.DoUpdateMultiResolutionFilesAsync");
170 } 171 }
171 172
172 return true; 173 return true;
diff --git a/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs b/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs
index 49c99c5..82ecf9a 100644
--- a/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs
@@ -32,7 +32,6 @@ using NUnit.Framework;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Servers; 33using OpenSim.Framework.Servers;
34using OpenSim.Framework.Servers.HttpServer; 34using OpenSim.Framework.Servers.HttpServer;
35using OpenSim.Tests.Common.Mock;
36 35
37namespace OpenSim.Tests.Common 36namespace OpenSim.Tests.Common
38{ 37{
diff --git a/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs b/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs
new file mode 100644
index 0000000..33cd8a2
--- /dev/null
+++ b/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Net;
30using Nini.Config;
31using OpenMetaverse;
32using OpenMetaverse.Packets;
33using OpenSim.Framework;
34using OpenSim.Region.ClientStack.LindenUDP;
35using OpenSim.Region.Framework.Scenes;
36
37namespace OpenSim.Tests.Common
38{
39 /// <summary>
40 /// This class adds full UDP client classes and associated scene presence to scene.
41 /// </summary>
42 /// <remarks>
43 /// This is used for testing client stack code. For testing other code, use SceneHelper methods instead since
44 /// they operate without the burden of setting up UDP structures which should be unnecessary for testing scene
45 /// code.
46 /// </remarks>
47 public static class ClientStackHelpers
48 {
49 public static ScenePresence AddChildClient(
50 Scene scene, LLUDPServer udpServer, UUID agentId, UUID sessionId, uint circuitCode)
51 {
52 IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
53
54 UseCircuitCodePacket uccp = new UseCircuitCodePacket();
55
56 UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
57 = new UseCircuitCodePacket.CircuitCodeBlock();
58 uccpCcBlock.Code = circuitCode;
59 uccpCcBlock.ID = agentId;
60 uccpCcBlock.SessionID = sessionId;
61 uccp.CircuitCode = uccpCcBlock;
62
63 byte[] uccpBytes = uccp.ToBytes();
64 UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
65 upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
66 Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
67
68 AgentCircuitData acd = new AgentCircuitData();
69 acd.AgentID = agentId;
70 acd.SessionID = sessionId;
71
72 scene.AuthenticateHandler.AddNewCircuit(circuitCode, acd);
73
74 udpServer.PacketReceived(upb);
75
76 return scene.GetScenePresence(agentId);
77 }
78
79 public static TestLLUDPServer AddUdpServer(Scene scene)
80 {
81 return AddUdpServer(scene, new IniConfigSource());
82 }
83
84 public static TestLLUDPServer AddUdpServer(Scene scene, IniConfigSource configSource)
85 {
86 uint port = 0;
87 AgentCircuitManager acm = scene.AuthenticateHandler;
88
89 TestLLUDPServer udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
90 udpServer.AddScene(scene);
91
92 return udpServer;
93 }
94 }
95} \ No newline at end of file
diff --git a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
index 049200c..cf7583e 100644
--- a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.CoreModules.Framework; 44using OpenSim.Region.CoreModules.Framework;
45using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47 46
48namespace OpenSim.Tests.Common 47namespace OpenSim.Tests.Common
49{ 48{
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index 4369659..1fb1c5c 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -49,7 +49,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
49using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts; 49using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
50using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; 50using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence;
51using OpenSim.Services.Interfaces; 51using OpenSim.Services.Interfaces;
52using OpenSim.Tests.Common.Mock;
53using GridRegion = OpenSim.Services.Interfaces.GridRegion; 52using GridRegion = OpenSim.Services.Interfaces.GridRegion;
54 53
55namespace OpenSim.Tests.Common 54namespace OpenSim.Tests.Common
diff --git a/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs b/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs
index e6e08cd..cb4fb80 100644
--- a/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs
+++ b/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs
@@ -30,7 +30,7 @@ using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32 32
33namespace OpenSim.Tests.Common.Mock 33namespace OpenSim.Tests.Common
34{ 34{
35 public class BaseAssetRepository 35 public class BaseAssetRepository
36 { 36 {
diff --git a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
index 4a15cf2..dddf75d 100644
--- a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs
@@ -31,7 +31,7 @@ using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Data; 32using OpenSim.Data;
33 33
34namespace OpenSim.Tests.Common.Mock 34namespace OpenSim.Tests.Common
35{ 35{
36 /// <summary> 36 /// <summary>
37 /// In memory asset data plugin for test purposes. Could be another dll when properly filled out and when the 37 /// In memory asset data plugin for test purposes. Could be another dll when properly filled out and when the
diff --git a/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs b/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs
index 5a257e9..7f530d0 100644
--- a/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs
+++ b/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs
@@ -40,7 +40,7 @@ using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 41using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
42 42
43namespace OpenSim.Tests.Common.Mock 43namespace OpenSim.Tests.Common
44{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
46 public class MockGroupsServicesConnector : ISharedRegionModule, IGroupsServicesConnector 46 public class MockGroupsServicesConnector : ISharedRegionModule, IGroupsServicesConnector
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 8eeaf99..0e1bc8f 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -38,7 +38,7 @@ using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Framework.Client; 39using OpenSim.Framework.Client;
40 40
41namespace OpenSim.Tests.Common.Mock 41namespace OpenSim.Tests.Common
42{ 42{
43 public class TestClient : IClientAPI, IClientCore 43 public class TestClient : IClientAPI, IClientCore
44 { 44 {
diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs
index fc44358..a8883b8 100644
--- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs
@@ -33,7 +33,7 @@ using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Data; 34using OpenSim.Data;
35 35
36namespace OpenSim.Tests.Common.Mock 36namespace OpenSim.Tests.Common
37{ 37{
38 /// <summary> 38 /// <summary>
39 /// In memory inventory data plugin for test purposes. Could be another dll when properly filled out and when the 39 /// In memory inventory data plugin for test purposes. Could be another dll when properly filled out and when the
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Tests/Common/Mock/TestLLUDPServer.cs
index 27b9e5b..26887c9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
+++ b/OpenSim/Tests/Common/Mock/TestLLUDPServer.cs
@@ -32,8 +32,9 @@ using System.Net.Sockets;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse.Packets; 33using OpenMetaverse.Packets;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.ClientStack.LindenUDP;
35 36
36namespace OpenSim.Region.ClientStack.LindenUDP.Tests 37namespace OpenSim.Tests.Common
37{ 38{
38 /// <summary> 39 /// <summary>
39 /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data. 40 /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data.
diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
index 3115035..89ebcd5 100644
--- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs
+++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
@@ -32,7 +32,7 @@ using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.CoreModules.World.Land; 33using OpenSim.Region.CoreModules.World.Land;
34 34
35namespace OpenSim.Tests.Common.Mock 35namespace OpenSim.Tests.Common
36{ 36{
37 /// <summary> 37 /// <summary>
38 /// Land channel for test purposes 38 /// Land channel for test purposes
diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs
index e769d30..7b1d2b5 100644
--- a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs
+++ b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs
@@ -35,7 +35,7 @@ using System.Text;
35using System.Web; 35using System.Web;
36using OpenSim.Framework.Servers.HttpServer; 36using OpenSim.Framework.Servers.HttpServer;
37 37
38namespace OpenSim.Tests.Common.Mock 38namespace OpenSim.Tests.Common
39{ 39{
40 public class TestOSHttpRequest : IOSHttpRequest 40 public class TestOSHttpRequest : IOSHttpRequest
41 { 41 {
diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs
index e10fe82..2e17f1e 100644
--- a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs
+++ b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs
@@ -32,7 +32,7 @@ using System.Text;
32using System.Web; 32using System.Web;
33using OpenSim.Framework.Servers.HttpServer; 33using OpenSim.Framework.Servers.HttpServer;
34 34
35namespace OpenSim.Tests.Common.Mock 35namespace OpenSim.Tests.Common
36{ 36{
37 public class TestOSHttpResponse : IOSHttpResponse 37 public class TestOSHttpResponse : IOSHttpResponse
38 { 38 {
diff --git a/OpenSim/Tests/Common/Mock/TestScene.cs b/OpenSim/Tests/Common/Mock/TestScene.cs
index 40e2adc..45acf91 100644
--- a/OpenSim/Tests/Common/Mock/TestScene.cs
+++ b/OpenSim/Tests/Common/Mock/TestScene.cs
@@ -36,7 +36,7 @@ using OpenSim.Region.Framework.Scenes;
36using OpenSim.Region.Physics.Manager; 36using OpenSim.Region.Physics.Manager;
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38 38
39namespace OpenSim.Tests.Common.Mock 39namespace OpenSim.Tests.Common
40{ 40{
41 public class TestScene : Scene 41 public class TestScene : Scene
42 { 42 {
diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
index 2be5524..be3a0cb 100644
--- a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
+++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
@@ -35,7 +35,7 @@ using OpenSim.Framework;
35using OpenSim.Data; 35using OpenSim.Data;
36using OpenSim.Data.Null; 36using OpenSim.Data.Null;
37 37
38namespace OpenSim.Tests.Common.Mock 38namespace OpenSim.Tests.Common
39{ 39{
40 public class TestXInventoryDataPlugin : NullGenericDataHandler, IXInventoryData 40 public class TestXInventoryDataPlugin : NullGenericDataHandler, IXInventoryData
41 { 41 {
diff --git a/OpenSim/Tests/Performance/NPCPerformanceTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs
index eb09061..e222dc2 100644
--- a/OpenSim/Tests/Performance/NPCPerformanceTests.cs
+++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.OptionalModules.World.NPC; 45using OpenSim.Region.OptionalModules.World.NPC;
46using OpenSim.Services.AvatarService; 46using OpenSim.Services.AvatarService;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49 48
50namespace OpenSim.Tests.Performance 49namespace OpenSim.Tests.Performance
51{ 50{
diff --git a/OpenSim/Tests/Performance/ObjectPerformanceTests.cs b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs
index 656a971..9dad423 100644
--- a/OpenSim/Tests/Performance/ObjectPerformanceTests.cs
+++ b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs
@@ -34,7 +34,6 @@ using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38 37
39namespace OpenSim.Tests.Performance 38namespace OpenSim.Tests.Performance
40{ 39{
diff --git a/OpenSim/Tests/Performance/ScriptPerformanceTests.cs b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs
index 4064edc..028f4b0 100644
--- a/OpenSim/Tests/Performance/ScriptPerformanceTests.cs
+++ b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs
@@ -40,7 +40,6 @@ using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.XEngine; 41using OpenSim.Region.ScriptEngine.XEngine;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock;
44 43
45namespace OpenSim.Tests.Performance 44namespace OpenSim.Tests.Performance
46{ 45{
diff --git a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs
index 1f220c0..0ab407e 100644
--- a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs
+++ b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs
@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.Scripting.VectorRender;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Tests.Common; 43using OpenSim.Tests.Common;
44using OpenSim.Tests.Common.Mock;
45 44
46namespace OpenSim.Tests.Stress 45namespace OpenSim.Tests.Stress
47{ 46{
@@ -79,7 +78,7 @@ namespace OpenSim.Tests.Stress
79 Drawer d = new Drawer(this, i); 78 Drawer d = new Drawer(this, i);
80 drawers.Add(d); 79 drawers.Add(d);
81 Console.WriteLine("Starting drawer {0}", i); 80 Console.WriteLine("Starting drawer {0}", i);
82 Util.FireAndForget(o => d.Draw()); 81 Util.FireAndForget(o => d.Draw(), null, "VectorRenderModuleStressTests.TestConcurrentRepeatedDraw");
83 } 82 }
84 83
85 Thread.Sleep(10 * 60 * 1000); 84 Thread.Sleep(10 * 60 * 1000);
diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
index 4a7237c..0d43781 100644
--- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
+++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs
@@ -46,7 +46,10 @@ namespace pCampBot
46 46
47 public override void Action() 47 public override void Action()
48 { 48 {
49 Bot.Client.Self.Jump(false);
50 Bot.Client.Self.Movement.Stop = true;
49 m_interruptEvent.WaitOne(); 51 m_interruptEvent.WaitOne();
52 Bot.Client.Self.Movement.Stop = false;
50 } 53 }
51 54
52 public override void Interrupt() 55 public override void Interrupt()