diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/RestClient.cs (renamed from OpenSim/Framework/Communications/RestClient.cs) | 156 |
1 files changed, 155 insertions, 1 deletions
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/RestClient.cs index 807222b..ca19392 100644 --- a/OpenSim/Framework/Communications/RestClient.cs +++ b/OpenSim/Framework/RestClient.cs | |||
@@ -37,7 +37,7 @@ using log4net; | |||
37 | 37 | ||
38 | using OpenSim.Framework.ServiceAuth; | 38 | using OpenSim.Framework.ServiceAuth; |
39 | 39 | ||
40 | namespace OpenSim.Framework.Communications | 40 | namespace OpenSim.Framework |
41 | { | 41 | { |
42 | /// <summary> | 42 | /// <summary> |
43 | /// Implementation of a generic REST client | 43 | /// Implementation of a generic REST client |
@@ -524,4 +524,158 @@ namespace OpenSim.Framework.Communications | |||
524 | 524 | ||
525 | #endregion Async Invocation | 525 | #endregion Async Invocation |
526 | } | 526 | } |
527 | |||
528 | internal class SimpleAsyncResult : IAsyncResult | ||
529 | { | ||
530 | private readonly AsyncCallback m_callback; | ||
531 | |||
532 | /// <summary> | ||
533 | /// Is process completed? | ||
534 | /// </summary> | ||
535 | /// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks> | ||
536 | private byte m_completed; | ||
537 | |||
538 | /// <summary> | ||
539 | /// Did process complete synchronously? | ||
540 | /// </summary> | ||
541 | /// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about | ||
542 | /// booleans and VolatileRead as m_completed | ||
543 | /// </remarks> | ||
544 | private byte m_completedSynchronously; | ||
545 | |||
546 | private readonly object m_asyncState; | ||
547 | private ManualResetEvent m_waitHandle; | ||
548 | private Exception m_exception; | ||
549 | |||
550 | internal SimpleAsyncResult(AsyncCallback cb, object state) | ||
551 | { | ||
552 | m_callback = cb; | ||
553 | m_asyncState = state; | ||
554 | m_completed = 0; | ||
555 | m_completedSynchronously = 1; | ||
556 | } | ||
557 | |||
558 | #region IAsyncResult Members | ||
559 | |||
560 | public object AsyncState | ||
561 | { | ||
562 | get { return m_asyncState; } | ||
563 | } | ||
564 | |||
565 | public WaitHandle AsyncWaitHandle | ||
566 | { | ||
567 | get | ||
568 | { | ||
569 | if (m_waitHandle == null) | ||
570 | { | ||
571 | bool done = IsCompleted; | ||
572 | ManualResetEvent mre = new ManualResetEvent(done); | ||
573 | if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null) | ||
574 | { | ||
575 | mre.Close(); | ||
576 | } | ||
577 | else | ||
578 | { | ||
579 | if (!done && IsCompleted) | ||
580 | { | ||
581 | m_waitHandle.Set(); | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | |||
586 | return m_waitHandle; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | |||
591 | public bool CompletedSynchronously | ||
592 | { | ||
593 | get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; } | ||
594 | } | ||
595 | |||
596 | |||
597 | public bool IsCompleted | ||
598 | { | ||
599 | get { return Thread.VolatileRead(ref m_completed) == 1; } | ||
600 | } | ||
601 | |||
602 | #endregion | ||
603 | |||
604 | #region class Methods | ||
605 | |||
606 | internal void SetAsCompleted(bool completedSynchronously) | ||
607 | { | ||
608 | m_completed = 1; | ||
609 | if (completedSynchronously) | ||
610 | m_completedSynchronously = 1; | ||
611 | else | ||
612 | m_completedSynchronously = 0; | ||
613 | |||
614 | SignalCompletion(); | ||
615 | } | ||
616 | |||
617 | internal void HandleException(Exception e, bool completedSynchronously) | ||
618 | { | ||
619 | m_completed = 1; | ||
620 | if (completedSynchronously) | ||
621 | m_completedSynchronously = 1; | ||
622 | else | ||
623 | m_completedSynchronously = 0; | ||
624 | m_exception = e; | ||
625 | |||
626 | SignalCompletion(); | ||
627 | } | ||
628 | |||
629 | private void SignalCompletion() | ||
630 | { | ||
631 | if (m_waitHandle != null) m_waitHandle.Set(); | ||
632 | |||
633 | if (m_callback != null) m_callback(this); | ||
634 | } | ||
635 | |||
636 | public void EndInvoke() | ||
637 | { | ||
638 | // This method assumes that only 1 thread calls EndInvoke | ||
639 | if (!IsCompleted) | ||
640 | { | ||
641 | // If the operation isn't done, wait for it | ||
642 | AsyncWaitHandle.WaitOne(); | ||
643 | AsyncWaitHandle.Close(); | ||
644 | m_waitHandle.Close(); | ||
645 | m_waitHandle = null; // Allow early GC | ||
646 | } | ||
647 | |||
648 | // Operation is done: if an exception occured, throw it | ||
649 | if (m_exception != null) throw m_exception; | ||
650 | } | ||
651 | |||
652 | #endregion | ||
653 | } | ||
654 | |||
655 | internal class AsyncResult<T> : SimpleAsyncResult | ||
656 | { | ||
657 | private T m_result = default(T); | ||
658 | |||
659 | public AsyncResult(AsyncCallback asyncCallback, Object state) : | ||
660 | base(asyncCallback, state) | ||
661 | { | ||
662 | } | ||
663 | |||
664 | public void SetAsCompleted(T result, bool completedSynchronously) | ||
665 | { | ||
666 | // Save the asynchronous operation's result | ||
667 | m_result = result; | ||
668 | |||
669 | // Tell the base class that the operation completed | ||
670 | // sucessfully (no exception) | ||
671 | base.SetAsCompleted(completedSynchronously); | ||
672 | } | ||
673 | |||
674 | public new T EndInvoke() | ||
675 | { | ||
676 | base.EndInvoke(); | ||
677 | return m_result; | ||
678 | } | ||
679 | } | ||
680 | |||
527 | } | 681 | } |