aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs194
1 files changed, 115 insertions, 79 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index ddae267..b0d30b6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -176,27 +176,6 @@ namespace OpenSim.Region.ClientStack.Linden
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Always returns a valid queue
180 /// </summary>
181 /// <param name="agentId"></param>
182 /// <returns></returns>
183 private Queue<OSD> TryGetQueue(UUID agentId)
184 {
185 lock (queues)
186 {
187 if (!queues.ContainsKey(agentId))
188 {
189 m_log.DebugFormat(
190 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
191 agentId, m_scene.RegionInfo.RegionName);
192 queues[agentId] = new Queue<OSD>();
193 }
194
195 return queues[agentId];
196 }
197 }
198
199 /// <summary>
200 /// May return a null queue 179 /// May return a null queue
201 /// </summary> 180 /// </summary>
202 /// <param name="agentId"></param> 181 /// <param name="agentId"></param>
@@ -278,47 +257,95 @@ namespace OpenSim.Region.ClientStack.Linden
278 public void OnRegisterCaps(UUID agentID, Caps caps) 257 public void OnRegisterCaps(UUID agentID, Caps caps)
279 { 258 {
280 // Register an event queue for the client 259 // Register an event queue for the client
281
282 m_log.DebugFormat( 260 m_log.DebugFormat(
283 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 261 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
284 agentID, caps, m_scene.RegionInfo.RegionName); 262 agentID, caps, m_scene.RegionInfo.RegionName);
285 263
286 // Let's instantiate a Queue for this agent right now
287 TryGetQueue(agentID);
288
289 UUID eventQueueGetUUID; 264 UUID eventQueueGetUUID;
265 Queue<OSD> queue;
266 Random rnd = new Random(Environment.TickCount);
267 int nrnd = rnd.Next(30000000);
268 if (nrnd < 0)
269 nrnd = -nrnd;
290 270
291 lock (m_AvatarQueueUUIDMapping) 271 lock (queues)
292 { 272 {
293 // Reuse open queues. The client does! 273 if (queues.ContainsKey(agentID))
294 // Its reuse caps path not queues those are been reused already 274 queue = queues[agentID];
295 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 275 else
276 queue = null;
277
278 if (queue == null)
296 { 279 {
297 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 280 queue = new Queue<OSD>();
298 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 281 queues[agentID] = queue;
282
283 // push markers to handle old responses still waiting
284 // this will cost at most viewer getting two forced noevents
285 // even being a new queue better be safe
286 queue.Enqueue(null);
287 queue.Enqueue(null); // one should be enough
288
289 lock (m_AvatarQueueUUIDMapping)
290 {
291 eventQueueGetUUID = UUID.Random();
292 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
293 {
294 // oops this should not happen ?
295 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
296 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
297 }
298 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
299 }
300 lock (m_ids)
301 {
302 if (!m_ids.ContainsKey(agentID))
303 m_ids.Add(agentID, nrnd);
304 else
305 m_ids[agentID] = nrnd;
306 }
299 } 307 }
300 else 308 else
301 { 309 {
302 eventQueueGetUUID = UUID.Random(); 310 // push markers to handle old responses still waiting
303 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); 311 // this will cost at most viewer getting two forced noevents
304 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 312 // even being a new queue better be safe
313 queue.Enqueue(null);
314 queue.Enqueue(null); // one should be enough
315
316 // reuse or not to reuse TODO FIX
317 lock (m_AvatarQueueUUIDMapping)
318 {
319 // Reuse open queues. The client does!
320 // Its reuse caps path not queues those are been reused already
321 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
322 {
323 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
324 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
325 }
326 else
327 {
328 eventQueueGetUUID = UUID.Random();
329 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
330 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
331 }
332 }
333 lock (m_ids)
334 {
335 // change to negative numbers so they are changed at end of sending first marker
336 // old data on a queue may be sent on a response for a new caps
337 // but at least will be sent with coerent IDs
338 if (!m_ids.ContainsKey(agentID))
339 m_ids.Add(agentID, -nrnd); // should not happen
340 else
341 m_ids[agentID] = -m_ids[agentID];
342 }
305 } 343 }
306 } 344 }
307 345
308 caps.RegisterPollHandler( 346 caps.RegisterPollHandler(
309 "EventQueueGet", 347 "EventQueueGet",
310 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); 348 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
311
312 Random rnd = new Random(Environment.TickCount);
313 int nrnd = rnd.Next(30000000);
314
315 lock (m_ids)
316 {
317 if (!m_ids.ContainsKey(agentID))
318 m_ids.Add(agentID, nrnd);
319 else
320 m_ids[agentID] = nrnd;
321 }
322 } 349 }
323 350
324 public bool HasEvents(UUID requestID, UUID agentID) 351 public bool HasEvents(UUID requestID, UUID agentID)
@@ -361,55 +388,65 @@ namespace OpenSim.Region.ClientStack.Linden
361 return NoEvents(requestID, pAgentId); 388 return NoEvents(requestID, pAgentId);
362 } 389 }
363 390
364 OSD element; 391 OSD element = null;;
392 OSDArray array = new OSDArray();
393 int thisID = 0;
394 bool negativeID = false;
395
365 lock (queue) 396 lock (queue)
366 { 397 {
367 if (queue.Count == 0) 398 if (queue.Count == 0)
368 return NoEvents(requestID, pAgentId); 399 return NoEvents(requestID, pAgentId);
369 element = queue.Dequeue(); // 15s timeout
370 }
371
372 int thisID = 0;
373 lock (m_ids)
374 thisID = m_ids[pAgentId];
375
376 OSDArray array = new OSDArray();
377 if (element == null) // didn't have an event in 15s
378 {
379 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
380 array.Add(EventQueueHelper.KeepAliveEvent());
381 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
382 }
383 else
384 {
385 if (DebugLevel > 0)
386 LogOutboundDebugMessage(element, pAgentId);
387 400
388 array.Add(element); 401 lock (m_ids)
402 thisID = m_ids[pAgentId];
389 403
390 lock (queue) 404 if (thisID < 0)
391 { 405 {
392 while (queue.Count > 0) 406 negativeID = true;
393 { 407 thisID = -thisID;
394 element = queue.Dequeue(); 408 }
409
410 while (queue.Count > 0)
411 {
412 element = queue.Dequeue();
413 // add elements until a marker is found
414 // so they get into a response
415 if (element == null)
416 break;
417 if (DebugLevel > 0)
418 LogOutboundDebugMessage(element, pAgentId);
419 array.Add(element);
420 thisID++;
421 }
422 }
395 423
396 if (DebugLevel > 0) 424 OSDMap events = null;
397 LogOutboundDebugMessage(element, pAgentId);
398 425
399 array.Add(element); 426 if (array.Count > 0)
400 thisID++; 427 {
401 } 428 events = new OSDMap();
402 } 429 events.Add("events", array);
430 events.Add("id", new OSDInteger(thisID));
403 } 431 }
404 432
405 OSDMap events = new OSDMap(); 433 if (negativeID && element == null)
406 events.Add("events", array); 434 {
435 Random rnd = new Random(Environment.TickCount);
436 thisID = rnd.Next(30000000);
437 if (thisID < 0)
438 thisID = -thisID;
439 }
407 440
408 events.Add("id", new OSDInteger(thisID));
409 lock (m_ids) 441 lock (m_ids)
410 { 442 {
411 m_ids[pAgentId] = thisID + 1; 443 m_ids[pAgentId] = thisID + 1;
412 } 444 }
445
446 // if there where no elements before a marker send a NoEvents
447 if (array.Count == 0)
448 return NoEvents(requestID, pAgentId);
449
413 Hashtable responsedata = new Hashtable(); 450 Hashtable responsedata = new Hashtable();
414 responsedata["int_response_code"] = 200; 451 responsedata["int_response_code"] = 200;
415 responsedata["content_type"] = "application/xml"; 452 responsedata["content_type"] = "application/xml";
@@ -432,7 +469,6 @@ namespace OpenSim.Region.ClientStack.Linden
432 responsedata["http_protocol_version"] = "HTTP/1.0"; 469 responsedata["http_protocol_version"] = "HTTP/1.0";
433 return responsedata; 470 return responsedata;
434 } 471 }
435
436 472
437 public void DisableSimulator(ulong handle, UUID avatarID) 473 public void DisableSimulator(ulong handle, UUID avatarID)
438 { 474 {