105 lines
3.3 KiB
ReStructuredText
105 lines
3.3 KiB
ReStructuredText
.. _module-pw_work_queue:
|
|
|
|
=============
|
|
pw_work_queue
|
|
=============
|
|
The ``pw_work_queue`` module contains utilities for deferring work to be
|
|
executed by another thread.
|
|
|
|
.. Warning::
|
|
This module is still under construction, the API is not yet stable.
|
|
|
|
---------
|
|
WorkQueue
|
|
---------
|
|
The ``pw::work_queue::WorkQueue`` class enables threads and interrupts to
|
|
enqueue work as a ``pw::work_queue::WorkItem`` for execution by the work queue.
|
|
|
|
The entire API is thread and interrupt safe.
|
|
|
|
Queue Sizing
|
|
============
|
|
The number of outstanding work requests is limited based on the
|
|
``pw::work_queue::WorkQueue``'s internal queue size. This must be set
|
|
appropriately for the application by the user.
|
|
|
|
The queue size is set trough either through the size of the ``queue_storage``
|
|
buffer passed into the constructor or by using the templated
|
|
``pw::work_queue::WorkQueueWithBuffer`` helper.
|
|
|
|
.. Note:: While the queue is full, the queue will not accept further work.
|
|
|
|
Cooperative Thread Cancellation
|
|
===============================
|
|
The class is a ``pw::thread::ThreadCore``, meaning it should be executed as a
|
|
single thread. In order to facilitate clean shutdown, it provides a
|
|
``RequestStop()`` API for cooperative cancellation which should be invoked
|
|
before joining the thread.
|
|
|
|
.. Note:: Once stop has been requested the queue will no longer accept further
|
|
work.
|
|
|
|
C++
|
|
===
|
|
.. cpp:class:: pw::work_queue::WorkQueue
|
|
|
|
.. cpp:function:: Status PushWork(WorkItem work_item)
|
|
|
|
Enqueues a work_item for execution by the work queue thread.
|
|
|
|
Returns:
|
|
|
|
* **Ok** - Success, entry was enqueued for execution.
|
|
* **FailedPrecondition** - the work queue is shutting down, entries are no
|
|
longer permitted.
|
|
* **ResourceExhausted** - internal work queue is full, entry was not
|
|
enqueued.
|
|
|
|
.. cpp:function:: void CheckPushWork(WorkItem work_item)
|
|
|
|
Queue work for execution. Crash if the work cannot be queued due to a
|
|
full queue or a stopped worker thread.
|
|
|
|
This call is recommended where possible since it saves error handling code
|
|
at the callsite; and in many practical cases, it is a bug if the work
|
|
queue is full (and so a crash is useful to detect the problem).
|
|
|
|
**Precondition:** The queue must not overflow, i.e. be full.
|
|
|
|
**Precondition:** The queue must not have been requested to stop, i.e. it
|
|
must not be in the process of shutting down.
|
|
|
|
.. cpp:function:: void RequestStop()
|
|
|
|
Locks the queue to prevent further work enqueing, finishes outstanding
|
|
work, then shuts down the worker thread.
|
|
|
|
The WorkQueue cannot be resumed after stopping as the ThreadCore thread
|
|
returns and may be joined. It must be reconstructed for re-use after
|
|
the thread has been joined.
|
|
|
|
Example
|
|
-------
|
|
|
|
.. code-block:: cpp
|
|
|
|
#include "pw_thread/detached_thread.h"
|
|
#include "pw_work_queue/work_queue.h"
|
|
|
|
pw::work_queue::WorkQueueWithBuffer<10> work_queue;
|
|
|
|
pw::thread::Options& WorkQueueThreadOptions();
|
|
void SomeLongRunningProcessing();
|
|
|
|
void SomeInterruptHandler() {
|
|
// Instead of executing the long running processing task in the interrupt,
|
|
// the work_queue executes it on the interrupt's behalf.
|
|
work_queue.CheckPushWork(SomeLongRunningProcessing);
|
|
}
|
|
|
|
int main() {
|
|
// Start up the work_queue as a detached thread which runs forever.
|
|
pw::thread::DetachedThread(WorkQueueThreadOptions(), work_queue);
|
|
}
|
|
|