* Enabled GTCache for AssetCache
* Items will now be locally cached for only 24 hours from last access. (Rather than until restart) * Caveat: Implementing the new caching mechanism means statistics gathering on AssetCache is no longer functional. (Justin - you might want to take a look and see if you can somehow get that back and running if you still need it)0.6.1-post-fixes
parent
448092332c
commit
c43e466301
|
@ -33,6 +33,7 @@ using OpenMetaverse;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenSim.Framework.Statistics;
|
using OpenSim.Framework.Statistics;
|
||||||
|
using GlynnTucker.Cache;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Communications.Cache
|
namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
|
@ -52,18 +53,20 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AssetCache : IAssetReceiver
|
public class AssetCache : IAssetReceiver
|
||||||
{
|
{
|
||||||
|
protected ICache m_memcache = new SimpleMemoryCache();
|
||||||
|
|
||||||
private static readonly ILog m_log
|
private static readonly ILog m_log
|
||||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cache of assets. This does not include textures.
|
/// The cache of assets. This does not include textures.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<UUID, AssetInfo> Assets;
|
//private Dictionary<UUID, AssetInfo> Assets;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cache of textures.
|
/// The cache of textures.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<UUID, TextureImage> Textures;
|
//private Dictionary<UUID, TextureImage> Textures;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Assets requests which are waiting for asset server data. This includes texture requests
|
/// Assets requests which are waiting for asset server data. This includes texture requests
|
||||||
|
@ -95,52 +98,11 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ShowState()
|
public void ShowState()
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("Assets:{0} Textures:{1} RequestLists:{2}",
|
m_log.InfoFormat("Memcache:{1} RequestLists:{2}",
|
||||||
Assets.Count,
|
m_memcache.Count,
|
||||||
Textures.Count,
|
|
||||||
// AssetRequests.Count,
|
// AssetRequests.Count,
|
||||||
// RequestedAssets.Count,
|
// RequestedAssets.Count,
|
||||||
RequestLists.Count);
|
RequestLists.Count);
|
||||||
|
|
||||||
int temporaryImages = 0;
|
|
||||||
int temporaryAssets = 0;
|
|
||||||
|
|
||||||
long imageBytes = 0;
|
|
||||||
long assetBytes = 0;
|
|
||||||
|
|
||||||
foreach (TextureImage texture in Textures.Values)
|
|
||||||
{
|
|
||||||
if (texture != null)
|
|
||||||
{
|
|
||||||
if (texture.Temporary)
|
|
||||||
{
|
|
||||||
temporaryImages++;
|
|
||||||
}
|
|
||||||
|
|
||||||
imageBytes += texture.Data.GetLongLength(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (AssetInfo asset in Assets.Values)
|
|
||||||
{
|
|
||||||
if (asset != null)
|
|
||||||
{
|
|
||||||
if (asset.Temporary)
|
|
||||||
{
|
|
||||||
temporaryAssets++;
|
|
||||||
}
|
|
||||||
|
|
||||||
assetBytes += asset.Data.GetLongLength(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.InfoFormat("Temporary Images: {0} Temporary Assets: {1}",
|
|
||||||
temporaryImages,
|
|
||||||
temporaryAssets);
|
|
||||||
|
|
||||||
m_log.InfoFormat("Image data: {0}kb Asset data: {1}kb",
|
|
||||||
imageBytes / 1024,
|
|
||||||
assetBytes / 1024);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -161,8 +123,6 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
Assets = new Dictionary<UUID, AssetInfo>();
|
|
||||||
Textures = new Dictionary<UUID, TextureImage>();
|
|
||||||
AssetRequests = new List<AssetRequest>();
|
AssetRequests = new List<AssetRequest>();
|
||||||
|
|
||||||
RequestedAssets = new Dictionary<UUID, AssetRequest>();
|
RequestedAssets = new Dictionary<UUID, AssetRequest>();
|
||||||
|
@ -181,7 +141,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
m_assetServer = assetServer;
|
m_assetServer = assetServer;
|
||||||
m_assetServer.SetReceiver(this);
|
m_assetServer.SetReceiver(this);
|
||||||
|
|
||||||
Thread assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
|
Thread assetCacheThread = new Thread(RunAssetManager);
|
||||||
assetCacheThread.Name = "AssetCacheThread";
|
assetCacheThread.Name = "AssetCacheThread";
|
||||||
assetCacheThread.IsBackground = true;
|
assetCacheThread.IsBackground = true;
|
||||||
assetCacheThread.Start();
|
assetCacheThread.Start();
|
||||||
|
@ -203,7 +163,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[ASSET CACHE]: " + e.ToString());
|
m_log.Error("[ASSET CACHE]: " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,14 +176,11 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// <returns>true if the asset was in the cache, false if it was not</returns>
|
/// <returns>true if the asset was in the cache, false if it was not</returns>
|
||||||
public bool TryGetCachedAsset(UUID assetId, out AssetBase asset)
|
public bool TryGetCachedAsset(UUID assetId, out AssetBase asset)
|
||||||
{
|
{
|
||||||
if (Textures.ContainsKey(assetId))
|
Object tmp;
|
||||||
|
if(m_memcache.TryGet(assetId, out tmp))
|
||||||
{
|
{
|
||||||
asset = Textures[assetId];
|
asset = (AssetBase)tmp;
|
||||||
return true;
|
//m_log.Info("Retrieved from cache " + assetId);
|
||||||
}
|
|
||||||
else if (Assets.ContainsKey(assetId))
|
|
||||||
{
|
|
||||||
asset = Assets[assetId];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,25 +269,22 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
else
|
m_assetServer.RequestAsset(assetID, isTexture);
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
m_assetServer.RequestAsset(assetID, isTexture);
|
Thread.Sleep(pollPeriod);
|
||||||
|
|
||||||
do
|
if (TryGetCachedAsset(assetID, out asset))
|
||||||
{
|
{
|
||||||
Thread.Sleep(pollPeriod);
|
return asset;
|
||||||
|
}
|
||||||
|
} while (--maxPolls > 0);
|
||||||
|
|
||||||
if (TryGetCachedAsset(assetID, out asset))
|
m_log.WarnFormat("[ASSET CACHE]: {0} {1} was not received before the retrieval timeout was reached",
|
||||||
{
|
isTexture ? "texture" : "asset", assetID.ToString());
|
||||||
return asset;
|
|
||||||
}
|
|
||||||
} while (--maxPolls > 0);
|
|
||||||
|
|
||||||
m_log.WarnFormat("[ASSET CACHE]: {0} {1} was not received before the retrieval timeout was reached",
|
return null;
|
||||||
isTexture ? "texture" : "asset", assetID.ToString());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -339,68 +293,34 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// <param name="asset"></param>
|
/// <param name="asset"></param>
|
||||||
public void AddAsset(AssetBase asset)
|
public void AddAsset(AssetBase asset)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
if (!m_memcache.Contains(asset.FullID))
|
||||||
// "[ASSET CACHE]: Uploaded asset {0}, temporary {1}, store local {2}",
|
|
||||||
// asset.ID, asset.Temporary, asset.Local);
|
|
||||||
|
|
||||||
if (asset.Type == (int)AssetType.Texture)
|
|
||||||
{
|
{
|
||||||
if (!Textures.ContainsKey(asset.FullID))
|
m_log.Info("[CACHE] Caching " + asset.FullID + " for 24 hours from last access");
|
||||||
|
// Use 24 hour rolling asset cache.
|
||||||
|
m_memcache.AddOrUpdate(asset.FullID, asset, TimeSpan.FromHours(24));
|
||||||
|
|
||||||
|
// According to http://wiki.secondlife.com/wiki/AssetUploadRequest, Local signifies that the
|
||||||
|
// information is stored locally. It could disappear, in which case we could send the
|
||||||
|
// ImageNotInDatabase packet to tell the client this.
|
||||||
|
//
|
||||||
|
// However, this doesn't quite appear to work with local textures that are part of an avatar's
|
||||||
|
// appearance texture set. Whilst sending an ImageNotInDatabase does trigger an automatic rebake
|
||||||
|
// and reupload by the client, if those assets aren't pushed to the asset server anyway, then
|
||||||
|
// on crossing onto another region server, other avatars can no longer get the required textures.
|
||||||
|
// There doesn't appear to be any signal from the sim to the newly region border crossed client
|
||||||
|
// asking it to reupload its local texture assets to that region server.
|
||||||
|
//
|
||||||
|
// One can think of other cunning ways around this. For instance, on a region crossing or teleport,
|
||||||
|
// the original sim could squirt local assets to the new sim. Or the new sim could have pointers
|
||||||
|
// to the original sim to fetch the 'local' assets (this is getting more complicated).
|
||||||
|
//
|
||||||
|
// But for now, we're going to take the easy way out and store local assets globally.
|
||||||
|
//
|
||||||
|
// TODO: Also, Temporary is now deprecated. We should start ignoring it and not passing it out from LLClientView.
|
||||||
|
if (!asset.Temporary || asset.Local)
|
||||||
{
|
{
|
||||||
TextureImage textur = new TextureImage(asset);
|
m_assetServer.StoreAsset(asset);
|
||||||
Textures.Add(textur.FullID, textur);
|
|
||||||
|
|
||||||
if (StatsManager.SimExtraStats != null)
|
|
||||||
StatsManager.SimExtraStats.AddTexture(textur);
|
|
||||||
|
|
||||||
// According to http://wiki.secondlife.com/wiki/AssetUploadRequest, Local signifies that the
|
|
||||||
// information is stored locally. It could disappear, in which case we could send the
|
|
||||||
// ImageNotInDatabase packet to tell the client this.
|
|
||||||
//
|
|
||||||
// However, this doesn't quite appear to work with local textures that are part of an avatar's
|
|
||||||
// appearance texture set. Whilst sending an ImageNotInDatabase does trigger an automatic rebake
|
|
||||||
// and reupload by the client, if those assets aren't pushed to the asset server anyway, then
|
|
||||||
// on crossing onto another region server, other avatars can no longer get the required textures.
|
|
||||||
// There doesn't appear to be any signal from the sim to the newly region border crossed client
|
|
||||||
// asking it to reupload its local texture assets to that region server.
|
|
||||||
//
|
|
||||||
// One can think of other cunning ways around this. For instance, on a region crossing or teleport,
|
|
||||||
// the original sim could squirt local assets to the new sim. Or the new sim could have pointers
|
|
||||||
// to the original sim to fetch the 'local' assets (this is getting more complicated).
|
|
||||||
//
|
|
||||||
// But for now, we're going to take the easy way out and store local assets globally.
|
|
||||||
//
|
|
||||||
// TODO: Also, Temporary is now deprecated. We should start ignoring it and not passing it out from LLClientView.
|
|
||||||
if (!asset.Temporary || asset.Local)
|
|
||||||
{
|
|
||||||
m_assetServer.StoreAsset(asset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// m_log.DebugFormat("[ASSET CACHE]: Textures already contains {0}", asset.ID);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!Assets.ContainsKey(asset.FullID))
|
|
||||||
{
|
|
||||||
AssetInfo assetInf = new AssetInfo(asset);
|
|
||||||
Assets.Add(assetInf.FullID, assetInf);
|
|
||||||
|
|
||||||
if (StatsManager.SimExtraStats != null)
|
|
||||||
StatsManager.SimExtraStats.AddAsset(assetInf);
|
|
||||||
|
|
||||||
// See comment above.
|
|
||||||
if (!asset.Temporary || asset.Local)
|
|
||||||
{
|
|
||||||
m_assetServer.StoreAsset(asset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// m_log.DebugFormat("[ASSET CACHE]: Assets already contains {0}", asset.ID);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,71 +337,46 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
// in the 2 caches differently. Also, locks are probably
|
// in the 2 caches differently. Also, locks are probably
|
||||||
// needed in all of this, or move to synchronized non
|
// needed in all of this, or move to synchronized non
|
||||||
// generic forms for Dictionaries.
|
// generic forms for Dictionaries.
|
||||||
if (Textures.ContainsKey(uuid))
|
if(m_memcache.Contains(uuid))
|
||||||
{
|
{
|
||||||
Textures.Remove(uuid);
|
m_memcache.Remove(uuid);
|
||||||
}
|
|
||||||
else if (Assets.ContainsKey(uuid))
|
|
||||||
{
|
|
||||||
Assets.Remove(uuid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See IAssetReceiver
|
// See IAssetReceiver
|
||||||
public void AssetReceived(AssetBase asset, bool IsTexture)
|
public void AssetReceived(AssetBase asset, bool IsTexture)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[ASSET CACHE]: Received asset {0}", asset.ID);
|
|
||||||
|
|
||||||
//check if it is a texture or not
|
|
||||||
//then add to the correct cache list
|
|
||||||
//then check for waiting requests for this asset/texture (in the Requested lists)
|
|
||||||
//and move those requests into the Requests list.
|
|
||||||
if (IsTexture)
|
|
||||||
{
|
|
||||||
TextureImage image = new TextureImage(asset);
|
|
||||||
if (!Textures.ContainsKey(image.FullID))
|
|
||||||
{
|
|
||||||
Textures.Add(image.FullID, image);
|
|
||||||
|
|
||||||
if (StatsManager.SimExtraStats != null)
|
AssetInfo assetInf = new AssetInfo(asset);
|
||||||
{
|
if (!m_memcache.Contains(assetInf.FullID))
|
||||||
StatsManager.SimExtraStats.AddTexture(image);
|
{
|
||||||
}
|
m_memcache.AddOrUpdate(assetInf.FullID, assetInf, TimeSpan.FromHours(24));
|
||||||
|
|
||||||
|
if (StatsManager.SimExtraStats != null)
|
||||||
|
{
|
||||||
|
StatsManager.SimExtraStats.AddAsset(assetInf);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
if (RequestedAssets.ContainsKey(assetInf.FullID))
|
||||||
{
|
|
||||||
AssetInfo assetInf = new AssetInfo(asset);
|
|
||||||
if (!Assets.ContainsKey(assetInf.FullID))
|
|
||||||
{
|
{
|
||||||
Assets.Add(assetInf.FullID, assetInf);
|
AssetRequest req = RequestedAssets[assetInf.FullID];
|
||||||
|
req.AssetInf = assetInf;
|
||||||
|
req.NumPackets = CalculateNumPackets(assetInf.Data);
|
||||||
|
|
||||||
if (StatsManager.SimExtraStats != null)
|
RequestedAssets.Remove(assetInf.FullID);
|
||||||
{
|
// If it's a direct request for a script, drop it
|
||||||
StatsManager.SimExtraStats.AddAsset(assetInf);
|
// because it's a hacked client
|
||||||
}
|
if (req.AssetRequestSource != 2 || assetInf.Type != 10)
|
||||||
|
AssetRequests.Add(req);
|
||||||
if (RequestedAssets.ContainsKey(assetInf.FullID))
|
|
||||||
{
|
|
||||||
AssetRequest req = RequestedAssets[assetInf.FullID];
|
|
||||||
req.AssetInf = assetInf;
|
|
||||||
req.NumPackets = CalculateNumPackets(assetInf.Data);
|
|
||||||
|
|
||||||
RequestedAssets.Remove(assetInf.FullID);
|
|
||||||
// If it's a direct request for a script, drop it
|
|
||||||
// because it's a hacked client
|
|
||||||
if (req.AssetRequestSource != 2 || assetInf.Type != 10)
|
|
||||||
AssetRequests.Add(req);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify requesters for this asset
|
// Notify requesters for this asset
|
||||||
AssetRequestsList reqList = null;
|
AssetRequestsList reqList;
|
||||||
|
|
||||||
lock (RequestLists)
|
lock (RequestLists)
|
||||||
{
|
{
|
||||||
if (RequestLists.TryGetValue(asset.FullID, out reqList))
|
if (RequestLists.TryGetValue(asset.FullID, out reqList))
|
||||||
RequestLists.Remove(asset.FullID);
|
RequestLists.Remove(asset.FullID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +384,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
if (StatsManager.SimExtraStats != null)
|
if (StatsManager.SimExtraStats != null)
|
||||||
StatsManager.SimExtraStats.AddAssetRequestTimeAfterCacheMiss(DateTime.Now - reqList.TimeRequested);
|
StatsManager.SimExtraStats.AddAssetRequestTimeAfterCacheMiss(DateTime.Now - reqList.TimeRequested);
|
||||||
|
|
||||||
foreach (NewAssetRequest req in reqList.Requests)
|
foreach (NewAssetRequest req in reqList.Requests)
|
||||||
{
|
{
|
||||||
// Xantor 20080526 are we really calling all the callbacks if multiple queued for 1 request? -- Yes, checked
|
// Xantor 20080526 are we really calling all the callbacks if multiple queued for 1 request? -- Yes, checked
|
||||||
|
@ -504,17 +399,8 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID);
|
// m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID);
|
||||||
|
|
||||||
if (IsTexture)
|
|
||||||
{
|
|
||||||
Textures[assetID] = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assets[assetID] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify requesters for this asset
|
// Notify requesters for this asset
|
||||||
AssetRequestsList reqList = null;
|
AssetRequestsList reqList;
|
||||||
lock (RequestLists)
|
lock (RequestLists)
|
||||||
{
|
{
|
||||||
if (RequestLists.TryGetValue(assetID, out reqList))
|
if (RequestLists.TryGetValue(assetID, out reqList))
|
||||||
|
@ -578,7 +464,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
//check to see if asset is in local cache, if not we need to request it from asset server.
|
//check to see if asset is in local cache, if not we need to request it from asset server.
|
||||||
//Console.WriteLine("asset request " + requestID);
|
//Console.WriteLine("asset request " + requestID);
|
||||||
if (!Assets.ContainsKey(requestID))
|
if (!m_memcache.Contains(requestID))
|
||||||
{
|
{
|
||||||
//not found asset
|
//not found asset
|
||||||
// so request from asset server
|
// so request from asset server
|
||||||
|
@ -598,7 +484,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
// It has an entry in our cache
|
// It has an entry in our cache
|
||||||
AssetInfo asset = Assets[requestID];
|
AssetInfo asset = (AssetInfo)m_memcache[requestID];
|
||||||
|
|
||||||
// FIXME: We never tell the client about assets which do not exist when requested by this transfer mechanism, which can't be right.
|
// FIXME: We never tell the client about assets which do not exist when requested by this transfer mechanism, which can't be right.
|
||||||
if (null == asset)
|
if (null == asset)
|
||||||
|
|
|
@ -48,22 +48,32 @@ namespace OpenSim.Region.Environment
|
||||||
{
|
{
|
||||||
m_log.Info("[CLIENTSTACK]: Attempting to load " + dllName);
|
m_log.Info("[CLIENTSTACK]: Attempting to load " + dllName);
|
||||||
|
|
||||||
plugin = null;
|
try
|
||||||
pluginAssembly = Assembly.LoadFrom(dllName);
|
|
||||||
|
|
||||||
foreach (Type pluginType in pluginAssembly.GetTypes())
|
|
||||||
{
|
{
|
||||||
if (pluginType.IsPublic)
|
plugin = null;
|
||||||
{
|
pluginAssembly = Assembly.LoadFrom(dllName);
|
||||||
Type typeInterface = pluginType.GetInterface("IClientNetworkServer", true);
|
|
||||||
|
|
||||||
if (typeInterface != null)
|
foreach (Type pluginType in pluginAssembly.GetTypes())
|
||||||
|
{
|
||||||
|
if (pluginType.IsPublic)
|
||||||
{
|
{
|
||||||
m_log.Info("[CLIENTSTACK]: Added IClientNetworkServer Interface");
|
Type typeInterface = pluginType.GetInterface("IClientNetworkServer", true);
|
||||||
plugin = pluginType;
|
|
||||||
return;
|
if (typeInterface != null)
|
||||||
|
{
|
||||||
|
m_log.Info("[CLIENTSTACK]: Added IClientNetworkServer Interface");
|
||||||
|
plugin = pluginType;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ReflectionTypeLoadException e)
|
||||||
|
{
|
||||||
|
foreach(Exception e2 in e.LoaderExceptions)
|
||||||
|
{
|
||||||
|
m_log.Error(e2.ToString());
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -664,7 +664,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CLIENT]: Entered main packet processing loop for {0} {1}", FirstName, LastName);
|
"[CLIENT]: Entered main packet processing loop for {0} {1}", FirstName, LastName);
|
||||||
|
|
||||||
while (true)
|
while (IsActive)
|
||||||
{
|
{
|
||||||
LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue();
|
LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue();
|
||||||
|
|
||||||
|
|
|
@ -743,6 +743,7 @@
|
||||||
<Reference name="Nini.dll" />
|
<Reference name="Nini.dll" />
|
||||||
<Reference name="XMLRPC.dll"/>
|
<Reference name="XMLRPC.dll"/>
|
||||||
<Reference name="log4net.dll"/>
|
<Reference name="log4net.dll"/>
|
||||||
|
<Reference name="GlynnTucker.Cache.dll"/>
|
||||||
|
|
||||||
<Files>
|
<Files>
|
||||||
<Match pattern="*.cs" recurse="true"/>
|
<Match pattern="*.cs" recurse="true"/>
|
||||||
|
@ -968,7 +969,6 @@
|
||||||
<Reference name="OpenSim.Region.Interfaces"/>
|
<Reference name="OpenSim.Region.Interfaces"/>
|
||||||
<Reference name="OpenSim.Data"/>
|
<Reference name="OpenSim.Data"/>
|
||||||
<Reference name="OpenSim.Framework.Servers"/>
|
<Reference name="OpenSim.Framework.Servers"/>
|
||||||
<Reference name="OpenSim.Framework.Client"/>
|
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
<Reference name="OpenSim.Framework.Communications"/>
|
<Reference name="OpenSim.Framework.Communications"/>
|
||||||
<Reference name="OpenSim.Framework.Statistics"/>
|
<Reference name="OpenSim.Framework.Statistics"/>
|
||||||
|
|
Loading…
Reference in New Issue