aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMW2008-02-14 18:59:03 +0000
committerMW2008-02-14 18:59:03 +0000
commit8ad450f83e70a45b79d9b058bf46854c7168a69c (patch)
tree3da8f1a76a56830250f63fc77b21dc55055b86a9 /OpenSim
parent* Fixed accessibility problem on ITerrainChannel (diff)
downloadopensim-SC-8ad450f83e70a45b79d9b058bf46854c7168a69c.zip
opensim-SC-8ad450f83e70a45b79d9b058bf46854c7168a69c.tar.gz
opensim-SC-8ad450f83e70a45b79d9b058bf46854c7168a69c.tar.bz2
opensim-SC-8ad450f83e70a45b79d9b058bf46854c7168a69c.tar.xz
More work on trying to get AvatarFactoryModule to play nicely with multiple threads
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs143
1 files changed, 80 insertions, 63 deletions
diff --git a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs
index 7933593..f43657c 100644
--- a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs
+++ b/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs
@@ -57,34 +57,27 @@ namespace OpenSim.Region.Environment.Modules
57 57
58 public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) 58 public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance)
59 { 59 {
60 appearance = CheckCache(avatarId); 60
61 if (appearance != null)
62 {
63 return true;
64 }
65
66 //not in cache so check to see if another thread is already fetching it
67 //should only let one thread at a time do this part 61 //should only let one thread at a time do this part
68 EventWaitHandle waitHandle = null; 62 EventWaitHandle waitHandle = null;
63 bool fetchInProgress = false;
69 lock (m_syncLock) 64 lock (m_syncLock)
70 { 65 {
66 appearance = CheckCache(avatarId);
67 if (appearance != null)
68 {
69 return true;
70 }
71
72 //not in cache so check to see if another thread is already fetching it
71 if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) 73 if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle))
72 { 74 {
73 waitHandle.WaitOne(); 75 fetchInProgress = true;
74 appearance = CheckCache(avatarId);
75 if (appearance != null)
76 {
77 waitHandle = null;
78 return true;
79 }
80 else
81 {
82 waitHandle = null;
83 return false;
84 }
85 } 76 }
86 else 77 else
87 { 78 {
79 fetchInProgress = false;
80
88 //no thread already fetching this appearance, so add a wait handle to list 81 //no thread already fetching this appearance, so add a wait handle to list
89 //for any following threads that want the same appearance 82 //for any following threads that want the same appearance
90 waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); 83 waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
@@ -92,62 +85,84 @@ namespace OpenSim.Region.Environment.Modules
92 } 85 }
93 } 86 }
94 87
95 88 if (fetchInProgress)
96 //this is the first thread to request this appearance
97 //so let it check the db and if not found then create a default appearance
98 //and add that to the cache
99 appearance = CheckDatabase(avatarId);
100 if (appearance != null)
101 { 89 {
102 //appearance has now been added to cache so lets pulse any waiting threads 90 waitHandle.WaitOne();
103 lock (m_syncLock) 91 appearance = CheckCache(avatarId);
92 if (appearance != null)
104 { 93 {
105 m_fetchesInProgress.Remove(avatarId); 94 waitHandle = null;
106 waitHandle.Set(); 95 return true;
107 } 96 }
108 waitHandle = null; 97 else
109 return true;
110 }
111
112 //not found a appearance for the user, so create a new default one
113 appearance = CreateDefault(avatarId);
114 if (appearance != null)
115 {
116 //update database
117 if (m_enablePersist)
118 { 98 {
119 m_appearanceMapper.Add(avatarId.UUID, appearance); 99 waitHandle = null;
100 return false;
120 } 101 }
121 102
122 //add appearance to dictionary cache 103 }
123 lock (m_avatarsAppearance) 104 else
105 {
106 Thread.Sleep(5000);
107
108 //this is the first thread to request this appearance
109 //so let it check the db and if not found then create a default appearance
110 //and add that to the cache
111 appearance = CheckDatabase(avatarId);
112 if (appearance != null)
124 { 113 {
125 m_avatarsAppearance[avatarId] = appearance; 114 //appearance has now been added to cache so lets pulse any waiting threads
115 lock (m_syncLock)
116 {
117 m_fetchesInProgress.Remove(avatarId);
118 waitHandle.Set();
119 }
120 // waitHandle.Close();
121 waitHandle = null;
122 return true;
126 } 123 }
127 124
128 //appearance has now been added to cache so lets pulse any waiting threads 125 //not found a appearance for the user, so create a new default one
129 lock (m_syncLock) 126 appearance = CreateDefault(avatarId);
127 if (appearance != null)
130 { 128 {
131 m_fetchesInProgress.Remove(avatarId); 129 //update database
132 waitHandle.Set(); 130 if (m_enablePersist)
131 {
132 m_appearanceMapper.Add(avatarId.UUID, appearance);
133 }
134
135 //add appearance to dictionary cache
136 lock (m_avatarsAppearance)
137 {
138 m_avatarsAppearance[avatarId] = appearance;
139 }
140
141 //appearance has now been added to cache so lets pulse any waiting threads
142 lock (m_syncLock)
143 {
144 m_fetchesInProgress.Remove(avatarId);
145 waitHandle.Set();
146 }
147 // waitHandle.Close();
148 waitHandle = null;
149 return true;
133 } 150 }
134 waitHandle = null; 151 else
135 return true;
136 }
137 else
138 {
139 //something went wrong, so release the wait handle and remove it
140 //all waiting threads will fail to find cached appearance
141 //but its better for them to fail than wait for ever
142 lock (m_syncLock)
143 { 152 {
144 m_fetchesInProgress.Remove(avatarId); 153 //something went wrong, so release the wait handle and remove it
145 waitHandle.Set(); 154 //all waiting threads will fail to find cached appearance
155 //but its better for them to fail than wait for ever
156 lock (m_syncLock)
157 {
158 m_fetchesInProgress.Remove(avatarId);
159 waitHandle.Set();
160 }
161 //waitHandle.Close();
162 waitHandle = null;
163 return false;
146 } 164 }
147 waitHandle = null;
148 return false;
149 } 165 }
150
151 } 166 }
152 167
153 private AvatarAppearance CreateDefault(LLUUID avatarId) 168 private AvatarAppearance CreateDefault(LLUUID avatarId)
@@ -197,8 +212,10 @@ namespace OpenSim.Region.Environment.Modules
197 212
198 public void Initialise(Scene scene, IConfigSource source) 213 public void Initialise(Scene scene, IConfigSource source)
199 { 214 {
200 scene.RegisterModuleInterface<IAvatarFactory>(this); 215
201 scene.EventManager.OnNewClient += NewClient; 216 scene.RegisterModuleInterface<IAvatarFactory>(this);
217 scene.EventManager.OnNewClient += NewClient;
218
202 219
203 if (m_scene == null) 220 if (m_scene == null)
204 { 221 {