diff options
author | Melanie | 2012-05-28 02:14:14 +0200 |
---|---|---|
committer | Melanie | 2012-05-28 02:14:14 +0200 |
commit | bbaf450c30a0822c8ffcc40bf75961f2c3c214e4 (patch) | |
tree | 0fd3c5e236f6958156c900a9db5d5c12bdfa4035 /OpenSim | |
parent | Merge branch 'ubitwork' into avination (diff) | |
download | opensim-SC-bbaf450c30a0822c8ffcc40bf75961f2c3c214e4.zip opensim-SC-bbaf450c30a0822c8ffcc40bf75961f2c3c214e4.tar.gz opensim-SC-bbaf450c30a0822c8ffcc40bf75961f2c3c214e4.tar.bz2 opensim-SC-bbaf450c30a0822c8ffcc40bf75961f2c3c214e4.tar.xz |
Modify SceneManeger to use a DoubleDictionary and work without locks.
Changes to the scenes dictionary are exceedingly rare and using atomic
operations makes the chance of collisions nearly nil in any case.
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneManager.cs | 266 |
1 files changed, 90 insertions, 176 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index e4eaf3a..e3fed49 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs | |||
@@ -53,12 +53,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
53 | get { return m_instance; } | 53 | get { return m_instance; } |
54 | } | 54 | } |
55 | 55 | ||
56 | private readonly List<Scene> m_localScenes = new List<Scene>(); | 56 | private readonly DoubleDictionary<UUID, string, Scene> m_localScenes = new DoubleDictionary<UUID, string, Scene>(); |
57 | private Scene m_currentScene = null; | 57 | private Scene m_currentScene = null; |
58 | 58 | ||
59 | public List<Scene> Scenes | 59 | public List<Scene> Scenes |
60 | { | 60 | { |
61 | get { return new List<Scene>(m_localScenes); } | 61 | get { return new List<Scene>(m_localScenes.FindAll(delegate(Scene s) { return true; })); } |
62 | } | 62 | } |
63 | 63 | ||
64 | public Scene CurrentScene | 64 | public Scene CurrentScene |
@@ -72,13 +72,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
72 | { | 72 | { |
73 | if (m_currentScene == null) | 73 | if (m_currentScene == null) |
74 | { | 74 | { |
75 | lock (m_localScenes) | 75 | List<Scene> sceneList = Scenes; |
76 | { | 76 | if (sceneList.Count == 0) |
77 | if (m_localScenes.Count > 0) | 77 | return null; |
78 | return m_localScenes[0]; | 78 | return sceneList[0]; |
79 | else | ||
80 | return null; | ||
81 | } | ||
82 | } | 79 | } |
83 | else | 80 | else |
84 | { | 81 | { |
@@ -90,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
90 | public SceneManager() | 87 | public SceneManager() |
91 | { | 88 | { |
92 | m_instance = this; | 89 | m_instance = this; |
93 | m_localScenes = new List<Scene>(); | 90 | m_localScenes = new DoubleDictionary<UUID, string, Scene>(); |
94 | } | 91 | } |
95 | 92 | ||
96 | public void Close() | 93 | public void Close() |
@@ -98,20 +95,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
98 | // collect known shared modules in sharedModules | 95 | // collect known shared modules in sharedModules |
99 | Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); | 96 | Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); |
100 | 97 | ||
101 | lock (m_localScenes) | 98 | List<Scene> sceneList = Scenes; |
99 | for (int i = 0; i < sceneList.Count; i++) | ||
102 | { | 100 | { |
103 | for (int i = 0; i < m_localScenes.Count; i++) | 101 | // extract known shared modules from scene |
102 | foreach (string k in sceneList[i].Modules.Keys) | ||
104 | { | 103 | { |
105 | // extract known shared modules from scene | 104 | if (sceneList[i].Modules[k].IsSharedModule && |
106 | foreach (string k in m_localScenes[i].Modules.Keys) | 105 | !sharedModules.ContainsKey(k)) |
107 | { | 106 | sharedModules[k] = sceneList[i].Modules[k]; |
108 | if (m_localScenes[i].Modules[k].IsSharedModule && | ||
109 | !sharedModules.ContainsKey(k)) | ||
110 | sharedModules[k] = m_localScenes[i].Modules[k]; | ||
111 | } | ||
112 | // close scene/region | ||
113 | m_localScenes[i].Close(); | ||
114 | } | 107 | } |
108 | // close scene/region | ||
109 | sceneList[i].Close(); | ||
115 | } | 110 | } |
116 | 111 | ||
117 | // all regions/scenes are now closed, we can now safely | 112 | // all regions/scenes are now closed, we can now safely |
@@ -120,31 +115,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
120 | { | 115 | { |
121 | mod.Close(); | 116 | mod.Close(); |
122 | } | 117 | } |
118 | |||
119 | m_localScenes.Clear(); | ||
123 | } | 120 | } |
124 | 121 | ||
125 | public void Close(Scene cscene) | 122 | public void Close(Scene cscene) |
126 | { | 123 | { |
127 | lock (m_localScenes) | 124 | if (!m_localScenes.ContainsKey(cscene.RegionInfo.RegionID)) |
128 | { | 125 | return; |
129 | if (m_localScenes.Contains(cscene)) | 126 | cscene.Close(); |
130 | { | ||
131 | for (int i = 0; i < m_localScenes.Count; i++) | ||
132 | { | ||
133 | if (m_localScenes[i].Equals(cscene)) | ||
134 | { | ||
135 | m_localScenes[i].Close(); | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | } | 127 | } |
141 | 128 | ||
142 | public void Add(Scene scene) | 129 | public void Add(Scene scene) |
143 | { | 130 | { |
144 | scene.OnRestart += HandleRestart; | 131 | scene.OnRestart += HandleRestart; |
145 | 132 | ||
146 | lock (m_localScenes) | 133 | m_localScenes.Add(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, scene); |
147 | m_localScenes.Add(scene); | ||
148 | } | 134 | } |
149 | 135 | ||
150 | public void HandleRestart(RegionInfo rdata) | 136 | public void HandleRestart(RegionInfo rdata) |
@@ -152,24 +138,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
152 | m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); | 138 | m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); |
153 | int RegionSceneElement = -1; | 139 | int RegionSceneElement = -1; |
154 | 140 | ||
155 | lock (m_localScenes) | 141 | m_localScenes.Remove(rdata.RegionID); |
156 | { | ||
157 | for (int i = 0; i < m_localScenes.Count; i++) | ||
158 | { | ||
159 | if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) | ||
160 | { | ||
161 | RegionSceneElement = i; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | // Now we make sure the region is no longer known about by the SceneManager | ||
166 | // Prevents duplicates. | ||
167 | |||
168 | if (RegionSceneElement >= 0) | ||
169 | { | ||
170 | m_localScenes.RemoveAt(RegionSceneElement); | ||
171 | } | ||
172 | } | ||
173 | 142 | ||
174 | // Send signal to main that we're restarting this sim. | 143 | // Send signal to main that we're restarting this sim. |
175 | OnRestartSim(rdata); | 144 | OnRestartSim(rdata); |
@@ -179,32 +148,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
179 | { | 148 | { |
180 | RegionInfo Result = null; | 149 | RegionInfo Result = null; |
181 | 150 | ||
182 | lock (m_localScenes) | 151 | Scene s = m_localScenes.FindValue(delegate(Scene x) |
183 | { | ||
184 | for (int i = 0; i < m_localScenes.Count; i++) | ||
185 | { | ||
186 | if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle) | ||
187 | { | 152 | { |
188 | // Inform other regions to tell their avatar about me | 153 | if (x.RegionInfo.RegionHandle == regionHandle) |
189 | Result = m_localScenes[i].RegionInfo; | 154 | return true; |
190 | } | 155 | return false; |
191 | } | 156 | }); |
192 | 157 | ||
193 | if (Result != null) | 158 | if (s != null) |
159 | { | ||
160 | List<Scene> sceneList = Scenes; | ||
161 | |||
162 | for (int i = 0; i < sceneList.Count; i++) | ||
194 | { | 163 | { |
195 | for (int i = 0; i < m_localScenes.Count; i++) | 164 | if (sceneList[i]!= s) |
196 | { | 165 | { |
197 | if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) | 166 | // Inform other regions to tell their avatar about me |
198 | { | 167 | //sceneList[i].OtherRegionUp(Result); |
199 | // Inform other regions to tell their avatar about me | ||
200 | //m_localScenes[i].OtherRegionUp(Result); | ||
201 | } | ||
202 | } | 168 | } |
203 | } | 169 | } |
204 | else | 170 | } |
205 | { | 171 | else |
206 | m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); | 172 | { |
207 | } | 173 | m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); |
208 | } | 174 | } |
209 | } | 175 | } |
210 | 176 | ||
@@ -308,8 +274,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
308 | { | 274 | { |
309 | if (m_currentScene == null) | 275 | if (m_currentScene == null) |
310 | { | 276 | { |
311 | lock (m_localScenes) | 277 | List<Scene> sceneList = Scenes; |
312 | m_localScenes.ForEach(func); | 278 | sceneList.ForEach(func); |
313 | } | 279 | } |
314 | else | 280 | else |
315 | { | 281 | { |
@@ -338,16 +304,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
338 | } | 304 | } |
339 | else | 305 | else |
340 | { | 306 | { |
341 | lock (m_localScenes) | 307 | Scene s; |
308 | |||
309 | if (m_localScenes.TryGetValue(regionName, out s)) | ||
342 | { | 310 | { |
343 | foreach (Scene scene in m_localScenes) | 311 | m_currentScene = s; |
344 | { | 312 | return true; |
345 | if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) | ||
346 | { | ||
347 | m_currentScene = scene; | ||
348 | return true; | ||
349 | } | ||
350 | } | ||
351 | } | 313 | } |
352 | 314 | ||
353 | return false; | 315 | return false; |
@@ -358,16 +320,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
358 | { | 320 | { |
359 | // m_log.Debug("Searching for Region: '" + regionID + "'"); | 321 | // m_log.Debug("Searching for Region: '" + regionID + "'"); |
360 | 322 | ||
361 | lock (m_localScenes) | 323 | Scene s; |
324 | |||
325 | if (m_localScenes.TryGetValue(regionID, out s)) | ||
362 | { | 326 | { |
363 | foreach (Scene scene in m_localScenes) | 327 | m_currentScene = s; |
364 | { | 328 | return true; |
365 | if (scene.RegionInfo.RegionID == regionID) | ||
366 | { | ||
367 | m_currentScene = scene; | ||
368 | return true; | ||
369 | } | ||
370 | } | ||
371 | } | 329 | } |
372 | 330 | ||
373 | return false; | 331 | return false; |
@@ -375,52 +333,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
375 | 333 | ||
376 | public bool TryGetScene(string regionName, out Scene scene) | 334 | public bool TryGetScene(string regionName, out Scene scene) |
377 | { | 335 | { |
378 | lock (m_localScenes) | 336 | return m_localScenes.TryGetValue(regionName, out scene); |
379 | { | ||
380 | foreach (Scene mscene in m_localScenes) | ||
381 | { | ||
382 | if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) | ||
383 | { | ||
384 | scene = mscene; | ||
385 | return true; | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | |||
390 | scene = null; | ||
391 | return false; | ||
392 | } | 337 | } |
393 | 338 | ||
394 | public bool TryGetScene(UUID regionID, out Scene scene) | 339 | public bool TryGetScene(UUID regionID, out Scene scene) |
395 | { | 340 | { |
396 | lock (m_localScenes) | 341 | return m_localScenes.TryGetValue(regionID, out scene); |
397 | { | ||
398 | foreach (Scene mscene in m_localScenes) | ||
399 | { | ||
400 | if (mscene.RegionInfo.RegionID == regionID) | ||
401 | { | ||
402 | scene = mscene; | ||
403 | return true; | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | scene = null; | ||
409 | return false; | ||
410 | } | 342 | } |
411 | 343 | ||
412 | public bool TryGetScene(uint locX, uint locY, out Scene scene) | 344 | public bool TryGetScene(uint locX, uint locY, out Scene scene) |
413 | { | 345 | { |
414 | lock (m_localScenes) | 346 | List<Scene> sceneList = Scenes; |
347 | foreach (Scene mscene in sceneList) | ||
415 | { | 348 | { |
416 | foreach (Scene mscene in m_localScenes) | 349 | if (mscene.RegionInfo.RegionLocX == locX && |
350 | mscene.RegionInfo.RegionLocY == locY) | ||
417 | { | 351 | { |
418 | if (mscene.RegionInfo.RegionLocX == locX && | 352 | scene = mscene; |
419 | mscene.RegionInfo.RegionLocY == locY) | 353 | return true; |
420 | { | ||
421 | scene = mscene; | ||
422 | return true; | ||
423 | } | ||
424 | } | 354 | } |
425 | } | 355 | } |
426 | 356 | ||
@@ -430,16 +360,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
430 | 360 | ||
431 | public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) | 361 | public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) |
432 | { | 362 | { |
433 | lock (m_localScenes) | 363 | List<Scene> sceneList = Scenes; |
364 | foreach (Scene mscene in sceneList) | ||
434 | { | 365 | { |
435 | foreach (Scene mscene in m_localScenes) | 366 | if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && |
367 | (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) | ||
436 | { | 368 | { |
437 | if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && | 369 | scene = mscene; |
438 | (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) | 370 | return true; |
439 | { | ||
440 | scene = mscene; | ||
441 | return true; | ||
442 | } | ||
443 | } | 371 | } |
444 | } | 372 | } |
445 | 373 | ||
@@ -504,15 +432,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
504 | 432 | ||
505 | public RegionInfo GetRegionInfo(UUID regionID) | 433 | public RegionInfo GetRegionInfo(UUID regionID) |
506 | { | 434 | { |
507 | lock (m_localScenes) | 435 | Scene s; |
436 | if (m_localScenes.TryGetValue(regionID, out s)) | ||
508 | { | 437 | { |
509 | foreach (Scene scene in m_localScenes) | 438 | return s.RegionInfo; |
510 | { | ||
511 | if (scene.RegionInfo.RegionID == regionID) | ||
512 | { | ||
513 | return scene.RegionInfo; | ||
514 | } | ||
515 | } | ||
516 | } | 439 | } |
517 | 440 | ||
518 | return null; | 441 | return null; |
@@ -530,14 +453,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
530 | 453 | ||
531 | public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) | 454 | public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) |
532 | { | 455 | { |
533 | lock (m_localScenes) | 456 | List<Scene> sceneList = Scenes; |
457 | foreach (Scene scene in sceneList) | ||
534 | { | 458 | { |
535 | foreach (Scene scene in m_localScenes) | 459 | if (scene.TryGetScenePresence(avatarId, out avatar)) |
536 | { | 460 | { |
537 | if (scene.TryGetScenePresence(avatarId, out avatar)) | 461 | return true; |
538 | { | ||
539 | return true; | ||
540 | } | ||
541 | } | 462 | } |
542 | } | 463 | } |
543 | 464 | ||
@@ -547,15 +468,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
547 | 468 | ||
548 | public bool TryGetRootScenePresence(UUID avatarId, out ScenePresence avatar) | 469 | public bool TryGetRootScenePresence(UUID avatarId, out ScenePresence avatar) |
549 | { | 470 | { |
550 | lock (m_localScenes) | 471 | List<Scene> sceneList = Scenes; |
472 | foreach (Scene scene in sceneList) | ||
551 | { | 473 | { |
552 | foreach (Scene scene in m_localScenes) | 474 | avatar = scene.GetScenePresence(avatarId); |
553 | { | ||
554 | avatar = scene.GetScenePresence(avatarId); | ||
555 | 475 | ||
556 | if (avatar != null && !avatar.IsChildAgent) | 476 | if (avatar != null && !avatar.IsChildAgent) |
557 | return true; | 477 | return true; |
558 | } | ||
559 | } | 478 | } |
560 | 479 | ||
561 | avatar = null; | 480 | avatar = null; |
@@ -564,22 +483,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
564 | 483 | ||
565 | public void CloseScene(Scene scene) | 484 | public void CloseScene(Scene scene) |
566 | { | 485 | { |
567 | lock (m_localScenes) | 486 | m_localScenes.Remove(scene.RegionInfo.RegionID); |
568 | m_localScenes.Remove(scene); | ||
569 | 487 | ||
570 | scene.Close(); | 488 | scene.Close(); |
571 | } | 489 | } |
572 | 490 | ||
573 | public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | 491 | public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) |
574 | { | 492 | { |
575 | lock (m_localScenes) | 493 | List<Scene> sceneList = Scenes; |
494 | foreach (Scene scene in sceneList) | ||
576 | { | 495 | { |
577 | foreach (Scene scene in m_localScenes) | 496 | if (scene.TryGetAvatarByName(avatarName, out avatar)) |
578 | { | 497 | { |
579 | if (scene.TryGetAvatarByName(avatarName, out avatar)) | 498 | return true; |
580 | { | ||
581 | return true; | ||
582 | } | ||
583 | } | 499 | } |
584 | } | 500 | } |
585 | 501 | ||
@@ -589,14 +505,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
589 | 505 | ||
590 | public bool TryGetRootScenePresenceByName(string firstName, string lastName, out ScenePresence sp) | 506 | public bool TryGetRootScenePresenceByName(string firstName, string lastName, out ScenePresence sp) |
591 | { | 507 | { |
592 | lock (m_localScenes) | 508 | List<Scene> sceneList = Scenes; |
509 | foreach (Scene scene in sceneList) | ||
593 | { | 510 | { |
594 | foreach (Scene scene in m_localScenes) | 511 | sp = scene.GetScenePresence(firstName, lastName); |
595 | { | 512 | if (sp != null && !sp.IsChildAgent) |
596 | sp = scene.GetScenePresence(firstName, lastName); | 513 | return true; |
597 | if (sp != null && !sp.IsChildAgent) | ||
598 | return true; | ||
599 | } | ||
600 | } | 514 | } |
601 | 515 | ||
602 | sp = null; | 516 | sp = null; |
@@ -605,8 +519,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
605 | 519 | ||
606 | public void ForEachScene(Action<Scene> action) | 520 | public void ForEachScene(Action<Scene> action) |
607 | { | 521 | { |
608 | lock (m_localScenes) | 522 | List<Scene> sceneList = Scenes; |
609 | m_localScenes.ForEach(action); | 523 | sceneList.ForEach(action); |
610 | } | 524 | } |
611 | } | 525 | } |
612 | } | 526 | } |