Class rw_serializer

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

See

reader_type, writer_type, serializer, rw_serializer

Public Functions

rw_serializer(any_executor base_executor = {}, any_executor cont_executor = {})

Constructor.

If

base_executor is not given, global_executor will be used. If cont_executor is not given, it will use base_executor if given, otherwise it will use spawn_continuation_executor for enqueueing continuations.
Parameters
  • base_executor: Executor to be used to enqueue new tasks

  • cont_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.

See

global_executor, spawn_continuation_executor

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.

See

task_group::set_exception_handler

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

reader_type(std::shared_ptr<impl> impl)

Constructor. Should only be called by rw_serializer.

template<typename F>
void execute(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.

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.

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

writer_type(std::shared_ptr<impl> impl)

Constructor. Should only be called by rw_serializer.

template<typename F>
void execute(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.