summaryrefslogtreecommitdiffstats
path: root/xpcom/docs/refptr.rst
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/docs/refptr.rst')
-rw-r--r--xpcom/docs/refptr.rst81
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.