diff Implab/AbstractEvent.cs @ 156:97fbbf816844 v2

Promises: SignalXXX methods merged into SignalHandler method. Components: RunnableComponent In progress
author cin
date Mon, 15 Feb 2016 04:22:15 +0300
parents e6d4b41f0101
children 5802131432e4
line wrap: on
line diff
--- a/Implab/AbstractEvent.cs	Fri Feb 12 16:24:24 2016 +0300
+++ b/Implab/AbstractEvent.cs	Mon Feb 15 04:22:15 2016 +0300
@@ -8,9 +8,9 @@
 
         const int UNRESOLVED_SATE = 0;
         const int TRANSITIONAL_STATE = 1;
-        const int SUCCEEDED_STATE = 2;
-        const int REJECTED_STATE = 3;
-        const int CANCELLED_STATE = 4;
+        protected const int SUCCEEDED_STATE = 2;
+        protected const int REJECTED_STATE = 3;
+        protected const int CANCELLED_STATE = 4;
 
         const int CANCEL_NOT_REQUESTED = 0;
         const int CANCEL_REQUESTING = 1;
@@ -22,7 +22,8 @@
         Exception m_error;
         int m_handlersCount;
 
-        readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT];
+        //readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT];
+        THandler[] m_handlers;
         MTQueue<THandler> m_extraHandlers;
         int m_handlerPointer = -1;
         int m_handlersCommited;
@@ -60,7 +61,7 @@
 
         protected void EndSetResult() {
             CompleteTransit(SUCCEEDED_STATE);
-            OnSuccess();
+            Signal();
         }
 
 
@@ -78,14 +79,13 @@
         protected void SetError(Exception error) {
             if (BeginTransit()) {
                 if (error is OperationCanceledException) {
+                    m_error = error.InnerException;
                     CompleteTransit(CANCELLED_STATE);
-                    m_error = error.InnerException;
-                    OnCancelled();
                 } else {
                     m_error = error is PromiseTransientException ? error.InnerException : error;
                     CompleteTransit(REJECTED_STATE);
-                    OnError();
                 }
+                Signal();
             } else {
                 WaitTransition();
                 if (m_state == SUCCEEDED_STATE)
@@ -101,22 +101,18 @@
             if (BeginTransit()) {
                 m_error = reason;
                 CompleteTransit(CANCELLED_STATE);
-                OnCancelled();
+                Signal();
             }
         }
 
-        protected abstract void SignalSuccess(THandler handler);
-
-        protected abstract void SignalError(THandler handler, Exception error);
+        protected abstract void SignalHandler(THandler handler, int signal);
 
-        protected abstract void SignalCancelled(THandler handler, Exception reason);
-
-        void OnSuccess() {
+        void Signal() {
             var hp = m_handlerPointer;
             var slot = hp +1 ;
             while (slot < m_handlersCommited) {
                 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
-                    SignalSuccess(m_handlers[slot]);
+                    SignalHandler(m_handlers[slot], m_state);
                 }
                 hp = m_handlerPointer;
                 slot = hp +1 ;
@@ -126,43 +122,7 @@
             if (m_extraHandlers != null) {
                 THandler handler;
                 while (m_extraHandlers.TryDequeue(out handler))
-                    SignalSuccess(handler);
-            }
-        }
-
-        void OnError() {
-            var hp = m_handlerPointer;
-            var slot = hp +1 ;
-            while (slot < m_handlersCommited) {
-                if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
-                    SignalError(m_handlers[slot],m_error);
-                }
-                hp = m_handlerPointer;
-                slot = hp +1 ;
-            }
-
-            if (m_extraHandlers != null) {
-                THandler handler;
-                while (m_extraHandlers.TryDequeue(out handler))
-                    SignalError(handler, m_error);
-            }
-        }
-
-        void OnCancelled() {
-            var hp = m_handlerPointer;
-            var slot = hp +1 ;
-            while (slot < m_handlersCommited) {
-                if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) {
-                    SignalCancelled(m_handlers[slot], m_error);
-                }
-                hp = m_handlerPointer;
-                slot = hp +1 ;
-            }
-
-            if (m_extraHandlers != null) {
-                THandler handler;
-                while (m_extraHandlers.TryDequeue(out handler))
-                    SignalCancelled(handler, m_error);
+                    SignalHandler(handler, m_state);
             }
         }
 
@@ -194,12 +154,15 @@
 
             if (m_state > 1) {
                 // the promise is in the resolved state, just invoke the handler
-                InvokeHandler(handler);
+                SignalHandler(handler, m_state);
             } else {
                 var slot = Interlocked.Increment(ref m_handlersCount) - 1;
 
                 if (slot < RESERVED_HANDLERS_COUNT) {
 
+                    if (slot == 0)
+                        Interlocked.CompareExchange(ref m_handlers, new THandler[RESERVED_HANDLERS_COUNT], null);
+
                     m_handlers[slot] = handler;
 
                     while (slot != Interlocked.CompareExchange(ref m_handlersCommited, slot + 1, slot)) {
@@ -212,7 +175,7 @@
                             if (slot < m_handlersCommited) {
                                 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) != hp)
                                     continue;
-                                InvokeHandler(m_handlers[slot]);
+                                SignalHandler(m_handlers[slot], m_state);
                             }
                             break;
                         } while(true);
@@ -233,27 +196,11 @@
                     // therefore we need to fetch a handler from the queue and execute it
                     // note that fetched handler may be not the one that we have added
                     // even we can fetch no handlers at all :)
-                    InvokeHandler(handler);
+                        SignalHandler(handler, m_state);
                 }
             }
         }
 
-        protected void InvokeHandler(THandler handler) {
-            switch (m_state) {
-                case SUCCEEDED_STATE:
-                    SignalSuccess(handler);
-                    break;
-                case CANCELLED_STATE:
-                    SignalCancelled(handler, m_error);
-                    break;
-                case REJECTED_STATE:
-                    SignalError(handler, m_error);
-                    break;
-                default:
-                    throw new Exception(String.Format("Invalid promise state {0}", m_state));
-            }
-        }
-
         #endregion
 
         #region IPromise implementation