v.5.7.5 - Stiffstream/sobjectizer GitHub Wiki

This page describes changes and new features of v.5.7.5.

NOTE The v.5.7.5 is a maintenance release. There are no new features, but several fixes that may be important in some cases.

A fix for the behavior of the environment() method for MPSC mboxes

In previous versions of SObjectizer, the environment() method for MPSC mboxes just called the so_environment() for the single consumer of the MPSC mbox. This approach resulted in dereferencing of a dangling pointer in the following case:

  • a coop with agent A is created and registered;
  • the direct mbox of the A is stored as mbox_a;
  • the coop with agent A is deregistered;
  • the environment() is called for mbox_a.

In this case, the old implementation of MPSC mbox called so_environment() for agent A (via pointer to A stored inside the mbox), but that pointer isn't valid after deregistration of the A's coop.

Since v.5.7.5 an MPSC mbox holds a reference to the SObjectizer Environment and returns this reference from environment() method. So it's safe to call environment() even after deregistration of the single consumer of that mbox.

ATTENTION. It's safe to call mbox's environment() method only while the SObjectizer Environment is still alive and is in working state. If the SObjectizer Environment in that the mbox was created is already stopped then the mbox must not be used.

A fix for order of destruction of agents and dispatcher binders in a coop

Up to v.5.7.5, the agents and dispatcher binders from a coop were destroyed in the following order:

  • the dispatcher binder for an agent was destroyed first,
  • then the agent was destroyed.

Sometimes it could lead to a problem: if disp_binder holds an object to that the agent refers to in the destructor, then that reference may become invalid when the agent's destructor works (it's because the disp_binder may be completely destroyed earlier).

One can imagine a case when disp_binder contains, for example, Asio's io_context object and the agent bound to that disp_binder creates a socket that uses that io_context object. The destructor of the socket may call some methods of the io_context object, but the reference to the io_context object is already invalid.

Since v.5.7.5 the order of the destruction is reversed: the agent is destroyed first, only then the disp_binder is destroyed. It is achieved by storing a smart pointer to disp_binder inside an agent. It means that while the agent is alive the disp_binder is alive too. When the agent is destroyed the reference count to disp_binder is decremented and disp_binder may be destroyed.

ATTENTION. Strictly speaking, the destructor of a coop doesn't directly destroy disp_binders and agents. It just decrements the reference count (smart pointers are used for holding agents). Usually, decrementing of the reference count leads to the destruction of these objects, because the coop is the only holder of such smart pointers. However, there may be much more complex cases where decrementing of the reference count in the coop's destructors won't destroy agents, because someone else still holds smart pointers to them.