3.1. bus — Message bus

A message bus provides a software-bus abstraction that gathers all the communications between a group of threads over a single shared virtual channel. Messages are transferred on the bus from a sender to one or more attached listeners. The concept is analogous to the bus concept found in computer hardware architecture.

3.1.1. Example

In this example there is a bus with three listeners attached; listerner 0, 1 and 2. Listener 0 and 1 are attached to the bus listening for message id 7, and listener 2 for message id 9.

Any thread can write a message to the bus by calling bus_write(). If a message with id 7 is written to the bus, both listerner 0 and 1 will receive the message. Listener 2 will receive messages with id 9.

Messages are read from the listener channel by the thread that owns the listener.

     +--------------+              +--------------+
     |  listener 0  |              |  listener 2  |
     | id:7, chan:0 |              | id:9, chan:2 |
     +-------+------+              +-------+------+
             |                             |
BUS  ========+==============+==============+=======
                            |
                    +-------+------+
                    |  listener 1  |
                    | id:7, chan:1 |
                    +--------------+

Source code: src/sync/bus.h, src/sync/bus.c

Test code: tst/sync/bus/main.c

Test coverage: src/sync/bus.c


Functions

int bus_module_init(void)

Initialize the bus module. This function must be called before calling any other function in this module.

The module will only be initialized once even if this function is called multiple times.

Return
zero(0) or negative error code

int bus_init(struct bus_t *self_p)

Initialize given bus.

Return
zero(0) or negative error code.
Parameters
  • self_p: Bus to initialize.

int bus_listener_init(struct bus_listener_t *self_p, int id, void *chan_p)

Initialize given listener to receive messages with given id, after the listener is attached to the bus. A listener can only receive messages of a single id, though, the same channel may be used in multiple listeners with different ids (if the channel supports it).

Return
zero(0) or negative error code.
Parameters
  • self_p: Listener to initialize.
  • id: Message id to receive.
  • chan_p: Channel to receive messages on.

int bus_attach(struct bus_t *self_p, struct bus_listener_t *listener_p)

Attach given listener to given bus. Messages written to the bus will be written to all listeners initialized with the written message id.

Return
zero(0) or negative error code.
Parameters
  • self_p: Bus to attach the listener to.
  • listener_p: Listener to attach to the bus.

int bus_detatch(struct bus_t *self_p, struct bus_listener_t *listener_p)

Detatch given listener from given bus. A detached listener will not receive any messages from the bus.

Return
zero(0) or negative error code.
Parameters
  • self_p: Bus to detach listener from.
  • listener_p: Listener to detach from the bus.

int bus_write(struct bus_t *self_p, int id, const void *buf_p, size_t size)

Write given message to given bus. All attached listeners to given bus will receive the message.

Return
Number of listeners that received the message, or negative error code.
Parameters
  • self_p: Bus to write the message to.
  • id: Message identity.
  • buf_p: Buffer to write to the bus. All listeners with given message id will receive this data.
  • size: Number of bytes to write.

struct bus_t
#include <bus.h>

Public Members

struct rwlock_t rwlock
struct binary_tree_t listeners
struct bus_listener_t

Public Members

struct binary_tree_node_t base
int id
void *chan_p
struct bus_listener_t *next_p