aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-05-06 19:53:35 +0100
committerJustin Clark-Casey (justincc)2014-05-06 19:53:35 +0100
commite44450cce1cd3a9077aec5514a1b9e65b8cffa0a (patch)
tree59f00f155e2f445b27623d8dcff81586ce7e2151 /OpenSim/Region/CoreModules
parentConsole commands for Estate Mgmt (diff)
downloadopensim-SC-e44450cce1cd3a9077aec5514a1b9e65b8cffa0a.zip
opensim-SC-e44450cce1cd3a9077aec5514a1b9e65b8cffa0a.tar.gz
opensim-SC-e44450cce1cd3a9077aec5514a1b9e65b8cffa0a.tar.bz2
opensim-SC-e44450cce1cd3a9077aec5514a1b9e65b8cffa0a.tar.xz
Revert "fix infinite recursion loop in SendGridInstantMessageViaXMLRPCAsync()"
There is a problem here with infinite recursion, but this patch loses the 'hunting' behaviour where the code will attempt multiple lookups if the avatar is teleporting rapidly around different simulators. This patch only does a single lookup before giving up. This reverts commit cecb446e0e91ede0b05ea9cf40c1313782241f3d.
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs178
1 files changed, 99 insertions, 79 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 4f8e2cd..40a400f 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
428 /// <summary> 428 /// <summary>
429 /// delegate for sending a grid instant message asynchronously 429 /// delegate for sending a grid instant message asynchronously
430 /// </summary> 430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); 431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
432 432
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
434 { 434 {
@@ -442,118 +442,138 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
442 { 442 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
444 444
445 d.BeginInvoke(im, result, GridInstantMessageCompleted, d); 445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
446 } 446 }
447 447
448 /// <summary> 448 /// <summary>
449 /// Internal SendGridInstantMessage over XMLRPC method. 449 /// Recursive SendGridInstantMessage over XMLRPC method.
450 /// This is called from within a dedicated thread. 450 /// This is called from within a dedicated thread.
451 /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from
452 /// itself, prevRegionHandle will be the last region handle that we tried to send.
453 /// If the handles are the same, we look up the user's location using the grid.
454 /// If the handles are still the same, we end. The send failed.
451 /// </summary> 455 /// </summary>
452 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result) 456 /// <param name="prevRegionHandle">
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried
459 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
453 { 461 {
454 UUID toAgentID = new UUID(im.toAgentID); 462 UUID toAgentID = new UUID(im.toAgentID);
455 UUID regionID;
456 bool lookupAgent;
457 463
458 /* 464 PresenceInfo upd = null;
459 * Try to get what region the agent is in from the cache. 465
460 */ 466 bool lookupAgent = false;
467
461 lock (m_UserRegionMap) 468 lock (m_UserRegionMap)
462 { 469 {
463 lookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID); 470 if (m_UserRegionMap.ContainsKey(toAgentID))
471 {
472 upd = new PresenceInfo();
473 upd.RegionID = m_UserRegionMap[toAgentID];
474
475 // We need to compare the current regionhandle with the previous region handle
476 // or the recursive loop will never end because it will never try to lookup the agent again
477 if (prevRegionID == upd.RegionID)
478 {
479 lookupAgent = true;
480 }
481 }
482 else
483 {
484 lookupAgent = true;
485 }
464 } 486 }
487
465 488
466 while (true) 489 // Are we needing to look-up an agent?
490 if (lookupAgent)
467 { 491 {
468 492 // Non-cached user agent lookup.
469 /* 493 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
470 * If not in cache, try to find out what region the agent is in. 494 if (presences != null && presences.Length > 0)
471 * Also do this if we know the existing cache entry is bad.
472 */
473 if (lookupAgent)
474 { 495 {
475 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 496 foreach (PresenceInfo p in presences)
476
477 regionID = UUID.Zero;
478 if (presences != null)
479 { 497 {
480 foreach (PresenceInfo p in presences) 498 if (p.RegionID != UUID.Zero)
481 { 499 {
482 if (p.RegionID != UUID.Zero) 500 upd = p;
483 { 501 break;
484 regionID = p.RegionID;
485 break;
486 }
487 } 502 }
488 } 503 }
504 }
489 505
490 // If not found, message is undeliverable 506 if (upd != null)
491 if (regionID == UUID.Zero) 507 {
508 // check if we've tried this before..
509 // This is one way to end the recursive loop
510 //
511 if (upd.RegionID == prevRegionID)
492 { 512 {
493 break; 513 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
514 HandleUndeliveredMessage(im, result);
515 return;
494 } 516 }
495 } 517 }
496 518 else
497 /*
498 * Try to find out about region.
499 * If unable, message is undeliverable.
500 */
501 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
502 if (reginfo == null)
503 { 519 {
504 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID); 520 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
505 break; 521 HandleUndeliveredMessage(im, result);
522 return;
506 } 523 }
524 }
507 525
508 /* 526 if (upd != null)
509 * Try to send message to agent in the region. 527 {
510 */ 528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
511 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); 529 upd.RegionID);
512 msgdata["region_handle"] = 0; 530 if (reginfo != null)
513 bool imresult = doIMSending(reginfo, msgdata);
514
515 /*
516 * If message delivery successful, save cache entry because we know it is good.
517 * Then tell caller message has been delivered and we are done.
518 */
519 if (imresult)
520 { 531 {
521 lock (m_UserRegionMap) 532 Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
533 // Not actually used anymore, left in for compatibility
534 // Remove at next interface change
535 //
536 msgdata["region_handle"] = 0;
537 bool imresult = doIMSending(reginfo, msgdata);
538 if (imresult)
539 {
540 // IM delivery successful, so store the Agent's location in our local cache.
541 lock (m_UserRegionMap)
542 {
543 if (m_UserRegionMap.ContainsKey(toAgentID))
544 {
545 m_UserRegionMap[toAgentID] = upd.RegionID;
546 }
547 else
548 {
549 m_UserRegionMap.Add(toAgentID, upd.RegionID);
550 }
551 }
552 result(true);
553 }
554 else
522 { 555 {
523 m_UserRegionMap[toAgentID] = regionID; 556 // try again, but lookup user this time.
557 // Warning, this must call the Async version
558 // of this method or we'll be making thousands of threads
559 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
560 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
561
562 // This is recursive!!!!!
563 SendGridInstantMessageViaXMLRPCAsync(im, result,
564 upd.RegionID);
524 } 565 }
525 result(true);
526 return;
527 } 566 }
528 567 else
529 /*
530 * Message delivery failed.
531 * If we just looked up what region the agent is in, message is undeliverable.
532 */
533 if (lookupAgent)
534 { 568 {
535 break; 569 m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
570 HandleUndeliveredMessage(im, result);
536 } 571 }
537
538 /*
539 * We used a cached entry that we now know is bad.
540 * Try again by searching the grid for the user.
541 */
542 lookupAgent = true;
543 } 572 }
544 573 else
545 /*
546 * Message is undeliverable for one reason or another.
547 * Remove possible bad entry from cache.
548 * Then inform caller that the message is undeliverable.
549 */
550 lock (m_UserRegionMap)
551 { 574 {
552 m_UserRegionMap.Remove(toAgentID); 575 HandleUndeliveredMessage(im, result);
553 } 576 }
554
555 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
556 HandleUndeliveredMessage(im, result);
557 } 577 }
558 578
559 /// <summary> 579 /// <summary>