|
TracktionEngine
|
Manages access to an object in a way that means it is lock-free to access from a real-time thread. More...
#include <tracktion_LockFreeObject.h>
Classes | |
| class | ScopedRealTimeAccess |
| Helper class to automatically retain/release real time access to an object. More... | |
Public Member Functions | |
| LockFreeObject () | |
| Constructs an initially empty object. | |
| void | clear () |
| Clears the current and any pending object. | |
| std::unique_ptr< ObjectType > | pushNonRealTime (ObjectType &&newObj) |
| Pushes a new object to be picked up on the real time thread. | |
| ObjectType * | retainRealTime () |
| Retains the object for use in a real time thread. | |
| void | releaseRealTime () |
| Releases the use of the object from a previous call to retainRealTime. | |
| ScopedRealTimeAccess | getScopedAccess () |
| Creates a ScopedRealTimeAccess for this LockFreeObject. | |
Manages access to an object in a way that means it is lock-free to access from a real-time thread.
This initially starts empty so call pushNonRealTime to queue an object. You can then get at this object using retainRealTime. It's thread safe to call pushNonRealTime as many times as you like, retainRealTime will just return the old object whilst those calls are in progress. Calls to pushNonRealTime may have to wait for the real time access to complete, signified by a call to releaseRealTime.
Objects are stored on the heap so they have a stable identity: once an object has been swapped in by retainRealTime, its address never changes and its contents are never written by this class again. When a subsequent push is consumed on the real-time thread, the previous object is retired rather than mutated, and ownership of it is handed back to the caller from the next pushNonRealTime call so it can be destroyed once any concurrent readers of it have finished.
Additionally, you may want to clear the objects e.g. releasing some resource they have stored. This can be done with the clear call. Whilst this is happening, retainRealTime will still be lock-free but will return nullptr signifying no object can be used.
| graph::LockFreeObject< ObjectType >::LockFreeObject | ( | ) |
Constructs an initially empty object.
Use the pushNonRealTime function to queue one for real-time access.
| void graph::LockFreeObject< ObjectType >::clear | ( | ) |
Clears the current and any pending object.
N.B. This destroys the objects so only call it once no other threads can be concurrently reading them (including any object previously swapped in by retainRealTime whose pointer readers may still hold).
| std::unique_ptr< ObjectType > graph::LockFreeObject< ObjectType >::pushNonRealTime | ( | ObjectType && | newObj | ) |
Pushes a new object to be picked up on the real time thread.
Returns the object this replaces which will either be a previously pushed object that was never swapped in on the real-time thread, or an object that has been retired by a retainRealTime call swapping in a newer one. In the latter case, other threads may still be reading the retired object if they obtained its pointer before the swap, so callers must wait for those readers to finish before destroying it.
| ObjectType * graph::LockFreeObject< ObjectType >::retainRealTime | ( | ) |
Retains the object for use in a real time thread.
If a previous push call has finished, this will update and use the newly pushed object. If a clear call is in progress, or no object has been pushed yet, this will return nullptr.
This must be matched with a corresponding call to releaseRealTime(). To Ensure this, use the ScopedRealTimeAccess helper class.
| void graph::LockFreeObject< ObjectType >::releaseRealTime | ( | ) |
Releases the use of the object from a previous call to retainRealTime.
| ScopedRealTimeAccess graph::LockFreeObject< ObjectType >::getScopedAccess | ( | ) |
Creates a ScopedRealTimeAccess for this LockFreeObject.