diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-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 07d58a1..a1991c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -289,7 +289,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
289 | m_items.LockItemsForWrite(false); | 289 | m_items.LockItemsForWrite(false); |
290 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 290 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
291 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 291 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
292 | StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); | 292 | StoreScriptErrors(item.ItemID, null); |
293 | m_part.ParentGroup.AddActiveScriptCount(1); | 293 | m_part.ParentGroup.AddActiveScriptCount(1); |
294 | m_part.ScheduleFullUpdate(); | 294 | m_part.ScheduleFullUpdate(); |
295 | return; | 295 | return; |
@@ -318,7 +318,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
318 | string script = Utils.BytesToString(asset.Data); | 318 | string script = Utils.BytesToString(asset.Data); |
319 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 319 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
320 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 320 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
321 | StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); | 321 | StoreScriptErrors(item.ItemID, null); |
322 | m_part.ParentGroup.AddActiveScriptCount(1); | 322 | m_part.ParentGroup.AddActiveScriptCount(1); |
323 | m_part.ScheduleFullUpdate(); | 323 | m_part.ScheduleFullUpdate(); |
324 | } | 324 | } |
@@ -387,12 +387,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
387 | 387 | ||
388 | /// <summary> | 388 | /// <summary> |
389 | /// Start a script which is in this prim's inventory. | 389 | /// Start a script which is in this prim's inventory. |
390 | /// Some processing may occur in the background, but this routine returns asap. | ||
390 | /// </summary> | 391 | /// </summary> |
391 | /// <param name="itemId"> | 392 | /// <param name="itemId"> |
392 | /// A <see cref="UUID"/> | 393 | /// A <see cref="UUID"/> |
393 | /// </param> | 394 | /// </param> |
394 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 395 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
395 | { | 396 | { |
397 | lock (m_scriptErrors) | ||
398 | { | ||
399 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion | ||
400 | m_scriptErrors.Remove(itemId); | ||
401 | } | ||
402 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
403 | } | ||
404 | |||
405 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
406 | { | ||
396 | m_items.LockItemsForRead(true); | 407 | m_items.LockItemsForRead(true); |
397 | if (m_items.ContainsKey(itemId)) | 408 | if (m_items.ContainsKey(itemId)) |
398 | { | 409 | { |
@@ -424,25 +435,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
424 | 435 | ||
425 | } | 436 | } |
426 | 437 | ||
438 | /// <summary> | ||
439 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
440 | /// </summary> | ||
441 | /// <param name="itemId"> | ||
442 | /// A <see cref="UUID"/> | ||
443 | /// </param> | ||
427 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 444 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
428 | { | 445 | { |
429 | ArrayList errors; | 446 | ArrayList errors; |
430 | 447 | ||
448 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
449 | // post any compilation/loading error messages | ||
431 | lock (m_scriptErrors) | 450 | lock (m_scriptErrors) |
432 | { | 451 | { |
433 | m_scriptErrors.Remove(itemId); | 452 | m_scriptErrors[itemId] = null; |
434 | } | 453 | } |
435 | CreateScriptInstance(itemId, startParam, postOnRez, engine, stateSource); | 454 | |
455 | // Perform compilation/loading | ||
456 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
457 | |||
458 | // Wait for and retrieve any errors | ||
436 | lock (m_scriptErrors) | 459 | lock (m_scriptErrors) |
437 | { | 460 | { |
438 | while (!m_scriptErrors.TryGetValue(itemId, out errors)) | 461 | while ((errors = m_scriptErrors[itemId]) == null) |
439 | { | 462 | { |
440 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | 463 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) |
441 | { | 464 | { |
442 | m_log.ErrorFormat( | 465 | m_log.ErrorFormat( |
443 | "[PRIM INVENTORY]: " + | 466 | "[PRIM INVENTORY]: " + |
444 | "timedout waiting for script {0} errors", itemId); | 467 | "timedout waiting for script {0} errors", itemId); |
445 | if (!m_scriptErrors.TryGetValue(itemId, out errors)) | 468 | errors = m_scriptErrors[itemId]; |
469 | if (errors == null) | ||
446 | { | 470 | { |
447 | errors = new ArrayList(1); | 471 | errors = new ArrayList(1); |
448 | errors.Add("timedout waiting for errors"); | 472 | errors.Add("timedout waiting for errors"); |
@@ -454,14 +478,49 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | } | 478 | } |
455 | return errors; | 479 | return errors; |
456 | } | 480 | } |
481 | |||
482 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
457 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | 483 | private void StoreScriptErrors(UUID itemId, ArrayList errors) |
458 | { | 484 | { |
459 | lock (m_scriptErrors) | 485 | lock (m_scriptErrors) |
460 | { | 486 | { |
487 | // If compilation/loading initiated via CreateScriptInstance(), | ||
488 | // it does not want the errors, so just get out | ||
489 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
490 | { | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
495 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
496 | if (errors != null) | ||
497 | { | ||
498 | m_scriptErrors[itemId] = errors; | ||
499 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
500 | return; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
505 | // the errors are yet, so retrieve them from the script engine. | ||
506 | // This may involve some waiting internal to GetScriptErrors(). | ||
507 | errors = GetScriptErrors(itemId); | ||
508 | |||
509 | // Get a default non-null value to indicate success. | ||
510 | if (errors == null) | ||
511 | { | ||
512 | errors = new ArrayList(); | ||
513 | } | ||
514 | |||
515 | // Post to CreateScriptInstanceEr() and wake it up | ||
516 | lock (m_scriptErrors) | ||
517 | { | ||
461 | m_scriptErrors[itemId] = errors; | 518 | m_scriptErrors[itemId] = errors; |
462 | System.Threading.Monitor.PulseAll(m_scriptErrors); | 519 | System.Threading.Monitor.PulseAll(m_scriptErrors); |
463 | } | 520 | } |
464 | } | 521 | } |
522 | |||
523 | // Like StoreScriptErrors(), but just posts a single string message | ||
465 | private void StoreScriptError(UUID itemId, string message) | 524 | private void StoreScriptError(UUID itemId, string message) |
466 | { | 525 | { |
467 | ArrayList errors = new ArrayList(1); | 526 | ArrayList errors = new ArrayList(1); |