[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / Execution / EventPump.cs
1 // ***********************************************************************
2 // Copyright (c) 2006-2016 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 #if PARALLEL
30 using System;
31 using System.Threading;
32 using NUnit.Framework.Interfaces;
33
34 namespace NUnit.Framework.Internal.Execution
35 {
36     /// <summary>
37     /// The EventPumpState enum represents the state of an
38     /// EventPump.
39     /// </summary>
40     public enum EventPumpState
41     {
42         /// <summary>
43         /// The pump is stopped
44         /// </summary>
45         Stopped,
46
47         /// <summary>
48         /// The pump is pumping events with no stop requested
49         /// </summary>
50         Pumping,
51
52         /// <summary>
53         /// The pump is pumping events but a stop has been requested
54         /// </summary>
55         Stopping
56     }
57
58     /// <summary>
59     /// EventPump pulls events out of an EventQueue and sends
60     /// them to a listener. It is used to send events back to
61     /// the client without using the CallContext of the test
62     /// runner thread.
63     /// </summary>
64     public class EventPump : IDisposable
65     {
66         static readonly Logger log = InternalTrace.GetLogger("EventPump");
67
68         #region Instance Variables
69
70         /// <summary>
71         /// The downstream listener to which we send events
72         /// </summary>
73         private readonly ITestListener _eventListener;
74
75         /// <summary>
76         /// The queue that holds our events
77         /// </summary>
78         private readonly EventQueue _events;
79
80         /// <summary>
81         /// Thread to do the pumping
82         /// </summary>
83         private Thread _pumpThread;
84
85         /// <summary>
86         /// The current state of the eventpump
87         /// </summary>
88         private int _pumpState = (int)EventPumpState.Stopped;
89
90         #endregion
91
92         #region Constructor
93         /// <summary>
94         /// Constructor
95         /// </summary>
96         /// <param name="eventListener">The EventListener to receive events</param>
97         /// <param name="events">The event queue to pull events from</param>
98         public EventPump( ITestListener eventListener, EventQueue events)
99         {
100             _eventListener = eventListener;
101             _events = events;
102         }
103
104         #endregion
105
106         #region Properties
107
108         /// <summary>
109         /// Gets or sets the current state of the pump
110         /// </summary>
111         public EventPumpState PumpState
112         {
113             get
114             {
115                 return (EventPumpState)_pumpState;
116             }
117         }
118
119         /// <summary>
120         /// Gets or sets the name of this EventPump
121         /// (used only internally and for testing).
122         /// </summary>
123         public string Name { get; set; }
124
125         #endregion
126
127         #region Public Methods
128
129         /// <summary>
130         /// Dispose stops the pump
131         /// Disposes the used WaitHandle, too.
132         /// </summary>
133         public void Dispose()
134         {
135             Stop();
136         }
137
138         /// <summary>
139         /// Start the pump
140         /// </summary>
141         public void Start()
142         {
143             if ( Interlocked.CompareExchange (ref _pumpState, (int)EventPumpState.Pumping, (int)EventPumpState.Stopped) == (int)EventPumpState.Stopped)  // Ignore if already started
144             {
145                 _pumpThread = new Thread (PumpThreadProc)
146                     {
147                     Name = "EventPumpThread" + Name,
148                     //Priority = ThreadPriority.Highest
149                     };
150
151                 _pumpThread.Start();
152             }
153         }
154
155         /// <summary>
156         /// Tell the pump to stop after emptying the queue.
157         /// </summary>
158         public void Stop()
159         {
160             if (Interlocked.CompareExchange (ref _pumpState, (int)EventPumpState.Stopping, (int)EventPumpState.Pumping) == (int)EventPumpState.Pumping)
161             {
162                 _events.Stop();
163                 _pumpThread.Join();
164             }
165         }
166         #endregion
167
168         #region PumpThreadProc
169
170         /// <summary>
171         /// Our thread proc for removing items from the event
172         /// queue and sending them on. Note that this would
173         /// need to do more locking if any other thread were
174         /// removing events from the queue.
175         /// </summary>
176         private void PumpThreadProc()
177         {
178             //ITestListener hostListeners = CoreExtensions.Host.Listeners;
179             try
180             {
181                 while (true)
182                 {
183                     Event e = _events.Dequeue( PumpState == EventPumpState.Pumping );
184                     if ( e == null )
185                         break;
186                     try 
187                     {
188                         e.Send(_eventListener);
189                         //e.Send(hostListeners);
190                     }
191                     catch (Exception ex)
192                     {
193                         log.Error( "Exception in event handler\r\n {0}", ex );
194                     }
195                 }
196             }
197             catch (Exception ex)
198             {
199                 log.Error( "Exception in pump thread", ex );
200             }
201             finally
202             {
203                 _pumpState = (int)EventPumpState.Stopped;
204                 //pumpThread = null;
205                 if (_events.Count > 0)
206                     log.Error("Event pump thread exiting with {0} events remaining");
207             }
208         }
209         #endregion
210     }
211 }
212 #endif