HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_EventQueue.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  */
8 
9 #ifndef __PDG_EventQueue_h__
10 #define __PDG_EventQueue_h__
11 
12 #include "PDG_API.h"
13 #include "PDG_Event.h"
14 #include "PDG_EventTypes.h"
15 
16 #include <UT/UT_Array.h>
18 #include <UT/UT_ConcurrentQueue.h>
19 #include <UT/UT_ConcurrentVector.h>
20 #include <UT/UT_ParallelUtil.h>
22 #include <UT/UT_UniquePtr.h>
23 
24 #include <SYS/SYS_AtomicInt.h>
25 
26 #define PDG_EVENT_QUEUE_STATS 0
27 
28 class PDG_EventEmitter;
29 class PDG_EventHandler;
30 
31 class UT_Thread;
32 
33 /* Event queue that dispatches PDG_Events to the handlers registered for
34  * the PDG_EventEmitter that produced them.
35  */
37 {
38 public:
39  /// Scoped object that pauses event handling. Pausing is implemented with
40  /// an atomic counter on the queue, so nested ScopedPause objects work as
41  /// expected. Each scoped pause increments the pause request counter, so
42  /// event processing will only proceed once all ScopedPause objects are
43  /// unwound.
45  {
46  public:
48  : myQueue(queue)
49  {
50  queue->pause();
51  }
52 
54  {
55  myQueue->resume();
56  }
57 
58  private:
59  PDG_EventQueue* myQueue;
60  };
61 
62 public:
63  /// Constructs a new event queue
64  PDG_EventQueue(bool background);
65  ~PDG_EventQueue();
66 
67  /// Queues an event that will eventually be dispatched by the background
68  /// thread running in this event queue instance.
69  void queueEvent(
70  const PDG_EventEmitter* emitter,
71  const PDG_Event& event);
72 
73  /// Emits an event immediately on the calling thread
74  void emitEvent(
75  const PDG_EventEmitter* emitter,
76  const PDG_Event& event) const;
77 
78  /// Waits for all queued events to finish, and prevents new events from
79  /// being added until that condition is reached. Blocks the caller. If
80  /// an event emitter is passed into this function, it gets deregistered
81  /// before unblocking the event queue.
82  void waitAllEvents(PDG_EventEmitter* emitter=nullptr);
83 
84  /// Waits until the specified emitter is registered, to ensure that all
85  /// events for that emitter have been flushed
86  void waitEmitter(const PDG_EventEmitter* emitter);
87 
88  /// Returns whether or not the event queue attempts to consolidate
89  /// consecutive events of the same type
90  inline bool isConsolidateEvents() const
91  { return myIsConsolidateEvents; }
92 
93  /// Configures the event consolidation flag
94  inline void setConsolidateEvents(bool consolidate)
95  { myIsConsolidateEvents = consolidate; }
96 
97 private:
98  friend class PDG_EventEmitter;
99  friend class PDG_GraphContext;
100 
101  struct EmitterInfo
102  {
103  PDG_EventHandlerArray myHandlers;
104  PDG_EventFilterArray myFilters;
105 
106  void add(
107  PDG_EventHandler* handler,
108  const PDG_EventFilter& filter,
109  PDG_EventFilterMap& filter_map);
110  bool remove(
111  PDG_EventHandler* handler,
112  PDG_EventFilterMap& filter_map);
113  void removeAll(
114  PDG_EventHandlerArray& removed,
115  PDG_EventFilterMap& filter_map,
116  bool user_only);
117  void emitEvent(const PDG_Event& event) const;
118  };
119 
120  enum EmitterUpdate
121  {
122  eHandlerAdd,
123  eHandlerRemove,
124  eHandlerRemoveAll
125  };
126 
127  struct DeferredEmitterUpdate
128  {
129  PDG_EventEmitter* myEmitter;
130  PDG_EventHandler* myHandler;
131 
132  PDG_EventFilter myFilter;
133 
134  EmitterUpdate myType;
135  bool myUserOnly;
136  };
137 
138  using EventInfo = std::pair<
139  const PDG_EventEmitter*, PDG_Event>;
140  using EventArray = UT_Array<EventInfo>;
141  using EventQueue = UT_ConcurrentQueue<EventInfo>;
142  using EmitterMap = UT_ConcurrentHashMap<
143  PDG_EventEmitter*, EmitterInfo>;
144  using EmitterArrayMap = UT_UniquePtr<EmitterMap[]>;
145  using EmitterUpdateArray = UT_ConcurrentVector<DeferredEmitterUpdate>;
146  using ActiveEmitter = UT_ThreadSpecificValue<
147  const PDG_EventEmitter*>;
148 
149  class EventFunctor
150  {
151  public:
152  EventFunctor(
154  const EventArray& events);
155  ~EventFunctor();
156 
157  void operator()(
158  const UT_BlockedRange<int64> &range) const;
159 
160  private:
161  PDG_EventQueue* myQueue;
162  const EventArray& myEvents;
163  };
164 
165 private:
166  void terminate();
167 
168  exint emitterIndex(const PDG_EventEmitter* emitter) const;
169 
170  void registerEmitter(PDG_EventEmitter* emitter);
171  void deregisterEmitter(PDG_EventEmitter* emitter);
172 
173  bool addEventHandler(
174  PDG_EventEmitter* emitter,
175  PDG_EventHandler* handler,
176  const PDG_EventFilter& filter);
177  void removeEventHandler(
178  PDG_EventEmitter* emitter,
179  PDG_EventHandler* handler);
180  void removeAllEventHandlers(
181  PDG_EventEmitter* emitter,
182  bool user_only);
183  void findEventHandlers(
184  const PDG_EventEmitter* emitter,
185  PDG_EventHandlerArray& handlers) const;
186 
187  void processQueueStats(int print_limit);
188  void processEvent(
189  const EventInfo& info,
190  const PDG_EventEmitter*& active_emitter);
191  void processEvents();
192 
193  inline void pause()
194  { myPauseRequests.add(1); }
195  inline void resume()
196  { myPauseRequests.add(-1); }
197 
198  static void* runThread(void* param);
199 
200 private:
201  EventQueue myEvents;
202  EmitterArrayMap myEmitters;
203  EmitterUpdateArray myEmitterUpdates;
204  ActiveEmitter myActiveEmitter;
205 
206  UT_Thread* myThread;
207 
208 #if PDG_EVENT_QUEUE_STATS
209  exint myDropEventCount;
210  exint myQueuedEventCount;
211  exint myPoppedEventCount;
212  exint myProcessedEventCount;
213  exint myQueueLogTime;
214 #endif
215 
216  exint myEmitterMapSize;
217  exint myProcessSleepTime;
218  SYS_AtomicInt32 myPauseRequests;
219 
220  bool myIsTerminating;
221  bool myIsWaiting;
222  bool myIsProcessing;
223  bool myIsConsolidateEvents;
224 };
225 
226 #endif
GLenum GLint * range
Definition: glcorearb.h:1925
#define PDG_API
Definition: PDG_API.h:23
int64 exint
Definition: SYS_Types.h:125
bool isConsolidateEvents() const
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
struct _cl_event * event
Definition: glcorearb.h:2961
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the queue
Definition: thread.h:632
tbb::concurrent_hash_map< K, T, H, A > UT_ConcurrentHashMap
GLenum GLfloat param
Definition: glcorearb.h:104
void setConsolidateEvents(bool consolidate)
Configures the event consolidation flag.
void pause(int delay) noexcept
Definition: thread.h:103
ScopedPause(PDG_EventQueue *queue)
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Declare prior to use.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297