aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMike Rieker2010-04-18 19:19:16 -0400
committerMike Rieker2010-04-18 19:19:16 -0400
commit68a4f897b4f39e46c291d180db5062725130392d (patch)
tree77e04f7c8cebc375bb547d923657c69301993c1f /OpenSim/Region
parentCommitting sacha's partial work (from orpheus). The GridBrat needs to learn (diff)
downloadopensim-SC-68a4f897b4f39e46c291d180db5062725130392d.zip
opensim-SC-68a4f897b4f39e46c291d180db5062725130392d.tar.gz
opensim-SC-68a4f897b4f39e46c291d180db5062725130392d.tar.bz2
opensim-SC-68a4f897b4f39e46c291d180db5062725130392d.tar.xz
This GetScriptErrors() change allows initial XEngine to run in background
thread. It should block only for the case of being called by CapsUpdateTaskInventoryScriptAsset().
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs71
1 files changed, 65 insertions, 6 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index d03b464..a2fceb7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -290,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes
290 m_items.LockItemsForWrite(false); 290 m_items.LockItemsForWrite(false);
291 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 291 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
292 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 292 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
293 StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); 293 StoreScriptErrors(item.ItemID, null);
294 m_part.ParentGroup.AddActiveScriptCount(1); 294 m_part.ParentGroup.AddActiveScriptCount(1);
295 m_part.ScheduleFullUpdate(); 295 m_part.ScheduleFullUpdate();
296 return; 296 return;
@@ -319,7 +319,7 @@ namespace OpenSim.Region.Framework.Scenes
319 string script = Utils.BytesToString(asset.Data); 319 string script = Utils.BytesToString(asset.Data);
320 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 320 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
321 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 321 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
322 StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); 322 StoreScriptErrors(item.ItemID, null);
323 m_part.ParentGroup.AddActiveScriptCount(1); 323 m_part.ParentGroup.AddActiveScriptCount(1);
324 m_part.ScheduleFullUpdate(); 324 m_part.ScheduleFullUpdate();
325 } 325 }
@@ -388,12 +388,23 @@ namespace OpenSim.Region.Framework.Scenes
388 388
389 /// <summary> 389 /// <summary>
390 /// Start a script which is in this prim's inventory. 390 /// Start a script which is in this prim's inventory.
391 /// Some processing may occur in the background, but this routine returns asap.
391 /// </summary> 392 /// </summary>
392 /// <param name="itemId"> 393 /// <param name="itemId">
393 /// A <see cref="UUID"/> 394 /// A <see cref="UUID"/>
394 /// </param> 395 /// </param>
395 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 396 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
396 { 397 {
398 lock (m_scriptErrors)
399 {
400 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
401 m_scriptErrors.Remove(itemId);
402 }
403 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
404 }
405
406 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
407 {
397 m_items.LockItemsForRead(true); 408 m_items.LockItemsForRead(true);
398 if (m_items.ContainsKey(itemId)) 409 if (m_items.ContainsKey(itemId))
399 { 410 {
@@ -425,25 +436,38 @@ namespace OpenSim.Region.Framework.Scenes
425 436
426 } 437 }
427 438
439 /// <summary>
440 /// Start a script which is in this prim's inventory and return any compilation error messages.
441 /// </summary>
442 /// <param name="itemId">
443 /// A <see cref="UUID"/>
444 /// </param>
428 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 445 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
429 { 446 {
430 ArrayList errors; 447 ArrayList errors;
431 448
449 // Indicate to CreateScriptInstanceInternal() we want it to
450 // post any compilation/loading error messages
432 lock (m_scriptErrors) 451 lock (m_scriptErrors)
433 { 452 {
434 m_scriptErrors.Remove(itemId); 453 m_scriptErrors[itemId] = null;
435 } 454 }
436 CreateScriptInstance(itemId, startParam, postOnRez, engine, stateSource); 455
456 // Perform compilation/loading
457 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
458
459 // Wait for and retrieve any errors
437 lock (m_scriptErrors) 460 lock (m_scriptErrors)
438 { 461 {
439 while (!m_scriptErrors.TryGetValue(itemId, out errors)) 462 while ((errors = m_scriptErrors[itemId]) == null)
440 { 463 {
441 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) 464 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
442 { 465 {
443 m_log.ErrorFormat( 466 m_log.ErrorFormat(
444 "[PRIM INVENTORY]: " + 467 "[PRIM INVENTORY]: " +
445 "timedout waiting for script {0} errors", itemId); 468 "timedout waiting for script {0} errors", itemId);
446 if (!m_scriptErrors.TryGetValue(itemId, out errors)) 469 errors = m_scriptErrors[itemId];
470 if (errors == null)
447 { 471 {
448 errors = new ArrayList(1); 472 errors = new ArrayList(1);
449 errors.Add("timedout waiting for errors"); 473 errors.Add("timedout waiting for errors");
@@ -455,14 +479,49 @@ namespace OpenSim.Region.Framework.Scenes
455 } 479 }
456 return errors; 480 return errors;
457 } 481 }
482
483 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
458 private void StoreScriptErrors(UUID itemId, ArrayList errors) 484 private void StoreScriptErrors(UUID itemId, ArrayList errors)
459 { 485 {
460 lock (m_scriptErrors) 486 lock (m_scriptErrors)
461 { 487 {
488 // If compilation/loading initiated via CreateScriptInstance(),
489 // it does not want the errors, so just get out
490 if (!m_scriptErrors.ContainsKey(itemId))
491 {
492 return;
493 }
494
495 // Initiated via CreateScriptInstanceEr(), if we know what the
496 // errors are, save them and wake CreateScriptInstanceEr().
497 if (errors != null)
498 {
499 m_scriptErrors[itemId] = errors;
500 System.Threading.Monitor.PulseAll(m_scriptErrors);
501 return;
502 }
503 }
504
505 // Initiated via CreateScriptInstanceEr() but we don't know what
506 // the errors are yet, so retrieve them from the script engine.
507 // This may involve some waiting internal to GetScriptErrors().
508 errors = GetScriptErrors(itemId);
509
510 // Get a default non-null value to indicate success.
511 if (errors == null)
512 {
513 errors = new ArrayList();
514 }
515
516 // Post to CreateScriptInstanceEr() and wake it up
517 lock (m_scriptErrors)
518 {
462 m_scriptErrors[itemId] = errors; 519 m_scriptErrors[itemId] = errors;
463 System.Threading.Monitor.PulseAll(m_scriptErrors); 520 System.Threading.Monitor.PulseAll(m_scriptErrors);
464 } 521 }
465 } 522 }
523
524 // Like StoreScriptErrors(), but just posts a single string message
466 private void StoreScriptError(UUID itemId, string message) 525 private void StoreScriptError(UUID itemId, string message)
467 { 526 {
468 ArrayList errors = new ArrayList(1); 527 ArrayList errors = new ArrayList(1);