diff options
Diffstat (limited to '')
-rw-r--r-- | xpcom/docs/refptr.rst | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/xpcom/docs/refptr.rst b/xpcom/docs/refptr.rst new file mode 100644 index 0000000000..f71acc6828 --- /dev/null +++ b/xpcom/docs/refptr.rst @@ -0,0 +1,81 @@ +Reference Counting Helpers +========================== + +RefPtr versus nsCOMPtr +---------------------- + +The general rule of thumb is to use ``nsCOMPtr<T>`` when ``T`` is an +interface type which inherits from ``nsISupports``, and ``RefPtr<T>`` when +``T`` is a concrete type. + +This basic rule derives from some ``nsCOMPtr<T>`` code being factored into +the ``nsCOMPtr_base`` base class, which stores the pointer as a +``nsISupports*``. This design was intended to save some space in the binary +(though it is unclear if it still does). Since ``nsCOMPtr`` stores the +pointer as ``nsISupports*``, it must be possible to unambiguously cast from +``T*`` to ``nsISupports**``. Many concrete classes inherit from more than +one XPCOM interface, meaning that they cannot be used with ``nsCOMPtr``, +which leads to the suggestion to use ``RefPtr`` for these classes. + +``nsCOMPtr<T>`` also requires that the target type ``T`` be a valid target +for ``QueryInterface`` so that it can assert that the stored pointer is a +canonical ``T`` pointer (i.e. that ``mRawPtr->QueryInterface(T_IID) == +mRawPtr``). + +do_XXX() nsCOMPtr helpers +------------------------- + +There are a number of ``do_XXX`` helper methods across the codebase which can +be assigned into ``nsCOMPtr`` (and sometimes ``RefPtr``) to perform explicit +operations based on the target pointer type. + +In general, when these operations succeed, they will initialize the smart +pointer with a valid value, and otherwise they will silently initialize the +smart pointer to ``nullptr``. + +``do_QueryInterface`` and ``do_QueryObject`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Attempts to cast the provided object to the target class using the XPCOM +``QueryInterface`` mechanism. In general, use ``do_QueryInterface`` may only +be used to cast between interface types in a ``nsCOMPtr<T>``, and +``do_QueryObject`` in situations when downcasting to concrete types. + + +``do_GetInterface`` +~~~~~~~~~~~~~~~~~~~ + +Looks up an object implementing the requested interface using the +``nsIInterfaceRequestor`` interface. If the target object doesn't implement +``nsIInterfaceRequestor`` or doesn't provide the given interface, initializes +the smart pointer with ``nullptr``. + + +``do_GetService`` +~~~~~~~~~~~~~~~~~ + +Looks up the component defined by the passed-in CID or ContractID string in +the component manager, and returns a pointer to the service instance. This +may start the service if it hasn't been started already. The resulting +service will be cast to the target interface type using ``QueryInterface``. + + +``do_CreateInstance`` +~~~~~~~~~~~~~~~~~~~~~ + +Looks up the component defined by the passed-in CID or ContractID string in +the component manager, creates and returns a new instance. The resulting +object will be cast to the target interface type using ``QueryInterface``. + + +``do_QueryReferent`` and ``do_GetWeakReference`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When passed a ``nsIWeakReference*`` (e.g. from a ``nsWeakPtr``), +``do_QueryReferent`` attempts to re-acquire a strong reference to the held +type, and cast it to the target type with ``QueryInterface``. Initializes the +smart pointer with ``nullptr`` if either of these steps fail. + +In contrast ``do_GetWeakReference`` does the opposite, using +``QueryInterface`` to cast the type to ``nsISupportsWeakReference*``, and +acquire a ``nsIWeakReference*`` to the passed-in object. |