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_OLD-8e08dd20dc9fe785874943c7986f82af60ed1879.zip
opensim-SC_OLD-8e08dd20dc9fe785874943c7986f82af60ed1879.tar.gz
opensim-SC_OLD-8e08dd20dc9fe785874943c7986f82af60ed1879.tar.bz2
opensim-SC_OLD-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.
-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>