aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs167
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs6
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs51
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs3
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs3
-rw-r--r--OpenSim/Framework/WebUtil.cs20
-rw-r--r--OpenSim/Region/Application/Application.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs21
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs223
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs4
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs2
-rw-r--r--OpenSim/Server/Handlers/Simulation/AgentHandlers.cs10
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs108
17 files changed, 425 insertions, 208 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index f040ff7..4e755aa 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -47,36 +47,36 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
47 47
48namespace OpenSim.Capabilities.Handlers 48namespace OpenSim.Capabilities.Handlers
49{ 49{
50 public class GetTextureHandler : BaseStreamHandler 50 public class GetTextureHandler
51 { 51 {
52 private static readonly ILog m_log = 52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
54 private IAssetService m_assetService; 55 private IAssetService m_assetService;
55 56
56 public const string DefaultFormat = "x-j2c"; 57 public const string DefaultFormat = "x-j2c";
57 58
58 // TODO: Change this to a config option 59 public GetTextureHandler(IAssetService assService)
59 const string REDIRECT_URL = null;
60
61 public GetTextureHandler(string path, IAssetService assService, string name, string description)
62 : base("GET", path, name, description)
63 { 60 {
64 m_assetService = assService; 61 m_assetService = assService;
65 } 62 }
66 63
67 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 64 public Hashtable Handle(Hashtable request)
68 { 65 {
69 // Try to parse the texture ID from the request URL 66 Hashtable ret = new Hashtable();
70 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); 67 ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
71 string textureStr = query.GetOne("texture_id"); 68 ret["content_type"] = "text/plain";
72 string format = query.GetOne("format"); 69 ret["keepalive"] = false;
70 ret["reusecontext"] = false;
71
72 string textureStr = (string)request["texture_id"];
73 string format = (string)request["format"];
73 74
74 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); 75 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
75 76
76 if (m_assetService == null) 77 if (m_assetService == null)
77 { 78 {
78 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); 79 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
79 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
80 } 80 }
81 81
82 UUID textureID; 82 UUID textureID;
@@ -91,30 +91,30 @@ namespace OpenSim.Capabilities.Handlers
91 } 91 }
92 else 92 else
93 { 93 {
94 formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); 94 formats = new string[1] { DefaultFormat }; // default
95 if (((Hashtable)request["headers"])["Accept"] != null)
96 formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
95 if (formats.Length == 0) 97 if (formats.Length == 0)
96 formats = new string[1] { DefaultFormat }; // default 98 formats = new string[1] { DefaultFormat }; // default
97 99
98 } 100 }
99 // OK, we have an array with preferred formats, possibly with only one entry 101 // OK, we have an array with preferred formats, possibly with only one entry
100 102
101 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
102 foreach (string f in formats) 103 foreach (string f in formats)
103 { 104 {
104 if (FetchTexture(httpRequest, httpResponse, textureID, f)) 105 if (FetchTexture(request, ret, textureID, f))
105 break; 106 break;
106 } 107 }
107 } 108 }
108 else 109 else
109 { 110 {
110 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); 111 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
111 } 112 }
112 113
113// m_log.DebugFormat( 114// m_log.DebugFormat(
114// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", 115// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
115// textureID, httpResponse.StatusCode, httpResponse.ContentLength); 116// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
116 117 return ret;
117 return null;
118 } 118 }
119 119
120 /// <summary> 120 /// <summary>
@@ -125,7 +125,7 @@ namespace OpenSim.Capabilities.Handlers
125 /// <param name="textureID"></param> 125 /// <param name="textureID"></param>
126 /// <param name="format"></param> 126 /// <param name="format"></param>
127 /// <returns>False for "caller try another codec"; true otherwise</returns> 127 /// <returns>False for "caller try another codec"; true otherwise</returns>
128 private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format) 128 private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
129 { 129 {
130// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); 130// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
131 AssetBase texture; 131 AssetBase texture;
@@ -134,84 +134,61 @@ namespace OpenSim.Capabilities.Handlers
134 if (format != DefaultFormat) 134 if (format != DefaultFormat)
135 fullID = fullID + "-" + format; 135 fullID = fullID + "-" + format;
136 136
137 if (!String.IsNullOrEmpty(REDIRECT_URL)) 137 // try the cache
138 texture = m_assetService.GetCached(fullID);
139
140 if (texture == null)
138 { 141 {
139 // Only try to fetch locally cached textures. Misses are redirected 142 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
140 texture = m_assetService.GetCached(fullID); 143
144 // Fetch locally or remotely. Misses return a 404
145 texture = m_assetService.Get(textureID.ToString());
141 146
142 if (texture != null) 147 if (texture != null)
143 { 148 {
144 if (texture.Type != (sbyte)AssetType.Texture) 149 if (texture.Type != (sbyte)AssetType.Texture)
150 return true;
151
152 if (format == DefaultFormat)
145 { 153 {
146 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 154 WriteTextureData(request, response, texture, format);
147 return true; 155 return true;
148 } 156 }
149 WriteTextureData(httpRequest, httpResponse, texture, format); 157 else
150 }
151 else
152 {
153 string textureUrl = REDIRECT_URL + textureID.ToString();
154 m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
155 httpResponse.RedirectLocation = textureUrl;
156 return true;
157 }
158 }
159 else // no redirect
160 {
161 // try the cache
162 texture = m_assetService.GetCached(fullID);
163
164 if (texture == null)
165 {
166 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
167
168 // Fetch locally or remotely. Misses return a 404
169 texture = m_assetService.Get(textureID.ToString());
170
171 if (texture != null)
172 { 158 {
173 if (texture.Type != (sbyte)AssetType.Texture) 159 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
174 { 160 newTexture.Data = ConvertTextureData(texture, format);
175 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 161 if (newTexture.Data.Length == 0)
176 return true; 162 return false; // !!! Caller try another codec, please!
177 } 163
178 if (format == DefaultFormat) 164 newTexture.Flags = AssetFlags.Collectable;
179 { 165 newTexture.Temporary = true;
180 WriteTextureData(httpRequest, httpResponse, texture, format); 166 m_assetService.Store(newTexture);
181 return true; 167 WriteTextureData(request, response, newTexture, format);
182 } 168 return true;
183 else
184 {
185 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
186 newTexture.Data = ConvertTextureData(texture, format);
187 if (newTexture.Data.Length == 0)
188 return false; // !!! Caller try another codec, please!
189
190 newTexture.Flags = AssetFlags.Collectable;
191 newTexture.Temporary = true;
192 m_assetService.Store(newTexture);
193 WriteTextureData(httpRequest, httpResponse, newTexture, format);
194 return true;
195 }
196 } 169 }
197 } 170 }
198 else // it was on the cache 171 }
199 { 172 else // it was on the cache
200 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); 173 {
201 WriteTextureData(httpRequest, httpResponse, texture, format); 174 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
202 return true; 175 WriteTextureData(request, response, texture, format);
203 } 176 return true;
204 } 177 }
205 178
206 // not found 179 // not found
207// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); 180// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
208 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
209 return true; 181 return true;
210 } 182 }
211 183
212 private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format) 184 private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
213 { 185 {
214 string range = request.Headers.GetOne("Range"); 186 Hashtable headers = new Hashtable();
187 response["headers"] = headers;
188
189 string range = String.Empty;
190 if (((Hashtable)request["headers"])["Range"] != null)
191 range = (string)((Hashtable)request["headers"])["Range"];
215 192
216 if (!String.IsNullOrEmpty(range)) // JP2's only 193 if (!String.IsNullOrEmpty(range)) // JP2's only
217 { 194 {
@@ -226,7 +203,7 @@ namespace OpenSim.Capabilities.Handlers
226 { 203 {
227// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; 204// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
228 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters 205 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
229 response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 206 response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
230 } 207 }
231 else 208 else
232 { 209 {
@@ -240,31 +217,33 @@ namespace OpenSim.Capabilities.Handlers
240 // We were accidentally sending back 404 before in this situation 217 // We were accidentally sending back 404 before in this situation
241 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the 218 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
242 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. 219 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
243 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; 220 response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
244 221 response["content-type"] = texture.Metadata.ContentType;
245 response.ContentLength = len; 222 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
246 response.ContentType = texture.Metadata.ContentType;
247 response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
248 223
249 response.Body.Write(texture.Data, start, len); 224 byte[] d = new byte[len];
225 Array.Copy(texture.Data, start, d, 0, len);
226 response["bin_response_data"] = d;
227// response.Body.Write(texture.Data, start, len);
250 } 228 }
251 } 229 }
252 else 230 else
253 { 231 {
254 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); 232 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
255 response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; 233 response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
256 } 234 }
257 } 235 }
258 else // JP2's or other formats 236 else // JP2's or other formats
259 { 237 {
260 // Full content request 238 // Full content request
261 response.StatusCode = (int)System.Net.HttpStatusCode.OK; 239 response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
262 response.ContentLength = texture.Data.Length;
263 if (format == DefaultFormat) 240 if (format == DefaultFormat)
264 response.ContentType = texture.Metadata.ContentType; 241 response["content_type"] = texture.Metadata.ContentType;
265 else 242 else
266 response.ContentType = "image/" + format; 243 response["content_type"] = "image/" + format;
267 response.Body.Write(texture.Data, 0, texture.Data.Length); 244
245 response["bin_response_data"] = texture.Data;
246// response.Body.Write(texture.Data, 0, texture.Data.Length);
268 } 247 }
269 248
270// if (response.StatusCode < 200 || response.StatusCode > 299) 249// if (response.StatusCode < 200 || response.StatusCode > 299)
@@ -368,4 +347,4 @@ namespace OpenSim.Capabilities.Handlers
368 return null; 347 return null;
369 } 348 }
370 } 349 }
371} \ No newline at end of file 350}
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
index 71cf033..bf66acb 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
@@ -33,6 +33,7 @@ using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base; 33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse; 34using OpenMetaverse;
35 35
36/*
36namespace OpenSim.Capabilities.Handlers 37namespace OpenSim.Capabilities.Handlers
37{ 38{
38 public class GetTextureServerConnector : ServiceConnector 39 public class GetTextureServerConnector : ServiceConnector
@@ -63,7 +64,8 @@ namespace OpenSim.Capabilities.Handlers
63 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); 64 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
64 65
65 server.AddStreamHandler( 66 server.AddStreamHandler(
66 new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null)); 67 new GetTextureHandler("/CAPS/GetTexture/", m_AssetService, "GetTexture", null));
67 } 68 }
68 } 69 }
69} \ No newline at end of file 70}
71*/
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
index 761e4e7..b6ae41b 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
@@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock; 40using OpenSim.Tests.Common.Mock;
41 41
42/*
42namespace OpenSim.Capabilities.Handlers.GetTexture.Tests 43namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
43{ 44{
44 [TestFixture] 45 [TestFixture]
@@ -60,4 +61,5 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
60 Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound)); 61 Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
61 } 62 }
62 } 63 }
63} \ No newline at end of file 64}
65*/
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 7384e39..2582b7b 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -640,7 +640,7 @@ namespace OpenSim.Framework.Servers.HttpServer
640 // Every month or so this will wrap and give bad numbers, not really a problem 640 // Every month or so this will wrap and give bad numbers, not really a problem
641 // since its just for reporting 641 // since its just for reporting
642 int tickdiff = requestEndTick - requestStartTick; 642 int tickdiff = requestEndTick - requestStartTick;
643 if (tickdiff > 3000) 643 if (tickdiff > 3000 && (requestHandler == null || requestHandler.Name == null || requestHandler.Name != "GetTexture"))
644 { 644 {
645 m_log.InfoFormat( 645 m_log.InfoFormat(
646 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", 646 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
@@ -1449,7 +1449,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1449 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1449 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1450 { 1450 {
1451 int responsecode; 1451 int responsecode;
1452 string responseString; 1452 string responseString = String.Empty;
1453 byte[] responseData = null;
1453 string contentType; 1454 string contentType;
1454 1455
1455 if (responsedata == null) 1456 if (responsedata == null)
@@ -1465,8 +1466,13 @@ namespace OpenSim.Framework.Servers.HttpServer
1465 { 1466 {
1466 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); 1467 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1467 responsecode = (int)responsedata["int_response_code"]; 1468 responsecode = (int)responsedata["int_response_code"];
1468 responseString = (string)responsedata["str_response_string"]; 1469 if (responsedata["bin_response_data"] != null)
1470 responseData = (byte[])responsedata["bin_response_data"];
1471 else
1472 responseString = (string)responsedata["str_response_string"];
1469 contentType = (string)responsedata["content_type"]; 1473 contentType = (string)responsedata["content_type"];
1474 if (responseString == null)
1475 responseString = String.Empty;
1470 } 1476 }
1471 catch 1477 catch
1472 { 1478 {
@@ -1520,25 +1526,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1520 1526
1521 response.AddHeader("Content-Type", contentType); 1527 response.AddHeader("Content-Type", contentType);
1522 1528
1529 if (responsedata.ContainsKey("headers"))
1530 {
1531 Hashtable headerdata = (Hashtable)responsedata["headers"];
1532
1533 foreach (string header in headerdata.Keys)
1534 response.AddHeader(header, (string)headerdata[header]);
1535 }
1536
1523 byte[] buffer; 1537 byte[] buffer;
1524 1538
1525 if (!(contentType.Contains("image") 1539 if (responseData != null)
1526 || contentType.Contains("x-shockwave-flash")
1527 || contentType.Contains("application/x-oar")
1528 || contentType.Contains("application/vnd.ll.mesh")))
1529 { 1540 {
1530 // Text 1541 buffer = responseData;
1531 buffer = Encoding.UTF8.GetBytes(responseString);
1532 } 1542 }
1533 else 1543 else
1534 { 1544 {
1535 // Binary! 1545 if (!(contentType.Contains("image")
1536 buffer = Convert.FromBase64String(responseString); 1546 || contentType.Contains("x-shockwave-flash")
1537 } 1547 || contentType.Contains("application/x-oar")
1548 || contentType.Contains("application/vnd.ll.mesh")))
1549 {
1550 // Text
1551 buffer = Encoding.UTF8.GetBytes(responseString);
1552 }
1553 else
1554 {
1555 // Binary!
1556 buffer = Convert.FromBase64String(responseString);
1557 }
1538 1558
1539 response.SendChunked = false; 1559 response.SendChunked = false;
1540 response.ContentLength64 = buffer.Length; 1560 response.ContentLength64 = buffer.Length;
1541 response.ContentEncoding = Encoding.UTF8; 1561 response.ContentEncoding = Encoding.UTF8;
1562 }
1542 1563
1543 return buffer; 1564 return buffer;
1544 } 1565 }
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index c24a000..a80b1d7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -52,7 +52,8 @@ namespace OpenSim.Framework.Servers.HttpServer
52 { 52 {
53 Normal = 0, 53 Normal = 0,
54 LslHttp = 1, 54 LslHttp = 1,
55 Inventory = 2 55 Inventory = 2,
56 Texture = 3
56 } 57 }
57 58
58 public PollServiceEventArgs( 59 public PollServiceEventArgs(
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index a1dee4e..db088e7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -231,8 +231,7 @@ namespace OpenSim.Framework.Servers.HttpServer
231 { 231 {
232 if (m_running) 232 if (m_running)
233 { 233 {
234 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LslHttp || 234 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal)
235 req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Inventory)
236 { 235 {
237 m_requests.Enqueue(req); 236 m_requests.Enqueue(req);
238 } 237 }
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 6a40cd5..8094b6d 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -695,6 +695,13 @@ namespace OpenSim.Framework
695 public static void MakeRequest<TRequest, TResponse>(string verb, 695 public static void MakeRequest<TRequest, TResponse>(string verb,
696 string requestUrl, TRequest obj, Action<TResponse> action) 696 string requestUrl, TRequest obj, Action<TResponse> action)
697 { 697 {
698 MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, 0);
699 }
700
701 public static void MakeRequest<TRequest, TResponse>(string verb,
702 string requestUrl, TRequest obj, Action<TResponse> action,
703 int maxConnections)
704 {
698 int reqnum = WebUtil.RequestNumber++; 705 int reqnum = WebUtil.RequestNumber++;
699 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 706 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
700 707
@@ -706,6 +713,10 @@ namespace OpenSim.Framework
706 Type type = typeof(TRequest); 713 Type type = typeof(TRequest);
707 714
708 WebRequest request = WebRequest.Create(requestUrl); 715 WebRequest request = WebRequest.Create(requestUrl);
716 HttpWebRequest ht = (HttpWebRequest)request;
717 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
718 ht.ServicePoint.ConnectionLimit = maxConnections;
719
709 WebResponse response = null; 720 WebResponse response = null;
710 TResponse deserial = default(TResponse); 721 TResponse deserial = default(TResponse);
711 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); 722 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
@@ -1003,6 +1014,11 @@ namespace OpenSim.Framework
1003 1014
1004 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) 1015 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
1005 { 1016 {
1017 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0);
1018 }
1019
1020 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections)
1021 {
1006 int reqnum = WebUtil.RequestNumber++; 1022 int reqnum = WebUtil.RequestNumber++;
1007 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 1023 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
1008 1024
@@ -1013,6 +1029,10 @@ namespace OpenSim.Framework
1013 TResponse deserial = default(TResponse); 1029 TResponse deserial = default(TResponse);
1014 1030
1015 WebRequest request = WebRequest.Create(requestUrl); 1031 WebRequest request = WebRequest.Create(requestUrl);
1032 HttpWebRequest ht = (HttpWebRequest)request;
1033 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
1034 ht.ServicePoint.ConnectionLimit = maxConnections;
1035
1016 request.Method = verb; 1036 request.Method = verb;
1017 if (pTimeout != 0) 1037 if (pTimeout != 0)
1018 request.Timeout = pTimeout * 1000; 1038 request.Timeout = pTimeout * 1000;
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 78636c4..0f90d37 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -74,7 +74,7 @@ namespace OpenSim
74 AppDomain.CurrentDomain.UnhandledException += 74 AppDomain.CurrentDomain.UnhandledException +=
75 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 75 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
76 76
77 ServicePointManager.DefaultConnectionLimit = 6; 77 ServicePointManager.DefaultConnectionLimit = 12;
78 78
79 // Add the arguments supplied when running the application to the configuration 79 // Add the arguments supplied when running the application to the configuration
80 ArgvConfigSource configSource = new ArgvConfigSource(args); 80 ArgvConfigSource configSource = new ArgvConfigSource(args);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 9982556..580c005 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Timers;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.IO; 32using System.IO;
@@ -466,6 +467,8 @@ namespace OpenSim.Region.ClientStack.Linden
466 467
467 if (llsdRequest.asset_type == "mesh") 468 if (llsdRequest.asset_type == "mesh")
468 { 469 {
470 cost += 20; // Constant for now to test showing a price
471
469 if (llsdRequest.asset_resources == null) 472 if (llsdRequest.asset_resources == null)
470 { 473 {
471 client.SendAgentAlertMessage("Unable to upload asset. missing information.", false); 474 client.SendAgentAlertMessage("Unable to upload asset. missing information.", false);
@@ -479,7 +482,7 @@ namespace OpenSim.Region.ClientStack.Linden
479 uint textures_cost = (uint)llsdRequest.asset_resources.texture_list.Array.Count; 482 uint textures_cost = (uint)llsdRequest.asset_resources.texture_list.Array.Count;
480 textures_cost *= (uint)mm.UploadCharge; 483 textures_cost *= (uint)mm.UploadCharge;
481 484
482 cost = textures_cost; 485 cost += textures_cost;
483 } 486 }
484 else 487 else
485 { 488 {
@@ -1092,6 +1095,9 @@ namespace OpenSim.Region.ClientStack.Linden
1092 1095
1093 public class AssetUploader 1096 public class AssetUploader
1094 { 1097 {
1098 private static readonly ILog m_log =
1099 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1100
1095 public event UpLoadedAsset OnUpLoad; 1101 public event UpLoadedAsset OnUpLoad;
1096 private UpLoadedAsset handlerUpLoad = null; 1102 private UpLoadedAsset handlerUpLoad = null;
1097 1103
@@ -1106,6 +1112,7 @@ namespace OpenSim.Region.ClientStack.Linden
1106 1112
1107 private string m_invType = String.Empty; 1113 private string m_invType = String.Empty;
1108 private string m_assetType = String.Empty; 1114 private string m_assetType = String.Empty;
1115 private Timer m_timeoutTimer = new Timer();
1109 1116
1110 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1117 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1111 UUID parentFolderID, string invType, string assetType, string path, 1118 UUID parentFolderID, string invType, string assetType, string path,
@@ -1121,6 +1128,11 @@ namespace OpenSim.Region.ClientStack.Linden
1121 m_assetType = assetType; 1128 m_assetType = assetType;
1122 m_invType = invType; 1129 m_invType = invType;
1123 m_dumpAssetsToFile = dumpAssetsToFile; 1130 m_dumpAssetsToFile = dumpAssetsToFile;
1131
1132 m_timeoutTimer.Elapsed += TimedOut;
1133 m_timeoutTimer.Interval = 120000;
1134 m_timeoutTimer.AutoReset = false;
1135 m_timeoutTimer.Start();
1124 } 1136 }
1125 1137
1126 /// <summary> 1138 /// <summary>
@@ -1142,6 +1154,7 @@ namespace OpenSim.Region.ClientStack.Linden
1142 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1154 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1143 1155
1144 httpListener.RemoveStreamHandler("POST", uploaderPath); 1156 httpListener.RemoveStreamHandler("POST", uploaderPath);
1157 m_timeoutTimer.Stop();
1145 1158
1146 // TODO: probably make this a better set of extensions here 1159 // TODO: probably make this a better set of extensions here
1147 string extension = ".jp2"; 1160 string extension = ".jp2";
@@ -1163,6 +1176,12 @@ namespace OpenSim.Region.ClientStack.Linden
1163 return res; 1176 return res;
1164 } 1177 }
1165 1178
1179 private void TimedOut(object sender, ElapsedEventArgs args)
1180 {
1181 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
1182 httpListener.RemoveStreamHandler("POST", uploaderPath);
1183 }
1184
1166 ///Left this in and commented in case there are unforseen issues 1185 ///Left this in and commented in case there are unforseen issues
1167 //private void SaveAssetToFile(string filename, byte[] data) 1186 //private void SaveAssetToFile(string filename, byte[] data)
1168 //{ 1187 //{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 5ae9cc3..5b125ea 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -27,18 +27,13 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Specialized; 30using System.Collections.Generic;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection; 31using System.Reflection;
34using System.IO; 32using System.Threading;
35using System.Web;
36using log4net; 33using log4net;
37using Nini.Config; 34using Nini.Config;
38using Mono.Addins; 35using Mono.Addins;
39using OpenMetaverse; 36using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework; 37using OpenSim.Framework;
43using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
@@ -47,64 +42,73 @@ using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
50 46
51namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
52{ 48{
53 49
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 50 /// <summary>
51 /// This module implements both WebFetchTextureDescendents and FetchTextureDescendents2 capabilities.
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 54 public class GetTextureModule : INonSharedRegionModule
56 { 55 {
57// private static readonly ILog m_log = 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57
59
60 private Scene m_scene; 58 private Scene m_scene;
61 private IAssetService m_assetService;
62 59
63 private bool m_Enabled = false; 60 private static GetTextureHandler m_getTextureHandler;
61
62 private IAssetService m_assetService = null;
64 63
65 // TODO: Change this to a config option 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
66 const string REDIRECT_URL = null; 65 private static Thread[] m_workerThreads = null;
67 66
68 private string m_URL; 67 private static OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs>();
69 69
70 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
71 71
72 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
73 { 73 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"];
75 if (config == null)
76 return;
77
78 m_URL = config.GetString("Cap_GetTexture", string.Empty);
79 // Cap doesn't exist
80 if (m_URL != string.Empty)
81 m_Enabled = true;
82 } 74 }
83 75
84 public void AddRegion(Scene s) 76 public void AddRegion(Scene s)
85 { 77 {
86 if (!m_Enabled)
87 return;
88
89 m_scene = s; 78 m_scene = s;
79 m_assetService = s.AssetService;
90 } 80 }
91 81
92 public void RemoveRegion(Scene s) 82 public void RemoveRegion(Scene s)
93 { 83 {
94 if (!m_Enabled)
95 return;
96
97 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 84 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
85 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
98 m_scene = null; 86 m_scene = null;
99 } 87 }
100 88
101 public void RegionLoaded(Scene s) 89 public void RegionLoaded(Scene s)
102 { 90 {
103 if (!m_Enabled) 91 // We'll reuse the same handler for all requests.
104 return; 92 m_getTextureHandler = new GetTextureHandler(m_assetService);
105 93
106 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
107 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 94 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
95 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
96
97 if (m_workerThreads == null)
98 {
99 m_workerThreads = new Thread[4];
100
101 for (uint i = 0; i < 4; i++)
102 {
103 m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
104 String.Format("TextureWorkerThread{0}", i),
105 ThreadPriority.Normal,
106 false,
107 true,
108 null,
109 int.MaxValue);
110 }
111 }
108 } 112 }
109 113
110 public void PostInitialise() 114 public void PostInitialise()
@@ -122,24 +126,155 @@ namespace OpenSim.Region.ClientStack.Linden
122 126
123 #endregion 127 #endregion
124 128
125 public void RegisterCaps(UUID agentID, Caps caps) 129 ~GetTextureModule()
130 {
131 foreach (Thread t in m_workerThreads)
132 t.Abort();
133 }
134
135 private class PollServiceTextureEventArgs : PollServiceEventArgs
126 { 136 {
127 UUID capID = UUID.Random(); 137 private List<Hashtable> requests =
138 new List<Hashtable>();
139 private Dictionary<UUID, Hashtable> responses =
140 new Dictionary<UUID, Hashtable>();
141
142 private Scene m_scene;
128 143
129 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 144 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
130 if (m_URL == "localhost") 145 base(null, null, null, null, pId, 30000)
131 { 146 {
132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 147 m_scene = scene;
133 caps.RegisterHandler( 148
134 "GetTexture", 149 HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
135 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString())); 150 GetEvents = (x, y, s) =>
151 {
152 try
153 {
154 return this.responses[x];
155 }
156 finally
157 {
158 responses.Remove(x);
159 }
160 };
161
162 Request = (x, y) =>
163 {
164 y["RequestID"] = x.ToString();
165 lock (this.requests)
166 this.requests.Add(y);
167
168 m_queue.Enqueue(this);
169 };
170
171 NoEvents = (x, y) =>
172 {
173 lock (this.requests)
174 {
175 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
176 requests.Remove(request);
177 }
178
179 Hashtable response = new Hashtable();
180
181 response["int_response_code"] = 500;
182 response["str_response_string"] = "Script timeout";
183 response["content_type"] = "text/plain";
184 response["keepalive"] = false;
185 response["reusecontext"] = false;
186
187 return response;
188 };
136 } 189 }
137 else 190
191 public void Process()
138 { 192 {
139// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 193 Hashtable response;
140 caps.RegisterHandler("GetTexture", m_URL); 194 Hashtable request = null;
195
196 try
197 {
198 lock (this.requests)
199 {
200 request = requests[0];
201 requests.RemoveAt(0);
202 }
203 }
204 catch
205 {
206 return;
207 }
208
209 UUID requestID = new UUID(request["RequestID"].ToString());
210
211 // If the avatar is gone, don't bother to get the texture
212 if (m_scene.GetScenePresence(Id) == null)
213 {
214 response = new Hashtable();
215
216 response["int_response_code"] = 500;
217 response["str_response_string"] = "Script timeout";
218 response["content_type"] = "text/plain";
219 response["keepalive"] = false;
220 response["reusecontext"] = false;
221
222 responses[requestID] = response;
223 return;
224 }
225
226 response = m_getTextureHandler.Handle(request);
227
228 responses[requestID] = response;
229 }
230 }
231
232 private void RegisterCaps(UUID agentID, Caps caps)
233 {
234 string capUrl = "/CAPS/" + UUID.Random() + "/";
235
236 // Register this as a poll service
237 // absurd large timeout to tune later to make a bit less than viewer
238 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
239
240 args.Type = PollServiceEventArgs.EventType.Texture;
241 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
242
243 string hostName = m_scene.RegionInfo.ExternalHostName;
244 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
245 string protocol = "http";
246
247 if (MainServer.Instance.UseSSL)
248 {
249 hostName = MainServer.Instance.SSLCommonName;
250 port = MainServer.Instance.SSLPort;
251 protocol = "https";
141 } 252 }
253 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
254
255 m_capsDict[agentID] = capUrl;
142 } 256 }
143 257
258 private void DeregisterCaps(UUID agentID, Caps caps)
259 {
260 string capUrl;
261
262 if (m_capsDict.TryGetValue(agentID, out capUrl))
263 {
264 MainServer.Instance.RemoveHTTPHandler("", capUrl);
265 m_capsDict.Remove(agentID);
266 }
267 }
268
269 private void DoTextureRequests()
270 {
271 while (true)
272 {
273 PollServiceTextureEventArgs args = m_queue.Dequeue();
274
275 args.Process();
276 }
277 }
144 } 278 }
279
145} 280}
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 1492302..716cc69 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -256,7 +256,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
256 if (sp.IsChildAgent) 256 if (sp.IsChildAgent)
257 return; 257 return;
258 sp.ControllingClient.Kick(reason); 258 sp.ControllingClient.Kick(reason);
259 sp.Scene.IncomingCloseAgent(sp.UUID); 259 sp.MakeChildAgent();
260 sp.ControllingClient.Close();
260 } 261 }
261 262
262 private void OnIncomingInstantMessage(GridInstantMessage msg) 263 private void OnIncomingInstantMessage(GridInstantMessage msg)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 9090f64..880b2cc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -648,7 +648,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
648 // 648 //
649 // This sleep can be increased if necessary. However, whilst it's active, 649 // This sleep can be increased if necessary. However, whilst it's active,
650 // an agent cannot teleport back to this region if it has teleported away. 650 // an agent cannot teleport back to this region if it has teleported away.
651 Thread.Sleep(2000); 651 Thread.Sleep(3000);
652 652
653 sp.Scene.IncomingCloseAgent(sp.UUID); 653 sp.Scene.IncomingCloseAgent(sp.UUID);
654 } 654 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index d0cab49..70dd1bc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
218 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 218 id, m_mod.Scene.RegionInfo.RegionName, currentState));
219 } 219 }
220 220
221 int count = 200; 221 int count = 400;
222 222
223 // There should be no race condition here since no other code should be removing the agent transfer or 223 // There should be no race condition here since no other code should be removing the agent transfer or
224 // changing the state to another other than Transferring => ReceivedAtDestination. 224 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -266,4 +266,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
266 } 266 }
267 } 267 }
268 } 268 }
269} \ No newline at end of file 269}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0dae946..8034bc6 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4274,7 +4274,7 @@ namespace OpenSim.Region.Framework.Scenes
4274 /// <param name='agentID'></param> 4274 /// <param name='agentID'></param>
4275 protected virtual ScenePresence WaitGetScenePresence(UUID agentID) 4275 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4276 { 4276 {
4277 int ntimes = 20; 4277 int ntimes = 30;
4278 ScenePresence sp = null; 4278 ScenePresence sp = null;
4279 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4279 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4280 Thread.Sleep(1000); 4280 Thread.Sleep(1000);
@@ -4326,7 +4326,7 @@ namespace OpenSim.Region.Framework.Scenes
4326 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4326 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4327 if (presence != null) 4327 if (presence != null)
4328 { 4328 {
4329 presence.ControllingClient.Close(); 4329 presence.ControllingClient.Close(false);
4330 return true; 4330 return true;
4331 } 4331 }
4332 4332
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index fbc6134..61d5a1d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -902,7 +902,7 @@ namespace OpenSim.Region.Physics.OdePlugin
902 axis.X = (axis.X > 0) ? 1f : 0f; 902 axis.X = (axis.X > 0) ? 1f : 0f;
903 axis.Y = (axis.Y > 0) ? 1f : 0f; 903 axis.Y = (axis.Y > 0) ? 1f : 0f;
904 axis.Z = (axis.Z > 0) ? 1f : 0f; 904 axis.Z = (axis.Z > 0) ? 1f : 0f;
905 m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); 905// m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z);
906 AddChange(changes.AngLock, axis); 906 AddChange(changes.AngLock, axis);
907 } 907 }
908 else 908 else
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
index d772c39..0bd8269 100644
--- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
+++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs
@@ -443,7 +443,15 @@ namespace OpenSim.Server.Handlers.Simulation
443 // subclasses can override this 443 // subclasses can override this
444 protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason) 444 protected virtual bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, out string reason)
445 { 445 {
446 return m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out reason); 446 reason = String.Empty;
447
448 Util.FireAndForget(x =>
449 {
450 string r;
451 m_SimulationService.CreateAgent(destination, aCircuit, teleportFlags, out r);
452 });
453
454 return true;
447 } 455 }
448 } 456 }
449 457
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
index 9e04601..9d6d9ad 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
@@ -27,6 +27,7 @@
27 27
28using log4net; 28using log4net;
29using System; 29using System;
30using System.Threading;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.IO; 32using System.IO;
32using System.Reflection; 33using System.Reflection;
@@ -50,7 +51,7 @@ namespace OpenSim.Services.Connectors
50 private IImprovedAssetCache m_Cache = null; 51 private IImprovedAssetCache m_Cache = null;
51 private int m_retryCounter; 52 private int m_retryCounter;
52 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>(); 53 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
53 private Timer m_retryTimer; 54 private System.Timers.Timer m_retryTimer;
54 private delegate void AssetRetrievedEx(AssetBase asset); 55 private delegate void AssetRetrievedEx(AssetBase asset);
55 56
56 // Keeps track of concurrent requests for the same asset, so that it's only loaded once. 57 // Keeps track of concurrent requests for the same asset, so that it's only loaded once.
@@ -61,6 +62,8 @@ namespace OpenSim.Services.Connectors
61 62
62 private Dictionary<string, string> m_UriMap = new Dictionary<string, string>(); 63 private Dictionary<string, string> m_UriMap = new Dictionary<string, string>();
63 64
65 private Thread[] m_fetchThreads;
66
64 public AssetServicesConnector() 67 public AssetServicesConnector()
65 { 68 {
66 } 69 }
@@ -96,7 +99,7 @@ namespace OpenSim.Services.Connectors
96 } 99 }
97 100
98 101
99 m_retryTimer = new Timer(); 102 m_retryTimer = new System.Timers.Timer();
100 m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck); 103 m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
101 m_retryTimer.Interval = 60000; 104 m_retryTimer.Interval = 60000;
102 105
@@ -112,6 +115,14 @@ namespace OpenSim.Services.Connectors
112 m_UriMap[prefix] = groupHost; 115 m_UriMap[prefix] = groupHost;
113 //m_log.DebugFormat("[ASSET]: Using {0} for prefix {1}", groupHost, prefix); 116 //m_log.DebugFormat("[ASSET]: Using {0} for prefix {1}", groupHost, prefix);
114 } 117 }
118
119 m_fetchThreads = new Thread[2];
120
121 for (int i = 0 ; i < 2 ; i++)
122 {
123 m_fetchThreads[i] = new Thread(AssetRequestProcessor);
124 m_fetchThreads[i].Start();
125 }
115 } 126 }
116 127
117 private string MapServer(string id) 128 private string MapServer(string id)
@@ -193,7 +204,7 @@ namespace OpenSim.Services.Connectors
193 if (asset == null || asset.Data == null || asset.Data.Length == 0) 204 if (asset == null || asset.Data == null || asset.Data.Length == 0)
194 { 205 {
195 asset = SynchronousRestObjectRequester. 206 asset = SynchronousRestObjectRequester.
196 MakeRequest<int, AssetBase>("GET", uri, 0); 207 MakeRequest<int, AssetBase>("GET", uri, 0, 30);
197 208
198 if (m_Cache != null) 209 if (m_Cache != null)
199 m_Cache.Cache(asset); 210 m_Cache.Cache(asset);
@@ -261,37 +272,25 @@ namespace OpenSim.Services.Connectors
261 return null; 272 return null;
262 } 273 }
263 274
264 public bool Get(string id, Object sender, AssetRetrieved handler) 275 private class QueuedAssetRequest
265 { 276 {
266 string uri = MapServer(id) + "/assets/" + id; 277 public string uri;
267 278 public string id;
268 AssetBase asset = null; 279 }
269 if (m_Cache != null)
270 asset = m_Cache.Get(id);
271 280
272 if (asset == null || asset.Data == null || asset.Data.Length == 0) 281 private OpenMetaverse.BlockingQueue<QueuedAssetRequest> m_requestQueue =
273 { 282 new OpenMetaverse.BlockingQueue<QueuedAssetRequest>();
274 lock (m_AssetHandlers)
275 {
276 AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
277 283
278// AssetRetrievedEx handlers; 284 private void AssetRequestProcessor()
279 List<AssetRetrievedEx> handlers; 285 {
280 if (m_AssetHandlers.TryGetValue(id, out handlers)) 286 QueuedAssetRequest r;
281 {
282 // Someone else is already loading this asset. It will notify our handler when done.
283// handlers += handlerEx;
284 handlers.Add(handlerEx);
285 return true;
286 }
287 287
288 // Load the asset ourselves 288 while (true)
289// handlers += handlerEx; 289 {
290 handlers = new List<AssetRetrievedEx>(); 290 r = m_requestQueue.Dequeue();
291 handlers.Add(handlerEx);
292 291
293 m_AssetHandlers.Add(id, handlers); 292 string uri = r.uri;
294 } 293 string id = r.id;
295 294
296 bool success = false; 295 bool success = false;
297 try 296 try
@@ -301,16 +300,7 @@ namespace OpenSim.Services.Connectors
301 { 300 {
302 if (m_Cache != null) 301 if (m_Cache != null)
303 m_Cache.Cache(a); 302 m_Cache.Cache(a);
304/*
305 AssetRetrievedEx handlers;
306 lock (m_AssetHandlers)
307 {
308 handlers = m_AssetHandlers[id];
309 m_AssetHandlers.Remove(id);
310 }
311 303
312 handlers.Invoke(a);
313*/
314 List<AssetRetrievedEx> handlers; 304 List<AssetRetrievedEx> handlers;
315 lock (m_AssetHandlers) 305 lock (m_AssetHandlers)
316 { 306 {
@@ -321,7 +311,7 @@ namespace OpenSim.Services.Connectors
321 h.Invoke(a); 311 h.Invoke(a);
322 if (handlers != null) 312 if (handlers != null)
323 handlers.Clear(); 313 handlers.Clear();
324 }); 314 }, 30);
325 315
326 success = true; 316 success = true;
327 } 317 }
@@ -340,6 +330,46 @@ namespace OpenSim.Services.Connectors
340 } 330 }
341 } 331 }
342 } 332 }
333 }
334
335 public bool Get(string id, Object sender, AssetRetrieved handler)
336 {
337 string uri = MapServer(id) + "/assets/" + id;
338
339 AssetBase asset = null;
340 if (m_Cache != null)
341 asset = m_Cache.Get(id);
342
343 if (asset == null || asset.Data == null || asset.Data.Length == 0)
344 {
345 lock (m_AssetHandlers)
346 {
347 AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); });
348
349// AssetRetrievedEx handlers;
350 List<AssetRetrievedEx> handlers;
351 if (m_AssetHandlers.TryGetValue(id, out handlers))
352 {
353 // Someone else is already loading this asset. It will notify our handler when done.
354// handlers += handlerEx;
355 handlers.Add(handlerEx);
356 return true;
357 }
358
359 // Load the asset ourselves
360// handlers += handlerEx;
361 handlers = new List<AssetRetrievedEx>();
362 handlers.Add(handlerEx);
363
364 m_AssetHandlers.Add(id, handlers);
365 }
366
367 QueuedAssetRequest request = new QueuedAssetRequest();
368 request.id = id;
369 request.uri = uri;
370
371 m_requestQueue.Enqueue(request);
372 }
343 else 373 else
344 { 374 {
345 handler(id, sender, asset); 375 handler(id, sender, asset);