All objects that are passed between Nx Server and the Plugin must be implemented using the reference counting technique, similarly to how it is done in COM technology. For the overview of this technique, refer to the SDK’s readme.md.
For the conventions on incrementing/decrementing the reference counter when passing objects to/from functions, refer to the Doxygen comments in class nx::sdk::IRefCountable (src/nx/sdk/i_ref_countable.h).
If the conventions on incrementing/decrementing the reference counter are not accurately followed, it leads to two types of problems:
- "Leaked" object — an object that is no longer needed nor used, but is not destroyed and occupies memory. This creates a memory leak in the application, which typically goes unnoticed.
- Attempts to delete an object which has already been destroyed. Typically leads to a crash.
In order to easily detect these problems, the SDK offers a ready-to-use mechanism of tracking each reference-countable object in a registry named RefCountableRegistry.
Once activated in runtime, the registry warns if an object is attempted to be deleted twice and, when the Server process finishes (Nx Server is stopped), reports all objects that still exist — because normally at this point, all objects should have been deleted.
To simplify the code while still properly handling the reference counting, we recommend using the smart pointer template
nx::sdk::Ptr (src/nx/sdk/ptr.h) where possible.
Note that there still are some cases which require manual reference counting operations — namely, addRef() must be called on an object when it is received in a function argument and needs to be stored in a class field, and also when a function returns an object stored in a class field.
How to use
There is no need to write any special code — every object which is inherited from the helper class nx::sdk::RefCountable automatically registers itself in the registry, if the registry is enabled in runtime.
To enable the registry, add the following option to vms_server_plugins.ini (see Configuring via .ini files – IniConfig for details about .ini files and their location), and restart Nx Server:
In the case of any erroneous operation with the reference counter of an object, an assertion will fail and the operation will be logged. Also, when the Server stops, if any reference-countable objects still exist, they will be logged and an assertion will fail.
Note: Nx Server and each Plugin have their own instance of the registry. When the corresponding registry instance is created, it logs a "welcome" message; when it is destroyed (on Server stop) and there are no existing ref-countable objects in that registry, it logs a "success" message.
All logging from a registry instance is tagged with the name of the dynamic library that the registry instance belongs to.
By default, all issues are logged to stderr by the RefCountableRegistry, and NX_KIT_ASSERT() is used. Alternatively, you can log issues to the main Server log with INFO logging level and using Nx Server’s assertion mechanism, by specifying the following option in vms_server_plugins.ini:
Normally, both assertion mechanisms mentioned above check for and log the issues in both Debug and Release build configurations; but after logging, the process is intentionally crashed only in Debug build configuration.
Nx Server’s assertion mechanism can be configured to crash the process on assertion failure even in Release build configuration of the Server, by specifying the following option in nx_utils.ini:
Turning this option on helps to find the issues immediately when they happen.
To easily identify the origin of the "leaked" objects reported at the Server stop, a verbose mode of the registry can be turned on by specifying the following option in vms_server_plugins.ini:
Then the registry will log the creation of each object specifying its memory address and each deletion attempt. If some objects are found leaked at the Server stop, their addresses can be looked up in the log above to find when they were created, which helps to identify these objects in the code.
To see how the RefCountableRegistry works and detect issues, try it on Stub Analytics Plugin as follows.
- Create an empty vms_server_plugins.ini in the .ini file directory (if it does not exist yet), and restart the Server. The file will be filled with the default values and detailed comments.
- Modify vms_server_plugins.ini to have the following lines:
- Restart Nx Server.
- In Nx Desktop, open a camera on the layout. Make sure the video starts playing.
- Right-click the camera video and select Camera Settings…
- Go to the Plugins tab, choose Stub Analytics Plugin, and toggle the on/off switch to "on".
- Check the stderr of the Server to see that two RefCountableRegistry instances were created (one for the Plugin, one for the Server).
- Stop Nx Server.
- Check the stderr of the Server to see that the two RefCountableRegistry instances were destroyed and no leaked objects were detected.
- Start Nx Server.
- Go to the Plugins tab, choose Stub Analytics Plugin and check the checkbox "Force a memory leak when processing a video frame". Click OK.
- Stop Nx Server.
- Check the stderr of the Server to see that some leaked objects were detected.
- Modify vms_server_plugins.ini to have the following line:
- Restart Nx Server.
- Check the stderr of the Server to see the detailed logging of objects being created or destroyed.
- Stop Nx Server.
- On the stderr of the Server, note the address of an object that was reported as leaked. Find this address higher in the log to see when this object was created.