aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs
diff options
context:
space:
mode:
authordiva2009-04-18 16:37:05 +0000
committerdiva2009-04-18 16:37:05 +0000
commit8e08dd20dc9fe785874943c7986f82af60ed1879 (patch)
treee73717f3a5c416514acb6bd363aad9a206a66360 /OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs
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 'OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs')
-rw-r--r--OpenSim/Region/Communications/OGS1/OGS1SecureInventoryService.cs122
1 files changed, 65 insertions, 57 deletions
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>