aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authordiva2009-04-18 16:37:05 +0000
committerdiva2009-04-18 16:37:05 +0000
commit8e08dd20dc9fe785874943c7986f82af60ed1879 (patch)
treee73717f3a5c416514acb6bd363aad9a206a66360
parentAddresses mantis #3485. (diff)
downloadopensim-SC-8e08dd20dc9fe785874943c7986f82af60ed1879.zip
opensim-SC-8e08dd20dc9fe785874943c7986f82af60ed1879.tar.gz
opensim-SC-8e08dd20dc9fe785874943c7986f82af60ed1879.tar.bz2
opensim-SC-8e08dd20dc9fe785874943c7986f82af60ed1879.tar.xz
Thank you dslake for diagnosing and fixing a race condition in OGS1SecureInventoryServer (mantis #3483). The provided patch was slightly modified to narrow the locking scope to smaller portions of the functions. Applied the same locking to HGInventoryService, which suffered from the same race condition.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs156
-rw-r--r--OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs122
2 files changed, 146 insertions, 132 deletions
diff --git a/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs
index 156137e..98f5f68 100644
--- a/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs
+++ b/OpenSim/Region/Communications/Hypergrid/HGInventoryService.cs
@@ -77,52 +77,54 @@ namespace OpenSim.Region.Communications.Hypergrid
77 } 77 }
78 78
79 // grid/hypergrid mode 79 // grid/hypergrid mode
80 if (!m_RequestingInventory.ContainsKey(userID)) 80 lock (m_RequestingInventory)
81 { 81 {
82 m_RequestingInventory.Add(userID, callback); 82 if (!m_RequestingInventory.ContainsKey(userID))
83
84 string invServer = GetUserInventoryURI(userID);
85 m_log.InfoFormat(
86 "[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
87 /*_inventoryServerUrl*/ invServer, userID, userID.Guid);
88
89 try
90 { 83 {
91 84 m_RequestingInventory.Add(userID, callback);
92 //RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
93 // = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
94 //requester.ResponseCallback = InventoryResponse;
95
96 //requester.BeginPostObject(invServer + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString());
97 GetInventoryDelegate d = GetInventoryAsync;
98 d.BeginInvoke(invServer, userID, session_id, GetInventoryCompleted, d);
99
100 } 85 }
101 catch (WebException e) 86 else
102 { 87 {
103 if (StatsManager.SimExtraStats != null) 88 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID);
104 StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); 89 return;
105
106 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Request inventory operation failed, {0} {1}",
107 e.Source, e.Message);
108
109 // Well, let's synthesize one
110 InventoryCollection icol = new InventoryCollection();
111 icol.UserID = userID;
112 icol.Items = new List<InventoryItemBase>();
113 icol.Folders = new List<InventoryFolderBase>();
114 InventoryFolderBase rootFolder = new InventoryFolderBase();
115 rootFolder.ID = UUID.Random();
116 rootFolder.Owner = userID;
117 icol.Folders.Add(rootFolder);
118 InventoryResponse(icol);
119 } 90 }
120 } 91 }
121 else 92 string invServer = GetUserInventoryURI(userID);
93 m_log.InfoFormat(
94 "[HGrid INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1} ({2})",
95 /*_inventoryServerUrl*/ invServer, userID, userID.Guid);
96
97 try
122 { 98 {
123 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: RequestInventoryForUser() - could not find user profile for {0}", userID); 99
100 //RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
101 // = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
102 //requester.ResponseCallback = InventoryResponse;
103
104 //requester.BeginPostObject(invServer + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString());
105 GetInventoryDelegate d = GetInventoryAsync;
106 d.BeginInvoke(invServer, userID, session_id, GetInventoryCompleted, d);
107
124 } 108 }
125 109 catch (WebException e)
110 {
111 if (StatsManager.SimExtraStats != null)
112 StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
113
114 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Request inventory operation failed, {0} {1}",
115 e.Source, e.Message);
116
117 // Well, let's synthesize one
118 InventoryCollection icol = new InventoryCollection();
119 icol.UserID = userID;
120 icol.Items = new List<InventoryItemBase>();
121 icol.Folders = new List<InventoryFolderBase>();
122 InventoryFolderBase rootFolder = new InventoryFolderBase();
123 rootFolder.ID = UUID.Random();
124 rootFolder.Owner = userID;
125 icol.Folders.Add(rootFolder);
126 InventoryResponse(icol);
127 }
126 } 128 }
127 129
128 private delegate InventoryCollection GetInventoryDelegate(string url, UUID userID, UUID sessionID); 130 private delegate InventoryCollection GetInventoryDelegate(string url, UUID userID, UUID sessionID);
@@ -447,62 +449,66 @@ namespace OpenSim.Region.Communications.Hypergrid
447 private void InventoryResponse(InventoryCollection response) 449 private void InventoryResponse(InventoryCollection response)
448 { 450 {
449 UUID userID = response.UserID; 451 UUID userID = response.UserID;
450 if (m_RequestingInventory.ContainsKey(userID)) 452 InventoryReceiptCallback callback = null;
453 lock (m_RequestingInventory)
451 { 454 {
452 m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " + 455 if (m_RequestingInventory.ContainsKey(userID))
453 "Received inventory response for user {0} containing {1} folders and {2} items", 456 {
454 userID, response.Folders.Count, response.Items.Count); 457 m_log.InfoFormat("[HGrid INVENTORY SERVICE]: " +
458 "Received inventory response for user {0} containing {1} folders and {2} items",
459 userID, response.Folders.Count, response.Items.Count);
460 callback = m_RequestingInventory[userID];
461 m_RequestingInventory.Remove(userID);
462 }
463 else
464 {
465 m_log.WarnFormat(
466 "[HGrid INVENTORY SERVICE]: " +
467 "Received inventory response for {0} for which we do not have a record of requesting!",
468 userID);
469 return;
470 }
471 }
455 472
456 InventoryFolderImpl rootFolder = null; 473 InventoryFolderImpl rootFolder = null;
457 InventoryReceiptCallback callback = m_RequestingInventory[userID];
458 474
459 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>(); 475 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
460 ICollection<InventoryItemBase> items = new List<InventoryItemBase>(); 476 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
461 477
462 foreach (InventoryFolderBase folder in response.Folders) 478 foreach (InventoryFolderBase folder in response.Folders)
479 {
480 if (folder.ParentID == UUID.Zero)
463 { 481 {
464 if (folder.ParentID == UUID.Zero) 482 rootFolder = new InventoryFolderImpl(folder);
465 { 483 folders.Add(rootFolder);
466 rootFolder = new InventoryFolderImpl(folder);
467 folders.Add(rootFolder);
468 484
469 break; 485 break;
470 }
471 } 486 }
487 }
472 488
473 if (rootFolder != null) 489 if (rootFolder != null)
490 {
491 foreach (InventoryFolderBase folder in response.Folders)
474 { 492 {
475 foreach (InventoryFolderBase folder in response.Folders) 493 if (folder.ID != rootFolder.ID)
476 {
477 if (folder.ID != rootFolder.ID)
478 {
479 folders.Add(new InventoryFolderImpl(folder));
480 }
481 }
482
483 foreach (InventoryItemBase item in response.Items)
484 { 494 {
485 items.Add(item); 495 folders.Add(new InventoryFolderImpl(folder));
486 } 496 }
487 } 497 }
488 else 498
499 foreach (InventoryItemBase item in response.Items)
489 { 500 {
490 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID); 501 items.Add(item);
491 } 502 }
492
493 m_RequestingInventory.Remove(userID);
494 callback(folders, items);
495
496 } 503 }
497 else 504 else
498 { 505 {
499 m_log.WarnFormat( 506 m_log.ErrorFormat("[HGrid INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
500 "[HGrid INVENTORY SERVICE]: " +
501 "Received inventory response for {0} for which we do not have a record of requesting!",
502 userID);
503 } 507 }
504 }
505 508
509 callback(folders, items);
510
511 }
506 512
507 private bool IsLocalStandaloneUser(UUID userID) 513 private bool IsLocalStandaloneUser(UUID userID)
508 { 514 {
diff --git a/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs b/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs
index 03fb0d5..e24f820 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs
@@ -69,34 +69,36 @@ namespace OpenSim.Region.Communications.OGS1
69 /// <param name="callback"></param> 69 /// <param name="callback"></param>
70 public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback) 70 public void RequestInventoryForUser(UUID userID, UUID session_id, InventoryReceiptCallback callback)
71 { 71 {
72 if (!m_RequestingInventory.ContainsKey(userID)) 72 lock (m_RequestingInventory)
73 { 73 {
74 m_RequestingInventory.Add(userID, callback); 74 if (!m_RequestingInventory.ContainsKey(userID))
75 75 m_RequestingInventory.Add(userID, callback);
76 try 76 else
77 { 77 {
78 m_log.InfoFormat( 78 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID);
79 "[OGS1 INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1}", 79 return;
80 _inventoryServerUrl, userID); 80 }
81 }
81 82
82 RestSessionObjectPosterResponse<Guid, InventoryCollection> requester 83 try
83 = new RestSessionObjectPosterResponse<Guid, InventoryCollection>(); 84 {
84 requester.ResponseCallback = InventoryResponse; 85 m_log.InfoFormat(
86 "[OGS1 INVENTORY SERVICE]: Requesting inventory from {0}/GetInventory/ for user {1}",
87 _inventoryServerUrl, userID);
85 88
86 requester.BeginPostObject(_inventoryServerUrl + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString()); 89 RestSessionObjectPosterResponse<Guid, InventoryCollection> requester
87 } 90 = new RestSessionObjectPosterResponse<Guid, InventoryCollection>();
88 catch (WebException e) 91 requester.ResponseCallback = InventoryResponse;
89 {
90 if (StatsManager.SimExtraStats != null)
91 StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
92 92
93 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Request inventory operation failed, {0} {1}", 93 requester.BeginPostObject(_inventoryServerUrl + "/GetInventory/", userID.Guid, session_id.ToString(), userID.ToString());
94 e.Source, e.Message);
95 }
96 } 94 }
97 else 95 catch (WebException e)
98 { 96 {
99 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: RequestInventoryForUser() - could you not find user profile for {0}", userID); 97 if (StatsManager.SimExtraStats != null)
98 StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure();
99
100 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Request inventory operation failed, {0} {1}",
101 e.Source, e.Message);
100 } 102 }
101 } 103 }
102 104
@@ -107,60 +109,66 @@ namespace OpenSim.Region.Communications.OGS1
107 private void InventoryResponse(InventoryCollection response) 109 private void InventoryResponse(InventoryCollection response)
108 { 110 {
109 UUID userID = response.UserID; 111 UUID userID = response.UserID;
110 if (m_RequestingInventory.ContainsKey(userID)) 112 InventoryReceiptCallback callback = null;
113 lock (m_RequestingInventory)
111 { 114 {
112 m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " + 115 if (m_RequestingInventory.ContainsKey(userID))
113 "Received inventory response for user {0} containing {1} folders and {2} items", 116 {
114 userID, response.Folders.Count, response.Items.Count); 117 callback = m_RequestingInventory[userID];
118 m_RequestingInventory.Remove(userID);
119 }
120 else
121 {
122 m_log.WarnFormat(
123 "[OGS1 INVENTORY SERVICE]: " +
124 "Received inventory response for {0} for which we do not have a record of requesting!",
125 userID);
126 return;
127 }
128 }
115 129
116 InventoryFolderImpl rootFolder = null; 130 m_log.InfoFormat("[OGS1 INVENTORY SERVICE]: " +
117 InventoryReceiptCallback callback = m_RequestingInventory[userID]; 131 "Received inventory response for user {0} containing {1} folders and {2} items",
132 userID, response.Folders.Count, response.Items.Count);
118 133
119 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>(); 134 InventoryFolderImpl rootFolder = null;
120 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
121 135
122 foreach (InventoryFolderBase folder in response.Folders) 136 ICollection<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
137 ICollection<InventoryItemBase> items = new List<InventoryItemBase>();
138
139 foreach (InventoryFolderBase folder in response.Folders)
140 {
141 if (folder.ParentID == UUID.Zero)
123 { 142 {
124 if (folder.ParentID == UUID.Zero) 143 rootFolder = new InventoryFolderImpl(folder);
125 { 144 folders.Add(rootFolder);
126 rootFolder = new InventoryFolderImpl(folder);
127 folders.Add(rootFolder);
128 145
129 break; 146 break;
130 }
131 } 147 }
148 }
132 149
133 if (rootFolder != null) 150 if (rootFolder != null)
151 {
152 foreach (InventoryFolderBase folder in response.Folders)
134 { 153 {
135 foreach (InventoryFolderBase folder in response.Folders) 154 if (folder.ID != rootFolder.ID)
136 { 155 {
137 if (folder.ID != rootFolder.ID) 156 folders.Add(new InventoryFolderImpl(folder));
138 {
139 folders.Add(new InventoryFolderImpl(folder));
140 }
141 }
142
143 foreach (InventoryItemBase item in response.Items)
144 {
145 items.Add(item);
146 } 157 }
147 } 158 }
148 else 159
160 foreach (InventoryItemBase item in response.Items)
149 { 161 {
150 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID); 162 items.Add(item);
151 } 163 }
152
153 callback(folders, items);
154
155 m_RequestingInventory.Remove(userID);
156 } 164 }
157 else 165 else
158 { 166 {
159 m_log.WarnFormat( 167 m_log.ErrorFormat("[OGS1 INVENTORY SERVICE]: Did not get back an inventory containing a root folder for user {0}", userID);
160 "[OGS1 INVENTORY SERVICE]: " +
161 "Received inventory response for {0} for which we do not have a record of requesting!",
162 userID);
163 } 168 }
169
170 callback(folders, items);
171
164 } 172 }
165 173
166 /// <summary> 174 /// <summary>