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 (Function< void(AsyncResult &)> *afterStopped=nullptr)
 Ask to stop current async operation. More...
 
bool isFree () const
 Returns true if this request is free. More...
 
bool isCancelling () const
 Returns true if this request is being cancelled. More...
 
bool isActive () const
 Returns true if this request is active or being reactivated. More...
 
Type getType () const
 Returns request type. More...
 

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));
}
int numRequests = 0;
eventLoop.enumerateRequests([&](AsyncRequest&) { numRequests++; });
SC_TEST_EXPECT(eventLoop.run());
SC_TEST_EXPECT(numRequests == NUM_WORKS);
// 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
void enumerateRequests(Function< void(AsyncRequest &)> enumerationCallback)
Enumerates all requests objects associated with this loop.
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:409
AsyncRequest(Type type)
Constructs a free async request of given type.
Definition: Async.h:173
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: