Sane C++ Libraries
C++ Platform Abstraction Libraries
SC::AsyncLoopWork Struct Reference

Executes work in a thread pool and then invokes a callback on the event loop thread. More...

#include <Async.h>

Inheritance diagram for SC::AsyncLoopWork:
SC::AsyncRequest

Public Types

using CompletionData = AsyncCompletionData
 Completion data for AsyncLoopWakeUp. More...
 
using Result = AsyncResultOf< AsyncLoopWork, CompletionData >
 Callback result for AsyncLoopWakeUp. More...
 
- Public Types inherited from SC::AsyncRequest
enum class  Type : uint8_t {
  LoopTimeout ,
  LoopWakeUp ,
  LoopWork ,
  ProcessExit ,
  SocketAccept ,
  SocketConnect ,
  SocketSend ,
  SocketReceive ,
  SocketClose ,
  FileRead ,
  FileWrite ,
  FileClose ,
  FilePoll
}
 Type of async request. More...
 

Public Member Functions

SC::Result setThreadPool (ThreadPool &threadPool)
 Sets the ThreadPool that will supply the thread to run the async work on. More...
 
SC::Result start (AsyncEventLoop &eventLoop)
 Schedule work to be executed on a background thread, notifying the event loop when it's finished. More...
 
- Public Member Functions inherited from SC::AsyncRequest
void setDebugName (const char *newDebugName)
 
AsyncEventLoopgetEventLoop () const
 Get the event loop associated with this AsyncRequest. More...
 
void cacheInternalEventLoop (AsyncEventLoop &loop)
 Caches the event loop associated with this AsyncRequest. More...
 
Result setThreadPoolAndTask (ThreadPool &pool, AsyncTask &task)
 Sets the thread pool and task to use for this request. More...
 
void resetThreadPoolAndTask ()
 Resets anything previously set with setThreadPoolAndTask. More...
 
 AsyncRequest (Type type)
 Constructs a free async request of given type. More...
 
Result stop ()
 Stops the async operation. More...
 
bool isFree () const
 

Public Attributes

Function< SC::Result()> work
 
Function< void(Result &)> callback
 Called to execute the work in a background threadpool thread. More...
 
- Public Attributes inherited from SC::AsyncRequest
AsyncRequestnext = nullptr
 
AsyncRequestprev = nullptr
 

Additional Inherited Members

- Protected Member Functions inherited from SC::AsyncRequest
Result validateAsync ()
 
void queueSubmission (AsyncEventLoop &eventLoop)
 
- Protected Attributes inherited from SC::AsyncRequest
AsyncEventLoopeventLoop = nullptr
 
AsyncTaskasyncTask = nullptr
 

Detailed Description

Executes work in a thread pool and then invokes a callback on the event loop thread.


AsyncLoopWork::work is invoked on one of the thread supplied by the ThreadPool passed during AsyncLoopWork::start. AsyncLoopWork::callback will be called as a completion, on the event loop thread AFTER work callback is finished.

// This test creates a thread pool with 4 thread and 16 AsyncLoopWork.
// All the 16 AsyncLoopWork are scheduled to do some work on a background thread.
// After work is done, their respective after-work callback is invoked on the event loop thread.
static constexpr int NUM_THREADS = 4;
static constexpr int NUM_WORKS = NUM_THREADS * NUM_THREADS;
ThreadPool threadPool;
SC_TEST_EXPECT(threadPool.create(NUM_THREADS));
AsyncEventLoop eventLoop;
SC_TEST_EXPECT(eventLoop.create());
AsyncLoopWork works[NUM_WORKS];
int numAfterWorkCallbackCalls = 0;
Atomic<int> numWorkCallbackCalls = 0;
for (int idx = 0; idx < NUM_WORKS; ++idx)
{
works[idx].work = [&]
{
// This work callback is called on some random threadPool thread
Thread::Sleep(50); // Execute some work on the thread
numWorkCallbackCalls.fetch_add(1); // Atomically increment this counter
return Result(true);
};
works[idx].callback = [&](AsyncLoopWork::Result&)
{
// This after-work callback is invoked on the event loop thread.
// More precisely this runs on the thread calling eventLoop.run().
numAfterWorkCallbackCalls++; // No need for atomics here, callback is run inside loop thread
};
// Must always call setThreadPool at least once before start
SC_TEST_EXPECT(works[idx].setThreadPool(threadPool));
SC_TEST_EXPECT(works[idx].start(eventLoop));
}
SC_TEST_EXPECT(eventLoop.run());
// Check that callbacks have been actually called
SC_TEST_EXPECT(numWorkCallbackCalls.load() == NUM_WORKS);
SC_TEST_EXPECT(numAfterWorkCallbackCalls == NUM_WORKS);
#define SC_TEST_EXPECT(e)
Records a test expectation (eventually aborting or breaking o n failed test)
Definition: Testing.h:113
Result create(Options options=Options())
Creates the event loop kernel object.
Result run()
Blocks until there are no more active queued requests, dispatching all completions.
SC::Result setThreadPool(ThreadPool &threadPool)
Sets the ThreadPool that will supply the thread to run the async work on.
SC::Result start(AsyncEventLoop &eventLoop)
Schedule work to be executed on a background thread, notifying the event loop when it's finished.
AsyncResultOf< AsyncLoopWork, CompletionData > Result
Callback result for AsyncLoopWakeUp.
Definition: Async.h:386
static void Sleep(uint32_t milliseconds)
Puts current thread to sleep.

Member Typedef Documentation

◆ CompletionData

◆ Result

Member Function Documentation

◆ setThreadPool()

SC::Result SC::AsyncLoopWork::setThreadPool ( ThreadPool threadPool)

Sets the ThreadPool that will supply the thread to run the async work on.

Note
Always call this method at least once before AsyncLoopWork::start

◆ start()

SC::Result SC::AsyncLoopWork::start ( AsyncEventLoop eventLoop)

Schedule work to be executed on a background thread, notifying the event loop when it's finished.

Parameters
eventLoopThe AsyncEventLoop where to schedule this work on
Note
Remember to call AsyncLoopWork::setThreadPool at least once before calling AsyncLoopWork::start

Member Data Documentation

◆ callback

Function<void(Result&)> SC::AsyncLoopWork::callback

Called to execute the work in a background threadpool thread.


The documentation for this struct was generated from the following file: