diff options
Merge branch 'master' of git://opensimulator.org/git/opensim
Diffstat (limited to 'OpenSim')
10 files changed, 188 insertions, 114 deletions
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index aef1192..3e90fac 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs | |||
@@ -76,9 +76,10 @@ namespace OpenSim.Framework | |||
76 | { | 76 | { |
77 | lock (m_queueSync) | 77 | lock (m_queueSync) |
78 | { | 78 | { |
79 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | 79 | bool success = true; |
80 | while (m_queue.Count < 1 && m_pqueue.Count < 1 && success) | ||
80 | { | 81 | { |
81 | Monitor.Wait(m_queueSync, msTimeout); | 82 | success = Monitor.Wait(m_queueSync, msTimeout); |
82 | } | 83 | } |
83 | 84 | ||
84 | if (m_pqueue.Count > 0) | 85 | if (m_pqueue.Count > 0) |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 020bfd5..9477100 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs | |||
@@ -50,7 +50,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
50 | 50 | ||
51 | public enum EventType : int | 51 | public enum EventType : int |
52 | { | 52 | { |
53 | Normal = 0, | 53 | LongPoll = 0, |
54 | LslHttp = 1, | 54 | LslHttp = 1, |
55 | Inventory = 2 | 55 | Inventory = 2 |
56 | } | 56 | } |
@@ -80,7 +80,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
80 | NoEvents = pNoEvents; | 80 | NoEvents = pNoEvents; |
81 | Id = pId; | 81 | Id = pId; |
82 | TimeOutms = pTimeOutms; | 82 | TimeOutms = pTimeOutms; |
83 | Type = EventType.Normal; | 83 | Type = EventType.LongPoll; |
84 | } | 84 | } |
85 | } | 85 | } |
86 | } | 86 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 1b9010a..b8f5743 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -47,12 +47,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
47 | private readonly BaseHttpServer m_server; | 47 | private readonly BaseHttpServer m_server; |
48 | 48 | ||
49 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); | 49 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); |
50 | private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); | 50 | private static Queue<PollServiceHttpRequest> m_longPollRequests = new Queue<PollServiceHttpRequest>(); |
51 | private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); | ||
52 | 51 | ||
53 | private uint m_WorkerThreadCount = 0; | 52 | private uint m_WorkerThreadCount = 0; |
54 | private Thread[] m_workerThreads; | 53 | private Thread[] m_workerThreads; |
55 | private Thread m_retrysThread; | 54 | private Thread m_longPollThread; |
56 | 55 | ||
57 | private bool m_running = true; | 56 | private bool m_running = true; |
58 | private int slowCount = 0; | 57 | private int slowCount = 0; |
@@ -84,9 +83,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
84 | int.MaxValue); | 83 | int.MaxValue); |
85 | } | 84 | } |
86 | 85 | ||
87 | m_retrysThread = Watchdog.StartThread( | 86 | m_longPollThread = Watchdog.StartThread( |
88 | this.CheckRetries, | 87 | this.CheckLongPollThreads, |
89 | string.Format("PollServiceWatcherThread:{0}", m_server.Port), | 88 | string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), |
90 | ThreadPriority.Normal, | 89 | ThreadPriority.Normal, |
91 | false, | 90 | false, |
92 | true, | 91 | true, |
@@ -97,49 +96,52 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
97 | private void ReQueueEvent(PollServiceHttpRequest req) | 96 | private void ReQueueEvent(PollServiceHttpRequest req) |
98 | { | 97 | { |
99 | if (m_running) | 98 | if (m_running) |
100 | { | 99 | m_requests.Enqueue(req); |
101 | lock (m_retryRequests) | ||
102 | m_retryRequests.Enqueue(req); | ||
103 | } | ||
104 | } | 100 | } |
105 | 101 | ||
106 | public void Enqueue(PollServiceHttpRequest req) | 102 | public void Enqueue(PollServiceHttpRequest req) |
107 | { | 103 | { |
108 | if (m_running) | 104 | if (m_running) |
109 | { | 105 | { |
110 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal) | 106 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) |
111 | { | 107 | { |
112 | m_requests.Enqueue(req); | 108 | lock (m_longPollRequests) |
109 | m_longPollRequests.Enqueue(req); | ||
113 | } | 110 | } |
114 | else | 111 | else |
115 | { | 112 | m_requests.Enqueue(req); |
116 | lock (m_slowRequests) | ||
117 | m_slowRequests.Enqueue(req); | ||
118 | } | ||
119 | } | 113 | } |
120 | } | 114 | } |
121 | 115 | ||
122 | private void CheckRetries() | 116 | private void CheckLongPollThreads() |
123 | { | 117 | { |
118 | // The only purpose of this thread is to check the EQs for events. | ||
119 | // If there are events, that thread will be placed in the "ready-to-serve" queue, m_requests. | ||
120 | // If there are no events, that thread will be back to its "waiting" queue, m_longPollRequests. | ||
121 | // All other types of tasks (Inventory handlers) don't have the long-poll nature, | ||
122 | // so if they aren't ready to be served by a worker thread (no events), they are placed | ||
123 | // directly back in the "ready-to-serve" queue by the worker thread. | ||
124 | while (m_running) | 124 | while (m_running) |
125 | { | 125 | { |
126 | Thread.Sleep(100); // let the world move .. back to faster rate | 126 | Thread.Sleep(1000); |
127 | Watchdog.UpdateThread(); | 127 | Watchdog.UpdateThread(); |
128 | lock (m_retryRequests) | ||
129 | { | ||
130 | while (m_retryRequests.Count > 0 && m_running) | ||
131 | m_requests.Enqueue(m_retryRequests.Dequeue()); | ||
132 | } | ||
133 | slowCount++; | ||
134 | if (slowCount >= 10) | ||
135 | { | ||
136 | slowCount = 0; | ||
137 | 128 | ||
138 | lock (m_slowRequests) | 129 | List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>(); |
130 | lock (m_longPollRequests) | ||
131 | { | ||
132 | while (m_longPollRequests.Count > 0 && m_running) | ||
139 | { | 133 | { |
140 | while (m_slowRequests.Count > 0 && m_running) | 134 | PollServiceHttpRequest req = m_longPollRequests.Dequeue(); |
141 | m_requests.Enqueue(m_slowRequests.Dequeue()); | 135 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ |
136 | (Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) // no events, but timeout | ||
137 | m_requests.Enqueue(req); | ||
138 | else | ||
139 | not_ready.Add(req); | ||
142 | } | 140 | } |
141 | |||
142 | foreach (PollServiceHttpRequest req in not_ready) | ||
143 | m_longPollRequests.Enqueue(req); | ||
144 | |||
143 | } | 145 | } |
144 | } | 146 | } |
145 | } | 147 | } |
@@ -153,24 +155,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
153 | foreach (Thread t in m_workerThreads) | 155 | foreach (Thread t in m_workerThreads) |
154 | Watchdog.AbortThread(t.ManagedThreadId); | 156 | Watchdog.AbortThread(t.ManagedThreadId); |
155 | 157 | ||
156 | try | ||
157 | { | ||
158 | foreach (PollServiceHttpRequest req in m_retryRequests) | ||
159 | { | ||
160 | req.DoHTTPGruntWork(m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
161 | } | ||
162 | } | ||
163 | catch | ||
164 | { | ||
165 | } | ||
166 | |||
167 | PollServiceHttpRequest wreq; | 158 | PollServiceHttpRequest wreq; |
168 | m_retryRequests.Clear(); | ||
169 | 159 | ||
170 | lock (m_slowRequests) | 160 | lock (m_longPollRequests) |
171 | { | 161 | { |
172 | while (m_slowRequests.Count > 0 && m_running) | 162 | while (m_longPollRequests.Count > 0 && m_running) |
173 | m_requests.Enqueue(m_slowRequests.Dequeue()); | 163 | m_requests.Enqueue(m_longPollRequests.Dequeue()); |
174 | } | 164 | } |
175 | 165 | ||
176 | while (m_requests.Count() > 0) | 166 | while (m_requests.Count() > 0) |
@@ -195,34 +185,33 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
195 | { | 185 | { |
196 | while (m_running) | 186 | while (m_running) |
197 | { | 187 | { |
198 | PollServiceHttpRequest req = m_requests.Dequeue(5000); | ||
199 | |||
200 | Watchdog.UpdateThread(); | 188 | Watchdog.UpdateThread(); |
201 | if (req != null) | 189 | |
190 | PollServiceHttpRequest req = null; | ||
191 | lock (m_requests) | ||
192 | { | ||
193 | if (m_requests.Count() > 0) | ||
194 | req = m_requests.Dequeue(); | ||
195 | } | ||
196 | if (req == null) | ||
197 | Thread.Sleep(100); | ||
198 | else | ||
202 | { | 199 | { |
203 | try | 200 | //PollServiceHttpRequest req = m_requests.Dequeue(5000); |
201 | //m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString())); | ||
202 | |||
203 | if (req != null) | ||
204 | { | 204 | { |
205 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) | 205 | try |
206 | { | 206 | { |
207 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); | 207 | if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) |
208 | { | ||
209 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); | ||
208 | 210 | ||
209 | if (responsedata == null) | 211 | if (responsedata == null) |
210 | continue; | 212 | continue; |
211 | 213 | ||
212 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue | 214 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue |
213 | { | ||
214 | try | ||
215 | { | ||
216 | req.DoHTTPGruntWork(m_server, responsedata); | ||
217 | } | ||
218 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | ||
219 | { | ||
220 | // Ignore it, no need to reply | ||
221 | } | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | m_threadPool.QueueWorkItem(x => | ||
226 | { | 215 | { |
227 | try | 216 | try |
228 | { | 217 | { |
@@ -232,27 +221,41 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
232 | { | 221 | { |
233 | // Ignore it, no need to reply | 222 | // Ignore it, no need to reply |
234 | } | 223 | } |
224 | } | ||
225 | else | ||
226 | { | ||
227 | m_threadPool.QueueWorkItem(x => | ||
228 | { | ||
229 | try | ||
230 | { | ||
231 | req.DoHTTPGruntWork(m_server, responsedata); | ||
232 | } | ||
233 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | ||
234 | { | ||
235 | // Ignore it, no need to reply | ||
236 | } | ||
235 | 237 | ||
236 | return null; | 238 | return null; |
237 | }, null); | 239 | }, null); |
238 | } | 240 | } |
239 | } | ||
240 | else | ||
241 | { | ||
242 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) | ||
243 | { | ||
244 | req.DoHTTPGruntWork( | ||
245 | m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
246 | } | 241 | } |
247 | else | 242 | else |
248 | { | 243 | { |
249 | ReQueueEvent(req); | 244 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) |
245 | { | ||
246 | req.DoHTTPGruntWork( | ||
247 | m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | ReQueueEvent(req); | ||
252 | } | ||
250 | } | 253 | } |
251 | } | 254 | } |
252 | } | 255 | catch (Exception e) |
253 | catch (Exception e) | 256 | { |
254 | { | 257 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); |
255 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); | 258 | } |
256 | } | 259 | } |
257 | } | 260 | } |
258 | } | 261 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 1835a72..f0445ff 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -364,8 +364,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
364 | 364 | ||
365 | caps.RegisterPollHandler( | 365 | caps.RegisterPollHandler( |
366 | "EventQueueGet", | 366 | "EventQueueGet", |
367 | new PollServiceEventArgs( | 367 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, 40000)); |
368 | null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, 40000)); | ||
369 | 368 | ||
370 | Random rnd = new Random(Environment.TickCount); | 369 | Random rnd = new Random(Environment.TickCount); |
371 | lock (m_ids) | 370 | lock (m_ids) |
@@ -383,7 +382,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
383 | Queue<OSD> queue = GetQueue(agentID); | 382 | Queue<OSD> queue = GetQueue(agentID); |
384 | if (queue != null) | 383 | if (queue != null) |
385 | lock (queue) | 384 | lock (queue) |
385 | { | ||
386 | //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count); | ||
386 | return queue.Count > 0; | 387 | return queue.Count > 0; |
388 | } | ||
387 | 389 | ||
388 | return false; | 390 | return false; |
389 | } | 391 | } |
@@ -406,7 +408,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
406 | public Hashtable GetEvents(UUID requestID, UUID pAgentId) | 408 | public Hashtable GetEvents(UUID requestID, UUID pAgentId) |
407 | { | 409 | { |
408 | if (DebugLevel >= 2) | 410 | if (DebugLevel >= 2) |
409 | m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); | 411 | m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); |
410 | 412 | ||
411 | Queue<OSD> queue = TryGetQueue(pAgentId); | 413 | Queue<OSD> queue = TryGetQueue(pAgentId); |
412 | OSD element; | 414 | OSD element; |
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs index 553e4ca..a70261e 100644 --- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs | |||
@@ -50,15 +50,16 @@ namespace OpenSim.Region.CoreModules.Framework | |||
50 | private readonly List<Scene> m_scenes = new List<Scene>(); | 50 | private readonly List<Scene> m_scenes = new List<Scene>(); |
51 | private System.Timers.Timer m_timer = new System.Timers.Timer(); | 51 | private System.Timers.Timer m_timer = new System.Timers.Timer(); |
52 | 52 | ||
53 | //private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>(); | ||
54 | // private OpenSim.Framework.DoubleQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.DoubleQueue<GridRegionRequest>(); | ||
55 | //private Queue<GridRegionRequest> m_RequestQueue = new Queue<GridRegionRequest>(); | ||
56 | private Queue<Action> m_RequestQueue = new Queue<Action>(); | 53 | private Queue<Action> m_RequestQueue = new Queue<Action>(); |
54 | private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>(); | ||
55 | private int m_Interval; | ||
57 | 56 | ||
58 | #region ISharedRegionModule | 57 | #region ISharedRegionModule |
59 | 58 | ||
60 | public void Initialise(IConfigSource config) | 59 | public void Initialise(IConfigSource config) |
61 | { | 60 | { |
61 | m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000); | ||
62 | |||
62 | m_timer = new System.Timers.Timer(); | 63 | m_timer = new System.Timers.Timer(); |
63 | m_timer.AutoReset = false; | 64 | m_timer.AutoReset = false; |
64 | m_timer.Enabled = true; | 65 | m_timer.Enabled = true; |
@@ -131,7 +132,7 @@ namespace OpenSim.Region.CoreModules.Framework | |||
131 | { | 132 | { |
132 | if (!m_timer.Enabled) | 133 | if (!m_timer.Enabled) |
133 | { | 134 | { |
134 | m_timer.Interval = 1000; | 135 | m_timer.Interval = m_Interval; |
135 | m_timer.Enabled = true; | 136 | m_timer.Enabled = true; |
136 | m_timer.Start(); | 137 | m_timer.Start(); |
137 | } | 138 | } |
@@ -156,18 +157,36 @@ namespace OpenSim.Region.CoreModules.Framework | |||
156 | client.SendRegionHandle(regionID, r.RegionHandle); | 157 | client.SendRegionHandle(regionID, r.RegionHandle); |
157 | }; | 158 | }; |
158 | 159 | ||
159 | lock (m_RequestQueue) | 160 | Enqueue("region", regionID.ToString(), action); |
160 | m_RequestQueue.Enqueue(action); | ||
161 | |||
162 | } | 161 | } |
163 | 162 | ||
164 | #endregion Events | 163 | #endregion Events |
165 | 164 | ||
166 | #region IServiceThrottleModule | 165 | #region IServiceThrottleModule |
167 | 166 | ||
168 | public void Enqueue(Action continuation) | 167 | public void Enqueue(string category, string itemid, Action continuation) |
169 | { | 168 | { |
170 | m_RequestQueue.Enqueue(continuation); | 169 | lock (m_RequestQueue) |
170 | { | ||
171 | if (m_Pending.ContainsKey(category)) | ||
172 | { | ||
173 | if (m_Pending[category].Contains(itemid)) | ||
174 | // Don't enqueue, it's already pending | ||
175 | return; | ||
176 | } | ||
177 | else | ||
178 | m_Pending.Add(category, new List<string>()); | ||
179 | |||
180 | m_Pending[category].Add(itemid); | ||
181 | |||
182 | m_RequestQueue.Enqueue(delegate | ||
183 | { | ||
184 | lock (m_RequestQueue) | ||
185 | m_Pending[category].Remove(itemid); | ||
186 | |||
187 | continuation(); | ||
188 | }); | ||
189 | } | ||
171 | } | 190 | } |
172 | 191 | ||
173 | #endregion IServiceThrottleModule | 192 | #endregion IServiceThrottleModule |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index da28a53..a91adfa 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -172,11 +172,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
172 | return; | 172 | return; |
173 | } | 173 | } |
174 | 174 | ||
175 | // Not found in cache, get it from services | 175 | // Not found in cache, queue continuation |
176 | m_ServiceThrottle.Enqueue(delegate | 176 | m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate |
177 | { | 177 | { |
178 | //m_log.DebugFormat("[YYY]: Name request {0}", uuid); | 178 | //m_log.DebugFormat("[YYY]: Name request {0}", uuid); |
179 | bool foundRealName = TryGetUserNamesFromServices(uuid, names); | 179 | bool foundRealName = TryGetUserNames(uuid, names); |
180 | 180 | ||
181 | if (names.Length == 2) | 181 | if (names.Length == 2) |
182 | { | 182 | { |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index c50ab64..a26a5f0 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -81,6 +81,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
81 | private List<UUID> m_rootAgents = new List<UUID>(); | 81 | private List<UUID> m_rootAgents = new List<UUID>(); |
82 | private volatile bool threadrunning = false; | 82 | private volatile bool threadrunning = false; |
83 | 83 | ||
84 | private IServiceThrottleModule m_ServiceThrottle; | ||
85 | |||
84 | //private int CacheRegionsDistance = 256; | 86 | //private int CacheRegionsDistance = 256; |
85 | 87 | ||
86 | #region INonSharedRegionModule Members | 88 | #region INonSharedRegionModule Members |
@@ -131,6 +133,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
131 | 133 | ||
132 | public virtual void RegionLoaded (Scene scene) | 134 | public virtual void RegionLoaded (Scene scene) |
133 | { | 135 | { |
136 | if (!m_Enabled) | ||
137 | return; | ||
138 | |||
139 | m_ServiceThrottle = scene.RequestModuleInterface<IServiceThrottleModule>(); | ||
134 | } | 140 | } |
135 | 141 | ||
136 | 142 | ||
@@ -170,13 +176,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
170 | m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; | 176 | m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; |
171 | m_scene.EventManager.OnRegionUp += OnRegionUp; | 177 | m_scene.EventManager.OnRegionUp += OnRegionUp; |
172 | 178 | ||
173 | StartThread(new object()); | 179 | // StartThread(new object()); |
174 | } | 180 | } |
175 | 181 | ||
176 | // this has to be called with a lock on m_scene | 182 | // this has to be called with a lock on m_scene |
177 | protected virtual void RemoveHandlers() | 183 | protected virtual void RemoveHandlers() |
178 | { | 184 | { |
179 | StopThread(); | 185 | // StopThread(); |
180 | 186 | ||
181 | m_scene.EventManager.OnRegionUp -= OnRegionUp; | 187 | m_scene.EventManager.OnRegionUp -= OnRegionUp; |
182 | m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; | 188 | m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; |
@@ -526,7 +532,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
526 | /// </summary> | 532 | /// </summary> |
527 | public void process() | 533 | public void process() |
528 | { | 534 | { |
529 | const int MAX_ASYNC_REQUESTS = 20; | 535 | //const int MAX_ASYNC_REQUESTS = 20; |
530 | try | 536 | try |
531 | { | 537 | { |
532 | while (true) | 538 | while (true) |
@@ -571,13 +577,44 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
571 | Watchdog.RemoveThread(); | 577 | Watchdog.RemoveThread(); |
572 | } | 578 | } |
573 | 579 | ||
580 | const int MAX_ASYNC_REQUESTS = 20; | ||
581 | |||
574 | /// <summary> | 582 | /// <summary> |
575 | /// Enqueues the map item request into the processing thread | 583 | /// Enqueues the map item request into the services throttle processing thread |
576 | /// </summary> | 584 | /// </summary> |
577 | /// <param name="state"></param> | 585 | /// <param name="state"></param> |
578 | public void EnqueueMapItemRequest(MapRequestState state) | 586 | public void EnqueueMapItemRequest(MapRequestState st) |
579 | { | 587 | { |
580 | requests.Enqueue(state); | 588 | |
589 | m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate | ||
590 | { | ||
591 | if (st.agentID != UUID.Zero) | ||
592 | { | ||
593 | bool dorequest = true; | ||
594 | lock (m_rootAgents) | ||
595 | { | ||
596 | if (!m_rootAgents.Contains(st.agentID)) | ||
597 | dorequest = false; | ||
598 | } | ||
599 | |||
600 | if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) | ||
601 | { | ||
602 | if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break | ||
603 | { | ||
604 | // AH!!! Recursive ! | ||
605 | // Put this request back in the queue and return | ||
606 | EnqueueMapItemRequest(st); | ||
607 | return; | ||
608 | } | ||
609 | |||
610 | RequestMapItemsDelegate d = RequestMapItemsAsync; | ||
611 | d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null); | ||
612 | //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle); | ||
613 | //RequestMapItemsCompleted(response); | ||
614 | Interlocked.Increment(ref nAsyncRequests); | ||
615 | } | ||
616 | } | ||
617 | }); | ||
581 | } | 618 | } |
582 | 619 | ||
583 | /// <summary> | 620 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs index bb6a8b4..198256f 100644 --- a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs | |||
@@ -5,7 +5,15 @@ namespace OpenSim.Region.Framework.Interfaces | |||
5 | { | 5 | { |
6 | public interface IServiceThrottleModule | 6 | public interface IServiceThrottleModule |
7 | { | 7 | { |
8 | void Enqueue(Action continuation); | 8 | /// <summary> |
9 | /// Enqueue a continuation meant to get a resource from elsewhere. | ||
10 | /// As usual with CPS, caller beware: if that continuation is a never-ending computation, | ||
11 | /// the whole thread will be blocked, and no requests are processed | ||
12 | /// </summary> | ||
13 | /// <param name="category">Category of the resource (e.g. name, region)</param> | ||
14 | /// <param name="itemid">The resource identifier</param> | ||
15 | /// <param name="continuation">The continuation to be executed</param> | ||
16 | void Enqueue(string category, string itemid, Action continuation); | ||
9 | } | 17 | } |
10 | 18 | ||
11 | } | 19 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index a41eaf8..fc4545f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -103,9 +103,10 @@ public abstract class BSPhysObject : PhysicsActor | |||
103 | CollisionsLastTickStep = -1; | 103 | CollisionsLastTickStep = -1; |
104 | 104 | ||
105 | SubscribedEventsMs = 0; | 105 | SubscribedEventsMs = 0; |
106 | CollidingStep = 0; | 106 | // Crazy values that will never be true |
107 | CollidingGroundStep = 0; | 107 | CollidingStep = BSScene.NotASimulationStep; |
108 | CollisionAccumulation = 0; | 108 | CollidingGroundStep = BSScene.NotASimulationStep; |
109 | CollisionAccumulation = BSScene.NotASimulationStep; | ||
109 | ColliderIsMoving = false; | 110 | ColliderIsMoving = false; |
110 | CollisionScore = 0; | 111 | CollisionScore = 0; |
111 | 112 | ||
@@ -349,7 +350,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
349 | if (value) | 350 | if (value) |
350 | CollidingStep = PhysScene.SimulationStep; | 351 | CollidingStep = PhysScene.SimulationStep; |
351 | else | 352 | else |
352 | CollidingStep = 0; | 353 | CollidingStep = BSScene.NotASimulationStep; |
353 | } | 354 | } |
354 | } | 355 | } |
355 | public override bool CollidingGround { | 356 | public override bool CollidingGround { |
@@ -359,7 +360,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
359 | if (value) | 360 | if (value) |
360 | CollidingGroundStep = PhysScene.SimulationStep; | 361 | CollidingGroundStep = PhysScene.SimulationStep; |
361 | else | 362 | else |
362 | CollidingGroundStep = 0; | 363 | CollidingGroundStep = BSScene.NotASimulationStep; |
363 | } | 364 | } |
364 | } | 365 | } |
365 | public override bool CollidingObj { | 366 | public override bool CollidingObj { |
@@ -368,7 +369,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
368 | if (value) | 369 | if (value) |
369 | CollidingObjectStep = PhysScene.SimulationStep; | 370 | CollidingObjectStep = PhysScene.SimulationStep; |
370 | else | 371 | else |
371 | CollidingObjectStep = 0; | 372 | CollidingObjectStep = BSScene.NotASimulationStep; |
372 | } | 373 | } |
373 | } | 374 | } |
374 | 375 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 214271b..41aca3b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -97,6 +97,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
97 | 97 | ||
98 | internal long m_simulationStep = 0; // The current simulation step. | 98 | internal long m_simulationStep = 0; // The current simulation step. |
99 | public long SimulationStep { get { return m_simulationStep; } } | 99 | public long SimulationStep { get { return m_simulationStep; } } |
100 | // A number to use for SimulationStep that is probably not any step value | ||
101 | // Used by the collision code (which remembers the step when a collision happens) to remember not any simulation step. | ||
102 | public static long NotASimulationStep = -1234; | ||
100 | 103 | ||
101 | internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate() | 104 | internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate() |
102 | 105 | ||