Class rw_serializer¶
Defined in File rw_serializer.hpp
Nested Relationships¶
Class Documentation¶
-
class
concore::v1::rw_serializer¶ Similar to a serializer but allows two types of tasks: READ and WRITE tasks.
This class is not an executor. It binds together two executors: one for READ tasks and one for WRITE tasks. This class adds constraints between READ and WRITE threads.
The READ tasks can be run in parallel with other READ tasks, but not with WRITE tasks. The WRITE tasks cannot be run in parallel neither with READ nor with WRITE tasks.
This class provides two methods to access to the two executors: reader() and writer(). The reader() executor should be used to enqueue READ tasks while the writer() executor should be used to enqueue WRITE tasks.
This implementation slightly favors the WRITEs: if there are multiple pending WRITEs and multiple pending READs, this will execute all the WRITEs before executing the READs. The rationale is twofold:
it’s expected that the number of WRITEs is somehow smaller than the number of READs (otherwise a simple serializer would probably work too)
it’s expected that the READs would want to read the latest data published by the WRITEs, so they are aiming to get the latest WRITE
Guarantees:
no more than 1 WRITE task is executed at once
no READ task is executed in parallel with other WRITE task
the WRITE tasks are executed in the order of enqueueing
Public Functions
-
rw_serializer(any_executor base_executor = {}, any_executor cont_executor = {})¶ Constructor.
If
base_executoris not given, global_executor will be used. Ifcont_executoris not given, it will usebase_executorif given, otherwise it will use spawn_continuation_executor for enqueueing continuations.- Parameters
base_executor: Executor to be used to enqueue new taskscont_executor: Executor that enqueues follow-up tasks
The first executor is used whenever new tasks are enqueued, and no task is in the wait list. The second executor is used whenever a task is completed and we need to continue with the enqueueing of another task. In this case, the default, spawn_continuation_executor tends to work better than global_executor, as the next task is picked up immediately by the current working thread, instead of going over the most general flow.
-
reader_type
reader() const¶ Returns an executor to enqueue READ tasks.
- Return
The executor for READ types
-
writer_type
writer() const¶ Returns an executor to enqueue WRITE tasks.
- Return
The executor for WRITE types
-
void
set_exception_handler(except_fun_t except_fun)¶ Sets the exception handler for enqueueing tasks.
The exception handler set here will be called whenever an exception is thrown while enqueueing a follow-up task. It will not be called whenever the task itself throws an exception; that will be handled by the exception handler set in the group of the task.
- Parameters
except_fun: The function to be called whenever an exception occurs.
Cannot be called in parallel with task enqueueing and execution.
-
class
reader_type¶ The type of the executor used for READ tasks.
Objects of this type will be created by rw_serializer to allow enqueueing READ tasks
Public Functions
Constructor. Should only be called by rw_serializer.
-
template<typename
F>
voidexecute(F &&f) const¶ Enqueue a functor as a write operation in the RW serializer.
Depending on the state of the parent rw_serializer object this will enqueue the task immediately (if there are no WRITE tasks), or it will place it in a waiting list to be executed later. The tasks on the waiting lists will be enqueued once there are no more WRITE tasks.
Friends
-
friend bool
operator==(reader_type l, reader_type r)¶ Equality operator.
-
friend bool
operator!=(reader_type l, reader_type r)¶ Inequality operator.
-
class
writer_type¶ The type of the executor used for WRITE tasks.
Objects of this type will be created by rw_serializer to allow enqueueing WRITE tasks
Public Functions
Constructor. Should only be called by rw_serializer.
-
template<typename
F>
voidexecute(F &&f) const¶ Enqueue a functor as a write operation in the RW serializer.
Depending on the state of the parent rw_serializer object this will enqueue the task immediately (if there are no other tasks executing), or it will place it in a waiting list to be executed later. The tasks on the waiting lists will be enqueued, in order, one by one. No new READ tasks are executed while we have WRITE tasks in the waiting list.
-
void
execute(task t) const¶ This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
-
void
operator()(task t) const¶ Enqueue a functor as a write operation in the RW serializer.
Depending on the state of the parent rw_serializer object this will enqueue the task immediately (if there are no other tasks executing), or it will place it in a waiting list to be executed later. The tasks on the waiting lists will be enqueued, in order, one by one. No new READ tasks are executed while we have WRITE tasks in the waiting list.
Friends
-
friend bool
operator==(writer_type l, writer_type r)¶ Equality operator.
-
friend bool
operator!=(writer_type l, writer_type r)¶ Inequality operator.