diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 71 |
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); |