From ecbeb5cea15e558b1df361dc90f1bf24bbc87152 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Mon, 1 Jun 2009 16:00:46 +0000
Subject: * Fix race condition in save oar
---
.../Asset/LocalAssetServiceConnector.cs | 4 ++
.../World/Archiver/ArchiveReadRequest.cs | 2 +
.../World/Archiver/ArchiveWriteRequestExecution.cs | 2 +-
.../CoreModules/World/Archiver/AssetsRequest.cs | 70 +++++++++++++---------
4 files changed, 50 insertions(+), 28 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs
index 96366f1..995a47a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectors/Asset/LocalAssetServiceConnector.cs
@@ -196,6 +196,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
public bool Get(string id, Object sender, AssetRetrieved handler)
{
AssetBase asset = null;
+
if (m_Cache != null)
m_Cache.Get(id);
@@ -209,6 +210,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
{
if ((a != null) && (m_Cache != null))
m_Cache.Cache(a);
+
handler.BeginInvoke(assetID, s, a, null, null);
});
}
@@ -217,8 +219,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectors.Asset
{
if (m_Cache != null)
m_Cache.Cache(asset);
+
if (asset.Temporary || asset.Local)
return asset.ID;
+
return m_AssetService.Store(asset);
}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 7fe6d2e..74904e2 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -310,6 +310,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
asset.Type = assetType;
asset.Data = data;
+ // We're relying on the asset service to do the sensible thing and not store the asset if it already
+ // exists.
m_scene.AssetService.Store(asset);
/**
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
index 4819746..9fd9469 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_archiveWriter.Close();
- m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_scene.RegionInfo.RegionName);
+ m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_scene.RegionInfo.RegionName);
m_scene.EventManager.TriggerOarFileSaved(m_requestId, String.Empty);
}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index c673e18..129d6d3 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -70,20 +70,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
private int m_repliesRequired;
///
- /// Asset cache used to request the assets
+ /// Asset service used to request the assets
///
- protected IAssetService m_assetCache;
+ protected IAssetService m_assetService;
protected AssetsArchiver m_assetsArchiver;
protected internal AssetsRequest(
AssetsArchiver assetsArchiver, ICollection uuids,
- IAssetService assetCache, AssetsRequestCallback assetsRequestCallback)
+ IAssetService assetService, AssetsRequestCallback assetsRequestCallback)
{
m_assetsArchiver = assetsArchiver;
m_uuids = uuids;
m_assetsRequestCallback = assetsRequestCallback;
- m_assetCache = assetCache;
+ m_assetService = assetService;
m_repliesRequired = uuids.Count;
}
@@ -93,14 +93,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// We can stop here if there are no assets to fetch
if (m_repliesRequired == 0)
- m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);
-
+ PerformAssetsRequestCallback();
+
foreach (UUID uuid in m_uuids)
{
- m_assetCache.Get(uuid.ToString(), this, AssetRequestCallback);
+ m_assetService.Get(uuid.ToString(), this, AssetRequestCallback);
}
}
+ private bool done = false;
///
/// Called back by the asset cache when it has the asset
///
@@ -108,29 +109,44 @@ namespace OpenSim.Region.CoreModules.World.Archiver
///
public void AssetRequestCallback(string id, object sender, AssetBase asset)
{
- //m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", assetID);
-
- if (asset != null)
- {
- m_foundAssetUuids.Add(asset.FullID);
- m_assetsArchiver.WriteAsset(asset);
- }
- else
+ try
{
- m_notFoundAssetUuids.Add(new UUID(id));
+ lock (this)
+ {
+ //m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", id);
+
+ if (asset != null)
+ {
+ m_foundAssetUuids.Add(asset.FullID);
+ m_assetsArchiver.WriteAsset(asset);
+ }
+ else
+ {
+ m_notFoundAssetUuids.Add(new UUID(id));
+ }
+
+ if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count == m_repliesRequired)
+ {
+ if (done)
+ throw new Exception("AArgh");
+
+ m_log.DebugFormat(
+ "[ARCHIVER]: Successfully added {0} assets ({1} assets missing)",
+ m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
+
+ done = true;
+
+ // We want to stop using the asset cache thread asap
+ // as we now need to do the work of producing the rest of the archive
+ Thread newThread = new Thread(PerformAssetsRequestCallback);
+ newThread.Name = "OpenSimulator archiving thread post assets receipt";
+ newThread.Start();
+ }
+ }
}
-
- if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count == m_repliesRequired)
+ catch (Exception e)
{
- m_log.DebugFormat(
- "[ARCHIVER]: Successfully added {0} assets ({1} assets missing)",
- m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
-
- // We want to stop using the asset cache thread asap
- // as we now need to do the work of producing the rest of the archive
- Thread newThread = new Thread(PerformAssetsRequestCallback);
- newThread.Name = "OpenSimulator archiving thread post assets receipt";
- newThread.Start();
+ m_log.ErrorFormat("[ARCHIVER]: AssetRequestCallback failed with {0}", e);
}
}
--
cgit v1.1