HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NET_ThreadedIO.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  * NAME: NET_ThreadedIO.h
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __NET_THREADEDIO_H__
13 #define __NET_THREADEDIO_H__
14 
15 #include "NET_API.h"
16 
17 #include <UT/UT_BoostAsio.h>
18 #include <UT/UT_Condition.h>
19 #include <UT/UT_Function.h>
20 #include <UT/UT_Lock.h>
21 #include <UT/UT_NonCopyable.h>
22 #include <UT/UT_ThreadedIO.h>
23 #include <UT/UT_UniquePtr.h>
24 
25 /// NOTE: This is ONLY a proof of concept as a replacement for UT_ThreadedIO
26 /// If accepted this would likely move to $UT
28 {
29 public:
30  /// Base Class to perform IO thread tasks
31  class NET_API Task
32  {
33  public:
34  Task() = default;
35  virtual ~Task() = default;
37 
38  virtual void invoke() = 0;
39  virtual exint memoryEstimate() const = 0;
40  };
41 
42 private:
43  class NET_API CallableTask : public Task
44  {
45  public:
46  CallableTask(UT_Function<void()> callable, exint mem_usage = 0) :
47  myClb(std::move(callable)),
48  myMemUsage(mem_usage)
49  {
50  }
51 
52  void invoke() override
53  {
54  myClb();
55  }
56 
57  exint memoryEstimate() const override
58  {
59  return myMemUsage;
60  }
61  private:
62  UT_Function<void()> myClb;
63  exint myMemUsage;
64  };
65 
66 public:
67  NET_ThreadedIO(ASIO_IOContext& ctx, exint max_cost = 0) :
68  myStrand(hboost::asio::make_strand(ctx.get_executor())),
69  myMaxCost(max_cost),
70  myCurrentCost(0)
71  {}
72 
73  /// Adds the task to the IO queue.
74  /// This will block until there is enough free space on the queue.
76  {
77  exint cost = task->memoryEstimate();
78 
79  UT_AutoLock l(myLock);
80 
81  // Check if we'll exceed the cost.
82  while (true)
83  {
84  if (cost && myMaxCost >= 0 && (myCurrentCost > 0)
85  && (myCurrentCost + cost > myMaxCost))
86  {
87  // Too expensive to add right now, so await a trigger.
88  myCond.waitForTrigger(myLock);
89  }
90  else
91  {
92  break;
93  }
94  }
95 
96  myCurrentCost += cost;
97  // Queue the task for execution when its the tasks turn to run
98  hboost::asio::post(myStrand, [this, work_task = std::move(task), cost]() {
99  {
100  UT_AutoLock l(myLock);
101  myCurrentCost -= cost;
102  myCond.triggerAll();
103  }
104 
105  work_task->invoke();
106  });
107 
108  myCond.triggerAll();
109  }
110 
111  /// Adds the task to the IO queue.
112  /// This will block until there is enough free space on the queue.
113  void postTask(UT_Function<void()> func, exint cost = 0)
114  {
115  postTask(UTmakeUnique<CallableTask>(std::move(func), cost));
116  }
117 
118 private:
119  exint myCurrentCost;
120  exint myMaxCost;
121 
122  mutable UT_Lock myLock;
123  UT_Condition myCond;
124 
125  // Used as the queue for posting work items.
126  hboost::asio::strand<hboost::asio::io_context::executor_type> myStrand;
127 };
128 
130 
131 
132 #endif // __NET_THREADEDIO_H__
133 
NET_API NET_ThreadedIO * NETgetThreadedIO()
NET_ThreadedIO(ASIO_IOContext &ctx, exint max_cost=0)
Base Class to perform IO thread tasks.
int64 exint
Definition: SYS_Types.h:125
void postTask(UT_Function< void()> func, exint cost=0)
Condition synchronization primitive.
Definition: UT_Condition.h:25
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
#define NET_API
Definition: NET_API.h:9
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
virtual exint memoryEstimate() const =0
void postTask(UT_UniquePtr< Task > task)
hboost::asio::io_context ASIO_IOContext
Definition: UT_BoostAsio.h:74
std::function< T > UT_Function
Definition: UT_Function.h:37
virtual void invoke()=0
GLenum func
Definition: glcorearb.h:783