diff options
When an uncached asset is requested multiple times concurrently, only load it once
Signed-off-by: root <root@grid00001.t-data.com>
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index f1da4fa..fdab254 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | |||
@@ -48,6 +48,13 @@ namespace OpenSim.Services.Connectors | |||
48 | private string m_ServerURI = String.Empty; | 48 | private string m_ServerURI = String.Empty; |
49 | private IImprovedAssetCache m_Cache = null; | 49 | private IImprovedAssetCache m_Cache = null; |
50 | 50 | ||
51 | private delegate void AssetRetrievedEx(AssetBase asset); | ||
52 | |||
53 | // Keeps track of concurrent requests for the same asset, so that it's only loaded once. | ||
54 | // Maps: Asset ID -> Handlers which will be called when the asset has been loaded | ||
55 | private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>(); | ||
56 | |||
57 | |||
51 | public AssetServicesConnector() | 58 | public AssetServicesConnector() |
52 | { | 59 | { |
53 | } | 60 | } |
@@ -178,23 +185,56 @@ namespace OpenSim.Services.Connectors | |||
178 | 185 | ||
179 | if (asset == null) | 186 | if (asset == null) |
180 | { | 187 | { |
181 | bool result = false; | 188 | lock (m_AssetHandlers) |
182 | 189 | { | |
183 | AsynchronousRestObjectRequester. | 190 | AssetRetrievedEx handlerEx = new AssetRetrievedEx(delegate(AssetBase _asset) { handler(id, sender, _asset); }); |
184 | MakeRequest<int, AssetBase>("GET", uri, 0, | 191 | |
192 | AssetRetrievedEx handlers; | ||
193 | if (m_AssetHandlers.TryGetValue(id, out handlers)) | ||
194 | { | ||
195 | // Someone else is already loading this asset. It will notify our handler when done. | ||
196 | handlers += handlerEx; | ||
197 | return true; | ||
198 | } | ||
199 | |||
200 | // Load the asset ourselves | ||
201 | handlers += handlerEx; | ||
202 | m_AssetHandlers.Add(id, handlers); | ||
203 | } | ||
204 | |||
205 | bool success = false; | ||
206 | try | ||
207 | { | ||
208 | AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, | ||
185 | delegate(AssetBase a) | 209 | delegate(AssetBase a) |
186 | { | 210 | { |
187 | if (m_Cache != null) | 211 | if (m_Cache != null) |
188 | m_Cache.Cache(a); | 212 | m_Cache.Cache(a); |
189 | handler(id, sender, a); | ||
190 | result = true; | ||
191 | }); | ||
192 | 213 | ||
193 | return result; | 214 | AssetRetrievedEx handlers; |
215 | lock (m_AssetHandlers) | ||
216 | { | ||
217 | handlers = m_AssetHandlers[id]; | ||
218 | m_AssetHandlers.Remove(id); | ||
219 | } | ||
220 | handlers.Invoke(a); | ||
221 | }); | ||
222 | |||
223 | success = true; | ||
224 | } | ||
225 | finally | ||
226 | { | ||
227 | if (!success) | ||
228 | { | ||
229 | lock (m_AssetHandlers) | ||
230 | { | ||
231 | m_AssetHandlers.Remove(id); | ||
232 | } | ||
233 | } | ||
234 | } | ||
194 | } | 235 | } |
195 | else | 236 | else |
196 | { | 237 | { |
197 | //Util.FireAndForget(delegate { handler(id, sender, asset); }); | ||
198 | handler(id, sender, asset); | 238 | handler(id, sender, asset); |
199 | } | 239 | } |
200 | 240 | ||