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(const ASIO_IOContext::executor_type& exc, exint max_cost = 0)
68  : myStrand(hboost::asio::make_strand(exc))
69  , myMaxCost(max_cost)
70  , myCurrentCost(0)
71  {
72  }
73 
74  /// Adds the task to the IO queue.
75  /// This will block until there is enough free space on the queue.
77  {
78  exint cost = task->memoryEstimate();
79 
80  UT_AutoLock l(myLock);
81 
82  // Check if we'll exceed the cost.
83  while (true)
84  {
85  if (cost && myMaxCost >= 0 && (myCurrentCost > 0)
86  && (myCurrentCost + cost > myMaxCost))
87  {
88  // Too expensive to add right now, so await a trigger.
89  myCond.waitForTrigger(myLock);
90  }
91  else
92  {
93  break;
94  }
95  }
96 
97  myCurrentCost += cost;
98  // Queue the task for execution when its the tasks turn to run
99  hboost::asio::post(myStrand, [this, work_task = std::move(task), cost]() {
100  {
101  UT_AutoLock l(myLock);
102  myCurrentCost -= cost;
103  myCond.triggerAll();
104  }
105 
106  work_task->invoke();
107  });
108 
109  myCond.triggerAll();
110  }
111 
112  /// Adds the task to the IO queue.
113  /// This will block until there is enough free space on the queue.
114  void postTask(UT_Function<void()> func, exint cost = 0)
115  {
116  postTask(UTmakeUnique<CallableTask>(std::move(func), cost));
117  }
118 
119 private:
120  exint myCurrentCost;
121  exint myMaxCost;
122 
123  mutable UT_Lock myLock;
124  UT_Condition myCond;
125 
126  // Used as the queue for posting work items.
127  hboost::asio::strand<hboost::asio::io_context::executor_type> myStrand;
128 };
129 
131 
132 
133 #endif // __NET_THREADEDIO_H__
NET_API NET_ThreadedIO * NETgetThreadedIO()
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
NET_ThreadedIO(const ASIO_IOContext::executor_type &exc, exint max_cost=0)
#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)
std::function< T > UT_Function
Definition: UT_Function.h:37
virtual void invoke()=0
GLenum func
Definition: glcorearb.h:783
int invoke(const Func &taskFunc1, Rest...taskFuncN)
Definition: Invoke.h:64