More work on trying to get AvatarFactoryModule to play nicely with multiple threads

ThreadPoolClientBranch
MW 2008-02-14 18:59:03 +00:00
parent e1d9275610
commit 8ad450f83e
1 changed files with 84 additions and 67 deletions

View File

@ -56,6 +56,12 @@ namespace OpenSim.Region.Environment.Modules
private object m_syncLock = new object(); private object m_syncLock = new object();
public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance)
{
//should only let one thread at a time do this part
EventWaitHandle waitHandle = null;
bool fetchInProgress = false;
lock (m_syncLock)
{ {
appearance = CheckCache(avatarId); appearance = CheckCache(avatarId);
if (appearance != null) if (appearance != null)
@ -64,11 +70,22 @@ namespace OpenSim.Region.Environment.Modules
} }
//not in cache so check to see if another thread is already fetching it //not in cache so check to see if another thread is already fetching it
//should only let one thread at a time do this part
EventWaitHandle waitHandle = null;
lock (m_syncLock)
{
if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle))
{
fetchInProgress = true;
}
else
{
fetchInProgress = false;
//no thread already fetching this appearance, so add a wait handle to list
//for any following threads that want the same appearance
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
m_fetchesInProgress.Add(avatarId, waitHandle);
}
}
if (fetchInProgress)
{ {
waitHandle.WaitOne(); waitHandle.WaitOne();
appearance = CheckCache(avatarId); appearance = CheckCache(avatarId);
@ -82,16 +99,11 @@ namespace OpenSim.Region.Environment.Modules
waitHandle = null; waitHandle = null;
return false; return false;
} }
} }
else else
{ {
//no thread already fetching this appearance, so add a wait handle to list Thread.Sleep(5000);
//for any following threads that want the same appearance
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
m_fetchesInProgress.Add(avatarId, waitHandle);
}
}
//this is the first thread to request this appearance //this is the first thread to request this appearance
//so let it check the db and if not found then create a default appearance //so let it check the db and if not found then create a default appearance
@ -105,6 +117,7 @@ namespace OpenSim.Region.Environment.Modules
m_fetchesInProgress.Remove(avatarId); m_fetchesInProgress.Remove(avatarId);
waitHandle.Set(); waitHandle.Set();
} }
// waitHandle.Close();
waitHandle = null; waitHandle = null;
return true; return true;
} }
@ -131,6 +144,7 @@ namespace OpenSim.Region.Environment.Modules
m_fetchesInProgress.Remove(avatarId); m_fetchesInProgress.Remove(avatarId);
waitHandle.Set(); waitHandle.Set();
} }
// waitHandle.Close();
waitHandle = null; waitHandle = null;
return true; return true;
} }
@ -144,10 +158,11 @@ namespace OpenSim.Region.Environment.Modules
m_fetchesInProgress.Remove(avatarId); m_fetchesInProgress.Remove(avatarId);
waitHandle.Set(); waitHandle.Set();
} }
//waitHandle.Close();
waitHandle = null; waitHandle = null;
return false; return false;
} }
}
} }
private AvatarAppearance CreateDefault(LLUUID avatarId) private AvatarAppearance CreateDefault(LLUUID avatarId)
@ -197,9 +212,11 @@ namespace OpenSim.Region.Environment.Modules
public void Initialise(Scene scene, IConfigSource source) public void Initialise(Scene scene, IConfigSource source)
{ {
scene.RegisterModuleInterface<IAvatarFactory>(this); scene.RegisterModuleInterface<IAvatarFactory>(this);
scene.EventManager.OnNewClient += NewClient; scene.EventManager.OnNewClient += NewClient;
if (m_scene == null) if (m_scene == null)
{ {
m_scene = scene; m_scene = scene;