Fusion:Reference Counter

A reference counter is a thread-safe counter, with special handling when it counts down to zero.

A reference counter is initialized with a call to fusion_ref_init. When you’re done with it, you’ll call fusion_ref_destroy, after which any further use of it will result in an error (unless you reinitialize it).

A call to fusion_ref_up simply acquires a lock on the reference counter and increments it. Calling fusion_ref_down acquires a lock and decrements the reference counter. An error will be returned if an attempt is made to decrement a counter that is already zero. You can check the value of a reference counter with fusion_ref_stat.

You can call fusion_ref_watch to register a callback to be called whenever the counter is decremented to zero. It is not valid to place a watch on a reference counter while it is zero. Also, make sure you get it right the first time, for once a watch is in place it cannot be removed or replaced except by destroying the reference counter.

You can also lock a reference counter that is currently zero by calling fusion_ref_zero_trylock, which will return an error if it’s not zero. If you want to block on a reference counter until it becomes zero and then lock it, fusion_ref_zero_lock will do the trick (unless it is being watched, in which case you cannot block on it). You release your lock on the reference counter with a call to fusion_ref_unlock. A reference counter can only be stated or destroyed while it is locked.

fusion_ref_inherit sets up a relationship between two references. The first reference had the ref count of the inherited reference added to it, and they are linked -- ref_up/ref_down operations from the inherited reference also apply to this reference. If the inherited reference is destroyed, this reference will have its refcount decreased by the destroyed ref's ref count.

(It seems like something may be missing in the implementation of the blocking lock… who signals the pthread cond variable?)

Multi-App: In the multi-app configuration the kernel device enables inter-process reference counting. In contrast to the single-app configuration which keeps the reference counter in the FusionRef variable you provide, the multi-app implementation keeps the actual counter in the kernel device and just stores its id in the FusionRef. In the multi-app configuration each reference counter keeps a global counter as well as a counter for each fusionee. When the global parameter to the up/down functions is true, the global counter is incremented/decremented, otherwise the counter for the current fusionee (process) is manipulated. In this configuration fusion_ref_stat and the zero_lock functions use the sum of the global and all local counters.