Moving all important docs to gila. This is a documentation only change - not part of the tinderbox|release builds

This commit is contained in:
dougt%meer.net 2003-06-06 19:49:28 +00:00
parent 0058480b59
commit 60d5f4ed17
15 changed files with 8 additions and 4775 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
<TITLE>Gemini Object Model</TITLE>
</HEAD>
<BODY>
<H1>
Gemini Object Model</H1>
The gemini object model is a cross platform component object model modelled
after win32's IUnknown and COM. We do not support a C API to gemini at
this time.
<H2>
nsID</H2>
Like OSF's DCE, we use an "interface id" which is a unique identifer which
names the interface. The nsID and be used as a key into a cross platform
registry service to discover an implementation of an interface. Here is
the declaration of nsID:
<UL><TT>struct nsID {</TT>
<BR><TT>&nbsp; PRUint32 m0;</TT>
<BR><TT>&nbsp; PRUint16 m1, m2;</TT>
<BR><TT>&nbsp; PRUint8 m3[8];</TT>
<P><TT>&nbsp; inline nsbool Equals(const nsID&amp; other) const {</TT>
<BR><TT>&nbsp;&nbsp;&nbsp; return</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[0] == ((PRUint32*)
&amp;other.m0)[0]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[1] == ((PRUint32*)
&amp;other.m0)[1]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[2] == ((PRUint32*)
&amp;other.m0)[2]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[3] == ((PRUint32*)
&amp;other.m0)[3]);</TT>
<BR><TT>&nbsp; }</TT>
<BR><TT>};</TT></UL>
On windows, the "uuidgen" program (provided with Visual C++) can be used
to generate these identifiers.
<H2>
nsISupports</H2>
This is the base class for all component objects. Not all objects are component
objects; these rules apply to objects which expose an interface which is
shared across dll/exe boundaries. Here is nsISupports:
<UL><TT>typedef nsID nsIID;</TT>
<BR><TT>class nsISupports {</TT>
<BR><TT>public:</TT>
<BR><TT>&nbsp; virtual nsqresult QueryInterface(const nsIID&amp; aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void** aInstancePtr) = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt AddRef() = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt Release() = 0;</TT>
<BR><TT>};</TT></UL>
The semantics of this interface are identical to win32's "COM" IUnknown
interface. In addition, the types are carefully mapped and the names are
the same so that if necessary we can "flip a switch" and have the windows
version (or any other platform that embraces COM) use the native COM IUnknown
without source code modification.
<H2>
Factory Procedures</H2>
Factory procedures use this design pattern
<UL><TT>nsqresult NS_NewFoo(nsIFoo** aInstancePtr, nsISupports* aOuter,
...);</TT></UL>
The return value is a status value (see nsISupports.h for the legal return
values); the first argument is a pointer to a cell which will hold the
new instance pointer if the factory procedure succeeds. The second argument
is a pointer to a containing component object that wishes to aggregate
in the Foo object. This pointer will be null if no aggregation is requested.
If the factory procedure cannot support aggregation of the Foo type then
it fails and returns an error if aggregation is requested.
<P>The following symbols are defined for standard error return values from
<TT>QueryInterface</TT> and from factory procedures:
<UL><TT>#define NS_FAILED(_nsresult) ((_nsresult) &lt; 0)</TT>
<BR><TT>#define NS_SUCCEEDED(_nsresult) ((_nsresult) >= 0)</TT>
<P><TT>// Standard "it worked" return value</TT>
<BR><TT>#define NS_OK 0</TT>
<P><TT>// Some standard error codes we use</TT>
<BR><TT>#define NS_ERROR_BASE ((nsresult) 0xC1F30000)</TT>
<BR><TT>#define NS_ERROR_OUT_OF_MEMORY (NS_ERROR_BASE + 0)</TT>
<BR><TT>#define NS_ERROR_NO_AGGREGATION (NS_ERROR_BASE + 1)</TT>
<BR><TT>#define NS_NOINTERFACE ((nqresult) 0x80004002L)</TT></UL>
<H2>
nsIFactory</H2>
Factory classes should eventually replace factory procedures for major
classes. They provide an easy mechanism for placing code in DLLs. The nsIFactory
class is as follows:
<BR>&nbsp;
<UL><TT>class nsIFactory: public nsISupports {</TT>
<BR><TT>public:</TT>
<UL><TT>virtual nsresult CreateInstance(const nsIID &amp;aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nsISupports *aOuter,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void **aResult) = 0;</TT>
<BR><TT>virtual void LockFactory(PRBool aLock) = 0;</TT></UL>
<TT>};</TT></UL>
This interface is again identical to the COM version. More on registering
factories shortly.
<H2>
Error Handling</H2>
Because no exceptions are returned, error handling is done in the traditional
"error status value" method.
<H2>
Cross Platform Registry</H2>
A cross platform registry was written for the SmartUpdate feature of Communicator.
We will investigate it's usefulness for our purposes.
<H2>
Library Management</H2>
NSPR 2.x provides the cross platform mechanism for loading and unloading
libraries, and run time linking.
<BR>&nbsp;
</BODY>
</HTML>

8
xpcom/doc/README Normal file
View File

@ -0,0 +1,8 @@
<HTML>
<HEAD>
<TITLE>READ ME</TITLE>
</HEAD>
<BODY>
<H4><P>
XPCOM documentation can be found at <a href="http://www.mozilla.org/projects/xpcom>www.mozilla.org/projects/xpcom</a>

View File

@ -1,254 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (WinNT; U) [Netscape]">
<meta name="Author" content="Suresh Duddi">
<title>TODO List for XPCOM</title>
</head>
<body>
<center>
<h1>
TODO List for XPCOM</h1></center>
<center>Last updated: 25 March 1999
<br><a href="mailto:dp@netscape.com">Suresh Duddi</a></center>
<table BORDER WIDTH="100%" NOSAVE >
<tr NOSAVE>
<th NOSAVE>Task</th>
<th NOSAVE><a href="http://bugzilla.mozilla.org/bug_status.html#priority">Priority</a></th>
<th NOSAVE>Owner</th>
<th NOSAVE>MileStone complete/Status</th>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>Move xpcom from using NR_*() functions (modules/libreg) to nsIRegistry
(xpcom/src/nsRegistry.cpp)
<ul>
<li>
Mainly you want to change all the Platform*() functions in nsComponentManager.cpp</li>
<li>
Now we open/close the registry all the time. I want to keep the registry
open all the time. That would get performance up.</li>
<li>
Platform*() functions use the NR_*Raw() functions in some places. I wonder
if the nsRegistry has a equivalent. If not we need to create them.</li>
</ul>
Mostly, there is equivalence between NR_*() calls and nsRegistry calls.&nbsp;</td>
<td>P2</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>3/22/1999 started
<br>3/27/1999 Patch submitted
<br>3/30/1999 landing
<br><b>DONE</b></td>
</tr>
<tr BGCOLOR="#33CCFF">
<td>RegisterFactory() and RegisterComponent(..persist=0) ignoring CONTRACTID.
Needs Fix.</td>
<td>P1</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/6/1999 started
<br>4/7/1999 Patch submitted
<br>4/12/1999 Patch Checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Startup components: Some components need to be created at startup.
Have a framework for them.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td></td>
</tr>
<tr>
<td>nsIRegistry access via Javascript.</td>
<td>P1</td>
<td></td>
<td>IDL of nsIRegistry will fix this says <a href="mailto:jband@netscape.com">John
Bandhauer</a></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>API changes: Remove all pathlist. XPCOM should support only
paths.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>4/2/1999 Checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Fix xpcom from being initialized before main from static variables.</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>3/22/1999 Started.
<br>- checked in a fixed xpcom initialization sequence.
<br>- Now got to fix all code statically calling it. I know Netlib does.
<br>- 4/1/1999 Fixed netlib on unix from static intialization. WIN is left.</td>
</tr>
<tr>
<td>Path handling: Use nsFileSpec instead of file path names. Char * pathnames
are not intl, and cannot be stored in the registry. Plus that wont support
mac aliases.
<ul>
<li>
Possibly move autoreg out of xpcom</li>
</ul>
</td>
<td>P1</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a>
<br><a href="mailto:rjc@netscape.com">Robert Churchill</a></td>
<td>3/24/1999 started
<br><b>Blocked </b>on deciding which solution to pick.</td>
</tr>
<tr>
<td>Registry dump utility (regExport exists on windows) and about:registry
(or) better yet an rdf data source for the registry.</td>
<td>P3</td>
<td><a href="mailto:dp@netscape.com">Suresh Duddi</a></td>
<td>4/5/1999 Fixed regExport to accurately dump the registry on win and
unix.
<br>- regExport needs to be compiled on the mac.</td>
</tr>
<tr>
<td>Replace use of nsVector (PL_Vector) with nsISupportsArray</td>
<td>P3</td>
<td></td>
<td></td>
</tr>
<tr>
<td>PATH argument to NSRegisterSelf() and NSUnregisterSelf() to be a nsISupports</td>
<td>P1</td>
<td></td>
<td></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>Code Cleanup:
<ul>
<li>
Registry path strings in nsComponentManager.cpp #defined</li>
</ul>
</td>
<td>P3</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/1/1999 started
<br>4/5/1999 Patch submitted and checked in
<br><b>DONE</b></td>
</tr>
<tr BGCOLOR="#33CCFF">
<td>Performance
<ul>
<li>
Cache commonly used registry keys</li>
</ul>
</td>
<td>P1</td>
<td>Nick Ambrose &lt;<a href="mailto:nicka87@hotmail.com">nicka87@hotmail.com</a>></td>
<td>4/1/1999 started
<br>4/5/1999 Patch submitted and checked in
<br><b>DONE</b></td>
</tr>
<tr>
<td>Factories: Use previously created factories for object creation instead
of creating the factory everytime the object needs to be created.
<ul>
<li>
This is very tricky as the factory is owned by the component and when it
decides to unload itself on a CanUnload() call, the factory will be released.
Got to make sure that the component manager gets notified of this if it
caches the factory.</li>
</ul>
</td>
<td>P2</td>
<td></td>
<td></td>
</tr>
<tr BGCOLOR="#33CCFF" NOSAVE>
<td NOSAVE>nsIAllocator: wrap it in a static api</td>
<td>P2</td>
<td><a href="mailto:jband@netscape.com">John Bandhauer</a></td>
<td NOSAVE>3/31/1999 started
<br>4/2/1999 Check in
<br><b>DONE</b></td>
</tr>
</table>
<h2>
Documentation on XPCOM</h2>
<ul>
<li>
<a href="TODO.html">TODO List</a> &lt;<i>this page></i></li>
<li>
XPCOM main page : <a href="http://www.mozilla.org/projects/xpcom">http://www.mozilla.org/projects/xpcom</a></li>
<li>
<a href="xpcom-code-faq.html">Code FAQ</a></li>
<li>
<a href="xpcom-component-registration.html">Component Registration</a></li>
</ul>
<hr WIDTH="100%">
</body>
</html>

View File

@ -1,93 +0,0 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; U) [Netscape]">
<TITLE>C++ Tips</TITLE>
</HEAD>
<BODY>
<H1>
C++ Tips</H1>
This is a compilation of tips on how to write cross-platform C++ code that
compiles everywhere.
<H2>
General</H2>
<UL>
<LI>
Always use the nspr types for intrinsic integer types. The only exception
to this rule is when writing machine dependent code that is called from
xp code. In this case you will probably need to bridge the type systems
and cast from an nspr type to a native type. The other exception is floating
point; nspr defines PRFloat as a double (!).</LI>
<LI>
Exceptions do not work everywhere so don't use them anywhere except in
machine specific code, and then if you do use them in machine specific
code you must catch all exceptions there because you can't throw the exception
across xp code.</LI>
<LI>
Templates do not work everywhere so don't use them anywhere.</LI>
<LI>
Do not wrap include statements with an #ifdef. The reason is that when
the symbol is not defined, other compiler symbols will not be defined and
it will be hard to test the code on all platforms. An example of what <B>not</B>
to do:</LI>
<BR>&nbsp;
<UL><TT>#ifdef X</TT>
<BR><TT>#include "foo.h"</TT>
<BR><TT>#endif</TT>
<BR><TT></TT>&nbsp;</UL>
<LI>
For types that do not need operator= or a copy constructor, declare them
yourselves and make them private. Example:</LI>
<BR>&nbsp;
<UL><TT>class foo {</TT>
<BR><TT>...</TT>
<BR><TT>private:</TT>
<BR><TT>&nbsp; // These are not supported and are not implemented!</TT>
<BR><TT>&nbsp; foo(const foo&amp; x);</TT>
<BR><TT>&nbsp; foo&amp; operator=(const foo&amp; x);</TT>
<BR><TT>};</TT></UL>
<LI>
</LI>
</UL>
<H2>
Windows Compatability</H2>
<H2>
Metroworks Compatability</H2>
<UL>
<LI>
MAC compilers do not handle #include path names in the same manner as other
systems. Consequently #include statements should not contain path names,
just simple file names. An example of what <B>not</B> to do:</LI>
<BR>&nbsp;
<UL>#include "gemini/nsICSSParser.h"
<BR>&nbsp;</UL>
<LI>
</LI>
</UL>
<H2>
G++ Compatability</H2>
<UL>
<LI>
Use void in argument lists for functions that have no arguments (this works
around a bug in g++ 2.6.3)</LI>
</UL>
</BODY>
</HTML>

View File

@ -1,774 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Suresh Duddi">
<meta name="GENERATOR" content="Mozilla/4.61 [en] (WinNT; U) [Netscape]">
<title>Memory leaks fixing</title>
</head>
<body>
<center>
<h1>
Memory leaks fixing effort
<hr WIDTH="100%"></h1></center>
<h2>
Viewer</h2>
<ul>
<li>
Startup (not the firsttime)</li>
<li>
Show default page</li>
<li>
Quit</li>
</ul>
<table BORDER COLS=3 WIDTH="100%" >
<tr>
<th>Component</th>
<th>Leaks fixing by...</th>
<th>Status (<a href="#Stage 1: nsIModule conversion">nsIModule conversion</a>)</th>
</tr>
<tr BGCOLOR="#FFFF99">
<td COLSPAN="3"><b>bin/Components/</b></td>
</tr>
<tr>
<td>caps.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>chardet.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>history.dll</td>
<td>dp</td>
<td>DONE</td>
</tr>
<tr>
<td>jsloader.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>lwbrk.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko_resource.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko_file.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>nsgif.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>nslocale.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>mimetype.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>oji.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>profile.dll</td>
<td>dp</td>
<td>DONE</td>
</tr>
<tr>
<td>raptorhtml.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>raptorview.dll</td>
<td>dp</td>
<td>DONE (doesnt cache factory)</td>
</tr>
<tr>
<td>rdf.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>uconv.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvlatin.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucharuti.dll</td>
<td>ftang</td>
<td>DONE</td>
</tr>
<tr>
<td>xpc3250.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>xppref32.dll</td>
<td>dp</td>
<td>DONE&nbsp;</td>
</tr>
<tr BGCOLOR="#FFFF99">
<td COLSPAN="3"><b>bin/</b></td>
</tr>
<tr>
<td>jsdom.dll</td>
<td></td>
<td></td>
</tr>
<tr>
<td>raptorhtmlpars.dll</td>
<td>vidur</td>
<td>DONE</td>
</tr>
<tr>
<td>raptorgfxwin.dll</td>
<td></td>
<td></td>
</tr>
<tr>
<td>raptorweb.dll</td>
<td></td>
<td></td>
</tr>
<tr>
<td>raptorplugin.dll</td>
<td></td>
<td></td>
</tr>
<tr>
<td>raptorwidget.dll</td>
<td></td>
<td></td>
</tr>
</table>
<h2>
Apprunner only</h2>
&nbsp;
<table BORDER COLS=3 WIDTH="100%" >
<tr>
<th>Component</th>
<th>Leaks fixing by...</th>
<th>Status (<a href="#Stage 1: nsIModule conversion">nsIModule conversion</a>)</th>
</tr>
<tr>
<td>addrbook.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>bookmarks.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>brprof.dll</td>
<td>XXX</td>
<td>rjc says: This should be removed from build. See bug # 13732</td>
</tr>
<tr>
<td>chrome.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>cnvts.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>cookie.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>directory.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>emitter.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>ender.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>eventloop.dll</td>
<td>XXX - Don't do this</td>
<td></td>
</tr>
<tr>
<td>intlcmpt.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>jar50.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>jsurl.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>mime.dll</td>
<td>mscott</td>
<td>DONE</td>
</tr>
<tr>
<td>mork.dll</td>
<td>bienvenu</td>
<td>DONE</td>
</tr>
<tr>
<td>mozbrwsr.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>mozfind.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>mozucth.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>mozxfer.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>msgbase.dll</td>
<td>putterman</td>
<td>DONE</td>
</tr>
<tr>
<td>msgcompo.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>msgdb.dll</td>
<td>bienvenu</td>
<td>DONE</td>
</tr>
<tr>
<td>msgimap.dll</td>
<td>mscott</td>
<td>DONE</td>
</tr>
<tr>
<td>msglocal.dll</td>
<td>mscott</td>
<td>DONE</td>
</tr>
<tr>
<td>msgnews.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>nativeapp.dll</td>
<td>XXX - Don't do this</td>
<td></td>
</tr>
<tr>
<td>necko_about.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko_data.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko_ftp.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>necko_http.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>nsjpg.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>nspng.dll</td>
<td>kipp</td>
<td>DONE</td>
</tr>
<tr>
<td>nsprefm.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>nsxpi.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>pics.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>prefwind.dll</td>
<td>alecf</td>
<td>DONE</td>
</tr>
<tr>
<td>rdfdomds.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>regviewer.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>related.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>sample.dll</td>
<td>-sample- Don't do this one.</td>
<td></td>
</tr>
<tr>
<td>search.dll</td>
<td>rjc</td>
<td>DONE</td>
</tr>
<tr>
<td>stremcnv.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>strres.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>txmgr.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>txtsvc.dll</td>
<td>morse</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvcn.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvja.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvko.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvtw.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>ucvtw2.dll</td>
<td>cata</td>
<td>DONE</td>
</tr>
<tr>
<td>vcard.dll</td>
<td>XXX - Don't do this</td>
<td></td>
</tr>
<tr>
<td>wallet.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>wlltvwrs.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>xpctest.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
<tr>
<td>xpiflash.dll</td>
<td>neeti</td>
<td>DONE</td>
</tr>
</table>
<br>&nbsp;
<h2>
How to fix leaks in a dll</h2>
<h3>
<a NAME="Stage 1: nsIModule conversion"></a>Stage 1: nsIModule conversion</h3>
<ol>
<li>
Convert dll to use nsIModule. Sample code is in&nbsp; <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/sample/nsSampleModule.cpp">mozilla/xpcom/sample/nsSampleModule.cpp</a>.
Things to watch out for:</li>
<ol>
<li>
nsIModule::UnregisterSelf should not return an Error.</li>
<li>
Cache factories created by modules in the module.</li>
</ol>
The sample code does all this right. So sticking to closely is adviced.</ol>
<h3>
<a NAME="Stage 2: Leak fixing"></a>Stage 2: Leak fixing <font color="#CC0000">(DONT
DO THIS NOW)</font></h3>
<ol>
<li>
While in purify run <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/tests/TestShutdown.cpp">bin/TestShutdown</a>
on the dll. For this you will need to find a CID that the module implements.
Then invoke TestShutdown as</li>
<ol>TestShutdown {123d4-4908-490840-409850}</ol>
<li>
Make sure there are no leaks from the purify output.</li>
<br>Use ns&lt;dll>Module::Shutdown() to release any global memory that
is being leaked.</ol>
<hr WIDTH="100%">
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>

View File

@ -1,262 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>nsIClassInfo Overview</title>
<meta name="author" content="Mike Shaver">
<meta name="description" content="General Overview of nsIClassInfo infrastructure">
<style type="text/css">
a:link, a:visited { text-decoration: none; }
</style>
</head>
<body bgcolor="#ffffff" link="#0000ee" vlink="#551a8b" alink="#0000ee">
<h2><code>nsIClassInfo</code> Overview</h2>
Mike Shaver &lt;<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>
&gt;<br>
&nbsp;&nbsp; &nbsp; Last Modified: March 12, 2001<br>
<hr align="Left" width="100%" size="2">
<h3>Table of Contents</h3>
<ul>
<li><a href="#What_is_nsIClassInfo">What is <code>nsIClassInfo</code>?</a></li>
<li><a href="#How_do_I_use_it">How do I use it?</a><a href="#What_is_nsIClassInfo"></a></li>
<li><a href="#Doesnt_that_break_the_COM">Doesn't that break the COM <code>
QueryInterface</code> rules?</a><a href="#Doesnt_that_break_the_COM"></a></li>
<li><a href="#What_are_the_language_helpers_for">What are the "language
helpers" for?</a><br>
</li>
<li><a href="#That_sounds_useful_How_do_I_make_it">That sounds useful.
How do I make that work with my code?</a></li>
<ul>
<li>I'm writing C++ code, and</li>
<ul>
<li><a href="#Im_writing_C_code_and_I_use_the">I use the generic factory
and <code>nsModuleComponentInfo</code></a></li>
<li><a href="#Im_writing_C_code_and_I_use_a_custom">I use a custom factory
or a singleton service object</a><br>
</li>
</ul>
</ul>
<ul>
<li><a href="#Im_writing_JS_code">I'm writing JS code.</a></li>
</ul>
<li><a href="#Whats_interface_flattening">What's "interface flattening"?</a><br>
</li>
</ul>
<hr align="Left" width="100%" size="2">
<h4><a name="What_is_nsIClassInfo"></a>What is <code>nsIClassInfo</code>?</h4>
<p><a href="http://lxr.mozilla.org/mozilla/source/xpcom/components/nsIClassInfo.idl#38"><code>
nsIClassInfo</code></a> is an interface that provides information
about a specific implementation class, to wit:</p>
<ul>
<li> a contract ID and class ID through which it may be instantiated;</li>
<li>the language of implementation (C++, JavaScript, etc.);</li>
<li> a list of the interfaces implemented by the class;</li>
<li>flags indicating whether or not the class is threadsafe or a singleton;
and</li>
<li>helper objects in support of various language bindings.</li>
</ul>
<h4><a name="How_do_I_use_it"></a>How do I use it?</h4>
<p> To get the <code>nsIClassInfo</code> object for the implementation behind
a given interface, simply <code>QueryInterface</code> for the nsIClassInfo
interface:</p>
<blockquote>C++:<br>
<code>nsCOMPtr&lt;nsIClassInfo&gt; info = do_QueryInterface(ifacePtr);</code><br>
<br>
JavaScript:<br>
<code>var info = ifacePtr.QueryInterface(Components.interfaces.nsIClassInfo);</code></blockquote>
<p>It's important to note that this will usually return a <i>singleton</i>
object: there often exists only one nsIClassInfo implementation for
all implementations of a given class. This is very important, because it
means that you can't <code>QueryInterface</code> back to the original object,
no matter how hard you try.</p>
<h4><a name="Doesnt_that_break_the_COM"></a>Doesn't that break the COM
<code>QueryInterface</code> rules?</h4>
<p>Quite. As discussed in <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">
bug 67699</a>, though, it's a reasonable concession to make in order
to avoid an additional vtbl entry on every class that wants to export <code>
nsIClassInfo</code> data.<br>
</p>
<h4><a name="What_are_the_language_helpers_for"></a>What are the "language
helpers" for?</h4>
<p>The language helpers are basically hooks for alternate language bindings
to use for providing language-specific wrapping and manipulation behaviour,
without adding code to every wrapped object.&nbsp; In <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">
bug 67669</a>, jband tells us what XPConnect does with the language helpers:</p>
<blockquote>
<p>When wrapping an object xpconnect QIs the object for its classinfo
(say 'foo'). If it has seen that foo classinfo pointer before then it knows
that this object is a foo and it can reuse all the info is knows about foo
objects. If it has never seen foo it will gather info (such as the JS helper)
and remember that for future wrappings of foo objects.</p>
<p> Assuming that the foo helper tells xpconnect to not bother QI'ing
each foo instance for a per instance helper (or if the instances don't respond
to QI for the helper) then the same foo helper is used on all calls from
JS relating to the foo instances. </p>
<p>What you may be missing is that methods on the helper (nsIXPCScriptable
in the xpconnect case) *all* receive a pointer to the instance wrapper when
called. I.e. the helper methods have an explicit 'self' param. This allows
the helper to customize its response for each method call without requiring
a helper per instance.</p>
</blockquote>
See <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=67699">bug 67699</a>
for more interesting discussion about pluggable language helpers and decoupling
them from specific wrapped classes.
<p></p>
<h4><a name="That_sounds_useful_How_do_I_make_it"></a>That sounds useful.
How do I make it work with my code?</h4>
<p>Why, yes, it <i>is</i> useful. To provide <code>nsIClassInfo</code>
data for your class, you need to ensure that it returns an <code>nsIClassInfo</code>
-implementing object when it is <code>QueryInterface</code>d for <code>
nsIClassInfo</code> . Simple enough, but it can be even simpler through
the use of a handful of helper macros/functions. Choose your own adventure:</p>
<h4><a name="Im_writing_C_code_and_I_use_the"></a>I'm writing C++ code,
and I use the generic factory and <code>nsModuleComponentInfo</code>.</h4>
<p>First, make sure that your class has the <code>nsIClassInfo</code>
helpers, by changing the <code>NS_IMPL_ISUPPORTS</code> line:</p>
<blockquote><code>NS_IMPL_ISUPPORTS2(nsSampleImpl, nsISample, nsIOther)</code><br>
</blockquote>
<p>becomes</p>
<blockquote><code>NS_IMPL_ISUPPORTS2_CI(nsSampleImpl, nsISample, nsIOther)</code><br>
</blockquote>
<p>This will provide an implementation of a helper function, named
<code>nsSampleImpl_GetInterfacesHelper</code>, which handles the processing
of <code>nsIClassInfo::getInterfaces</code>.</p>
<p>Next, in your module code, use <code>NS_DECL_CLASSINFO</code> to
provide the rest of the per-class infrastructure (a global pointer into
which to stash the <code>nsIClassInfo</code> object, and an extern declaration
of the interfaces-helper, in case it's defined in another file):</p>
<blockquote><code>NS_DECL_CLASSINFO(nsSampleImpl)</code><br>
</blockquote>
<p>You'll need one of these lines for each <code>nsIClassInfo</code>
-supporting class represented in your <code>nsModuleComponentInfo</code>
array.</p>
<p>Lastly, fill in the appropriate members of <code>nsModuleComponentInfo</code>
to wire everything up:</p>
<blockquote><code>static nsModuleComponentInfo components[] =</code><br>
<code>{</code><br>
<code> &nbsp; {<br>
&nbsp; &nbsp; "Sample Component", NS_SAMPLE_CID, NS_SAMPLE_CONTRACTID,
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>
&nbsp; &nbsp; nsSampleImplConstructor,</code><br>
<code> &nbsp; &nbsp; nsSampleRegistrationProc,</code><br>
<code> &nbsp; &nbsp; nsSampleUnregistrationProc,</code><br>
<code> &nbsp; &nbsp; nsnull /* no factory destructor */,</code><br>
<code><font color="#ff0000"> &nbsp; &nbsp; NS_CI_INTERFACE_GETTER_NAME(nsSampleImpl),&nbsp;
/* interface getter */</font></code><br>
<code> &nbsp; &nbsp; nsnull /* no language helper */,</code><br>
<code><font color="#ff0000"> &nbsp; &nbsp; &amp;NS_CLASSINFO_NAME(nsSampleImpl),&nbsp;
/* global class-info pointer */</font></code><br>
<code> &nbsp; &nbsp; 0 /* no class flags */<br>
&nbsp; }</code><br>
<code>};</code><br>
</blockquote>
<p>If you want to add a callback which provides language-helper
objects, replace the last <code>nsnull</code> with your callback. See the
<a href="http://lxr.mozilla.org/mozilla/source/xpcom/components/nsIClassInfo.idl"><code>
nsIClassInfo</code> IDL file</a> for details on language helpers and
other esoterica.</p>
<p><b><i>Note</i></b>: the details of these macros may change
slightly over the next week or so, as we refine a system for using table-driven
QI and sharing data between QI and the class-info calls.<br>
</p>
<h4><a name="Im_writing_C_code_and_I_use_a_custom"></a>I'm writing
C++ code, and I use a custom factory or a singleton service object.</h4>
<p>You need some utility macros, don't ya?&nbsp; We're working
on it.&nbsp; (You should really use the generic factory and module, though.&nbsp;
See <a href="http://lxr.mozilla.org/seamonkey/source/intl/uconv/src/nsUConvModule.cpp">
nsUConvModule.cpp</a> for an example of how to use <code>nsModuleComponentInfo</code>
and the generic modules even when you have highly-custom registration
requirements.)</p>
<h4><a name="Im_writing_JS_code"></a>I'm writing JS code.</h4>
You poor thing. You suffer without even a GenericModule helper. We're
<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=71689">working on
that</a>, too.
<h4><a name="Whats_interface_flattening"></a>What's "interface
flattening"?</h4>
<p></p>
<p> Interface flattening is a way to present multiple interfaces
of the same object to a language binding, without requiring explicit <code>
QueryInterface</code> calls.&nbsp; Consider the following interfaces and
an object <code>obj</code> that implements both of them:</p>
<blockquote>
<p><code>interface nsIFoo : nsISupports {<br>
&nbsp; &nbsp; void fooMeth(in string message);<br>
};</code></p>
<p><code>interface nsIBar : nsISupports {<br>
&nbsp; &nbsp; void barMeth(in PRUint32 meaning);<br>
};</code></p>
</blockquote>
<p>You could use the following code to call both fooMeth and
barMeth without any QueryInterface:<br>
</p>
<blockquote><code>obj.fooMeth("welcome to foo");<br>
obj.barMeth(42);</code></blockquote>
<p>Pretty, no?&nbsp; Pretty, yes. </p>
<p>There are also intricacies related to conflicting method
names and the difference between interface sets that are part of a contract's
promise and those which are simply artifacts of the implementation, but they're
beyond the scope of this overview.<br>
<br>
</p>
</body>
</html>

View File

@ -1,487 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; U; Linux 2.2.5-15 i686) [Netscape]">
<title>xpcom-review</title>
</head>
<body>
<center>
<h1>
XPCOM Brown Bag I</h1></center>
<center>Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
<br>August 17, 1999&nbsp;
<hr WIDTH="100%"></center>
<h3>
Terminology</h3>
&nbsp;
<table BORDER WIDTH="100%" NOSAVE >
<tr NOSAVE>
<td NOSAVE>Interface</td>
<td>Contract betwen the implementation and usage. A pure virtual abstract
base class with no data members. eg. nsIZip</td>
</tr>
<tr>
<td>IID</td>
<td>Interface ID {xxxxx-xxx-xxx-xxxxxx} a unique number that identifies
the Interface being talked about</td>
</tr>
<tr>
<td>nsISupports</td>
<td>The mother of all interfaces. All interfaces ultimately inherit from
this. Provides refcounting. The IID and definition has been carefully choosen
so as to be binary compatible with COM.</td>
</tr>
<tr>
<td>Component</td>
<td>An implementation of a set of interfaces identified by a CLSID</td>
</tr>
<tr>
<td>Object</td>
<td>An instance of a Component</td>
</tr>
<tr>
<td>CLSID</td>
<td>Component ID&nbsp; {xxxxx-xxx-xxx-xxxxxx} a unique number that identifies
a component</td>
</tr>
<tr>
<td>Module</td>
<td>A packaging of a set of Components (ie) a DLL</td>
</tr>
<tr>
<td>Factory</td>
<td>An object whose sole purpose is creation of objects of a particular
component. There exists only one factory for every Component (CLSID). The
IID and definition has been carefully choosen so as to be binary compatible
with COM. nsIFactory</td>
</tr>
<tr>
<td>ClassObject</td>
<td>Same object as factory.</td>
</tr>
<tr>
<td>ContractID</td>
<td>A String name for a Component.</td>
</tr>
<tr>
<td>ComponentManager</td>
<td>Central Object of XPCOM that provides API for object creation and management.</td>
</tr>
<tr>
<td>ServiceManager</td>
<td>A singleton manager. Holds and manages singleton references to objects
for application. Going to be merged with the componentmanager.</td>
</tr>
<tr>
<td>Service</td>
<td>A singleton object within an application.</td>
</tr>
<tr>
<td>Registry</td>
<td>A hierarchical attribute-value pair storage.</td>
</tr>
<tr>
<td>XPIDL</td>
<td>Cross Platform Interface Definition Language. Language for expressing
interfaces.</td>
</tr>
<tr>
<td>Typelib</td>
<td>A storage for meta information about interfaces. Interfaces expressed
in IDL have their meta information maintained in Typelib automatically.</td>
</tr>
<tr>
<td>XPConnect</td>
<td>Ability to call c++ implementations of interfaces expressed in IDL
from javascript and viceversa.</td>
</tr>
</table>
<h3>
An Interface</h3>
<ul>
<li>
E.g Image Decoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/public_com/nsIImgDecoder.h">nsIImgDecoder</a></li>
<br>&nbsp;
<li>
Dont put data members</li>
<li>
Return value of member function should always be <tt>nsresult using the
NS_IMETHOD macro.</tt></li>
<li>
Use XPIDL for interface header files</li>
<li>
Useful Macros if not using XPIDL</li>
<ul>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_STATIC_IID_ACCESSOR">NS_DEFINE_STATIC_IID_ACCESSOR</a>
- Defines static GetIID() method for an interface</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMETHOD">NS_IMETHOD</a>
- Prototypes return value of interface function declaration</li>
</ul>
</ul>
<h3>
The Component</h3>
<ul>
<li>
E.g GIF Image Decoder nsGIFDecoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFDecoder.h">nsGIFDecoder.h</a>,
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFDecoder.cpp">nsGIFDecoder.cpp</a></li>
<br>&nbsp;
<li>
Useful Macros</li>
<ul>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DECL_ISUPPORTS">NS_DECL_ISUPPORTS</a>
- Declares all methods of nsISupports. Used in implementation declaration
header file.</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_INIT_ISUPPORTS">NS_INIT_ISUPPORTS</a>&nbsp;
- nitilize the base class ISupports. Used in constructor of implementation.</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ISUPPORTS">NS_IMPL_ISUPPORTS</a>
- Implement the nsISupports functions. Used in implementation file.</li>
<ul>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ADDREF">NS_IMPL_ADDREF</a>
- Implementation of nsISupports::Release()</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_RELEASE">NS_IMPL_RELEASE</a>
- Implementation of nsISupports::AddRef()</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_QUERY_INTERFACE">NS_IMPL_QUERY_INTERFACE</a>
- Implementation of nsISupports::QueryInterface() for one IID</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMPL_ISUPPORTS2">NS_IMPL_ISUPPORTS2</a>
- Implements the nsISupports function with QueryInterface for two IIDs</li>
<br>&nbsp;</ul>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_IID">NS_DEFINE_IID</a>
- Define a variable of type nsIID initialized with a struct representatio
of an IID</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>
- Use this instead of nsIFoo::GetIID() or NS_DEFINE_IID()...</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_DEFINE_CID">NS_DEFINE_CID</a>
- Define a variable of type nsCID intialized with a struct representation
of the CLSID</li>
<br>&nbsp;
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IMETHODIMP">NS_IMETHODIMP</a>
- Prototypes return value for interface functions implementation. Used
in implementation file.</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_ADDREF">NS_ADDREF</a>,
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IF_ADDREF">NS_IF_ADDREF</a>&nbsp;
- Addref an object by client</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_ADDREF_THIS">NS_ADDREF_THIS</a>
- Addref used in object implementation. Dont need this if using NS_IMPL_ADDREF</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE">NS_RELEASE</a>,
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_IF_RELEASE">NS_IF_RELEASE</a>
- Release an object by client</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE_THIS">NS_RELEASE_THIS</a>
- Released used in object implementation. Dont need this if using NS_IMPL_RELEASE</li>
<li>
<a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_RELEASE2">NS_RELEASE2</a>
- Release and get the refcount. Useful to check if refcount hit Zero.</li>
<br>&nbsp;</ul>
<li>
Generic Factory - A generic factory implementation with callback ability
for object creation. Simplies factory implementation.</li>
</ul>
<h3>
Object Creation</h3>
<ul><tt>rv = compMgr->CreateInstance(imgContractID, NULL, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>(nsIImgDecoder),
(void **)&amp;imgdec);</tt>
<br>&nbsp;
<li>
It is preferable to use the NS_GET_IID() version of getting iid instead
of the old way</li>
<ul>
<li>
NS_DEFINE_IID(kImgDecodeIID, NS_IIMGDECODER_IID);</li>
<br>and then using kImgDecoderIID for the IID
<li>
<b>DO NOT USE nsIImgDecoder::GetIID()</b></li>
</ul>
<li>
The component manager does this on a CreateInstance()</li>
<ul>
<li>
map ContractID to CLSID</li>
<li>
Get module object for dll which implements component CLSID</li>
<li>
nsISupports classObject = module->GetClassObject()</li>
<li>
nsIFactory factory = classObject->QueryInterface(NS_GET_IID(nsIFactory));</li>
<li>
return factory->CreateInstance(IID);</li>
</ul>
<li>
<b>[hint]</b> Use nsCOMPtr</li>
<br>&nbsp;
<ul><tt>nsCOMPtr &lt;nsIImgDecoder> imgdec;</tt>
<br><tt>rv = compMgr->CreateInstance(imgContractID, NULL, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NS_GET_IID">NS_GET_IID</a>(nsIImgDecoder),
<font color="#990000">getter_AddRefs(imgdec)</font>);</tt></ul>
</ul>
<h3>
Object Release</h3>
<blockquote><tt>NS_IF_RELEASE(obj);</tt>
<p>It should be noted that release and addref are directly talking to the
object with no intermediaries. The macro NS_*_RELEASE() set the object
to NULL.</blockquote>
<h3>
Component Registration Process</h3>
<ul>
<li>
<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/components/nsIModule.idl">nsIModule.idl</a></li>
</ul>
<ul>At startup of apprunner, a call to <tt>nsIComponentManager::AutoRegister(<i>Startup,
&lt;exedir>/Components</i>)</tt> This will descend recursively looking
for loadable files (files with a certain externsion and on Mac of certain
type) If the file had changed since the last time the file was visited
(ModifiedDate check) registration is initiated on the file.
<p>Registration involves:
<ul>
<li>
Load the dll</li>
<li>
nsIModule module = "NSGetModule"() - Create the module object</li>
<li>
module->RegisterSelf(<i>location</i>)</li>
</ul>
<p><br>The module registers with the componentmanager every {CLSID, ContractID}
it implements with a call to <tt>nsIComponentManager::RegisterComponentSpec()</tt>
These registrations are stored in the registry. Hence the next time around,
the module is loaded not at startup but only when the first object that
is implemented by a component in the module is created.
<p>e.g Registration of GIF Decoder <a href="http://lxr.mozilla.org/seamonkey/source/modules/libimg/gifcom/nsGIFModule.cpp">nsGIFModule.cpp</a>
<p><b>DO NOT CONVERT YOUR COMPONENT TO nsIModule yet. We are working on
the sample code which will make the conversion process even simpler.</b></ul>
<h3>
Module Unloading</h3>
<blockquote>Every module implements a CanUnload() function that returns
a boolean of whether the module can be unloaded. This implies that the
module needs to be counting all outstanding object and return PR_TRUE only
if there are no outstanding objects served from within the module.
<p>Unloading happens either on a Timer or on an explicit call to nsComponentManager::<a href="http://lxr.mozilla.org/seamonkey/ident?i=FreeLibraries">FreeLibraries()</a>.
The general logic is:
<ul>
<li>
PRBool unloadable = module->CanUnload()</li>
<li>
if (unloadable &amp;&amp; marked for unload)</li>
<ul>
<li>
Unload()</li>
</ul>
<li>
if (unloadable &amp;&amp; not mark for unload)</li>
<ul>
<li>
mark for unload</li>
</ul>
</ul>
No assumptions can be made that the module will be unloaded if nsIModule::CanUnload()
returns PR_TRUE. It is guaranteed that if nsIModule::CanUnload() returns
PR_FALSE, the module <b>will not</b> be unloaded.</blockquote>
<h3>
The Component Registry</h3>
<blockquote>Nothing but a persistent hiearchical store of attribute value
pairs. It is the use of the registry by XPCOM that is very interesting.
Physical location of the registry is in the &lt;exedir>/component.reg
<p>The xpcom hierarchy of the registry is considered to be opaque to components.
Use the nsIComponentManager Api to register as opposed to meddling with
the xpcom hierarchy in the registry directly.
<p>mozregistry.dat is NOT the component registry. It is the application
(apprunner) registry.</blockquote>
<h3>
Old Method for Module definition</h3>
<blockquote>Previously module definition was scattered across many exported
functions from a dll.
<br>&nbsp;<a href="http://lxr.mozilla.org/seamonkey/ident?i=NSGetFactory">NSGetFactory(
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSCanUnload">NSCanUnload(
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSRegisterSelf">NSRegisterSelf(
)</a>, <a href="http://lxr.mozilla.org/seamonkey/ident?i=NSUnregisterSelf">NSUnregisterSelf(
)</a>
<br>Now these are combined into a <a href="http://lxr.mozilla.org/seamonkey/source/xpcom/components/nsIModule.idl">nsIModule</a>
<p><b>Please continue to use the old method until sample code using nsIModule
is available.</b></blockquote>
<h3>
ComponentManager vs ServiceManager</h3>
<blockquote>ServiceManager is a an object that holds instances to objects
in a cache and manages them. It uses the ComponentManager to create an
instance the first time an object is queried for. Lifetime of the instance
is currently the lifetime of the app. We are working on what is required
here and how to control the lifetime. Possbily merging ServiceManager with
the ComponentManager.
<p>From the components perspective there is nothing it does special to
behave as a service. The application controls the creation of services
by its usage or call to <tt>nsServiceManager::GetService()</tt> .Some components
that want to enforce being a service return cached instances on <tt>nsComponentManager::CreateInstance()
</tt>.
We are working on a more elegant syntax and semantics for this. Post suggestions
to newsgroup netscape.public.mozilla.xpcom (or Email <a href="mailto:mozilla-xpcom@mozilla.org">mozilla-xpcom@mozilla.org</a>)
with suggestions.</blockquote>
<h3>
ContractID vs CLSID</h3>
<blockquote>CLSID is a number identifying a specific implementation.
<p>ContractID is a like a pointer to a CLSID. It is an opaque string to xpcom.It
is used for two purposes.
<ol>
<li>
Implementation independence for clients: <tt>@mozilla.org/registry;1</tt></li>
<br>The CLSID associating itself to a ContractID can be changed. Hence if a
new implementation with a new CLSID superceeds an older implementation,
the client wont be tied to the older implementation if it uses the ContractID.
<li>
CLSID switching: <tt>@mozilla.org/image/decoder;1?type=image/gif</tt></li>
<br>A client wants to create different objects based on a switch (the mimetype
for the case of imagedecoders). A Contractid is formed with a concatenation
of a BASE_CONTRACTID and the switch (mimetype) and an instance of that created.
Components, when registering, associate their CLSID to specific contractids.</ol>
NOTE: Only Clients that are adamant about the use of a specific implementation
need to create instances using CLSID.
<p>We encourage use of ContractID. This works well in the scriptable world
too.
<p><b>We are working on a ContractID syntax.</b></blockquote>
<h3>
Steps for XPCOM Review</h3>
<ol>
<li>
Know your interfaces and objects.</li>
<br>List the objects your component is serving. List the interfaces that
it implements.
<li>
List the objects that your component uses.</li>
<li>
<a href="http://www.mozilla.org/scriptable/interface-rules-we-break.html">http://www.mozilla.org/scriptable/interface-rules-we-break.html</a></li>
<li>
Do not switch over to using nsIModule yet. We will publish sample code
in a week with guidelines.</li>
<li>
Use the above stated macros.</li>
<li>
<a href="http://www.mozilla.org/projects/xpcom/">http://www.mozilla.org/projects/xpcom/</a>
- <b>Watch for more documents here</b></li>
</ol>
<p><br>
<hr WIDTH="100%">
<br>&nbsp;
</body>
</html>

View File

@ -1,319 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.71 [en] (X11; U; Linux 2.2.12-20 i686) [Netscape]">
<meta name="Author" content="Suresh Duddi">
<title>XPCOM Code FAQ</title>
</head>
<body>
<h2>
XPCOM Code FAQ</h2>
Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
<br>Last Modified: May 25 2000
<br>
<hr WIDTH="100%">
<br>I am documenting things randomly as I am replying to people's questions.
So this looks more like an FAQ.
<h3>
Table of Contents</h3>
<ol>
<li>
<a href="#What are the Global Objects that XPCOM maintains">What are the
Global Objects that XPCOM maintains</a></li>
<li>
<a href="#What are the static classes that XPCOM maintains">What are the
static classes that XPCOM maintains</a></li>
<li>
<a href="#Is there any restriction on which static class I should call fi">Is
there any restriction on which static class I should call first</a></li>
<li>
<a href="#What is the order of creation of the ServiceManager, ComponentM">What
is the order of creation of the ServiceManager, ComponentManager and Registry</a></li>
<li>
<a href="#Is there a global Registry being maintained">Is there a global
Registry being maintained</a></li>
<li>
<font color="#000000"><a href="#ComponentManager Vs ServiceManager">ComponentManager
Vs ServiceManager</a></font></li>
<li>
<a href="#ContractID Vs CLSID">ContractID Vs CLSID</a></li>
<li>
<a href="#How to set break points in component code">How to set breakpoints
in component code</a></li>
<li>
<a href="#Generating a log from xpcom:">Generating the XPCOM LOG</a>
<hr WIDTH="100%"></li>
</ol>
<h4>
<a NAME="What are the Global Objects that XPCOM maintains"></a>What are
the Global Objects that XPCOM maintains</h4>
<ul>mGlobalServiceManager
<br>mGlobalComponentManager</ul>
<h4>
<a NAME="What are the static classes that XPCOM maintains"></a>What are
the static classes that XPCOM maintains</h4>
<blockquote>nsComponentManager
<br>nsServiceManager</blockquote>
<h4>
<a NAME="Is there any restriction on which static class I should call fi"></a>Is
there any restriction on which static class I should call first</h4>
<blockquote>No restrictions. You can call any function from the static
classes nsComponentManager and nsServiceManager. XPCOM will do the right
thing to initialize itself at both places.
<p>Autoregistration() can happen only after Init_XPCOM() is called since
the registy might be required by SelfRegister() functions of the dlls and
it is only in Init_XPCOM() do we create register the RegistryFactory()
with the ComponentManager.</blockquote>
<h4>
<a NAME="What is the order of creation of the ServiceManager, ComponentM"></a>What
is the order of creation of the ServiceManager, ComponentManager and Registry</h4>
<blockquote>Init_XPCOM()
<blockquote>
<li>
create the global service manager</li>
<li>
create the global component manager and register as service with the global
service manager</li>
<li>
RegisterFactory(...RegistryFactory...)&nbsp; Register the RegistryFactory
with the component manager so that new registry objects can be created.</li>
</blockquote>
Now the hard problem is when to trigger Init_XPCOM() There are two static
objects nsComponentManager and nsServiceManager. Any function in either
of them can be called first. Today nsServiceManager::GetService() is the
first one that gets called. All the members of the static nsServiceManager
use the NS_GetGlobalServiceManager() to get to the global service manager.
All members of the static nsComponentManager use the NS_GetGlobalComponentManager()
to get to the global component manager. Hence if we trigger Init_XPCOM()
from both NS_GetGlobalComponentManager() and NS_GetGlobalServiceManager()
we will be safe.</blockquote>
<h4>
<a NAME="Is there a global Registry being maintained"></a>Is there a global
Registry being maintained</h4>
<blockquote>No. The nsIRegistry is designed to be lightweight access to
the registry. Consumers who need to access the registry should use the
component manager to create the their own registry access object. This
is required because the open() call is supported by the nsIRegistry() and
if we maintain a global registry arbitrating which registry file is opened
is going to be a major headach.
<p>The ContractID for the registry will be <font color="#990000">@mozilla.org/registry;1</font>
<br>&nbsp;</blockquote>
<h4>
<a NAME="ComponentManager Vs ServiceManager"></a><font color="#000000">ComponentManager
Vs ServiceManager</font></h4>
<blockquote><font color="#000000">ComponentManager is the only way for
component creation. ComponentManager always uses the component's factory
to create the component instance. Clients (code that calls CreateInstance()
to create and use a component) call the ComponentManager to create instances.
Components (the code that implemented NSRegisterSelf()) calls the ComponentManager
to register itself and gets called when a Client wants to instantiate a
component.</font>
<p><font color="#000000">ServiceManager is a convinience for getting singleton
components, components for which only one instance stays alive for the
entire application e.g Netlib. It enforces only one of a kind of a component
to exist. Hence the notion of getting a service not creating one. (as opposed
to the notion of Creating instances with the componentManager). ServiceManager
is a convenience because components can technically force singletonism
by making their factory return the same instance if one was created already.
The other big use of ServiceManager is the (still unimplemented) notion
of Shutting down a service.</font>
<p><b><i><font color="#000000">Client</font></i></b>
<ul>
<li>
<i><font color="#000000">When does a client use the service manager vs
component manager</font></i></li>
<br><font color="#000000">When a client knows that the component that they
are trying to instantiate is a singleton, they need to call service manager
instead of component manager. Clients dont have to worry about calling
the ComponentManager at all in this case. The ServiceManager will take
care of creating the instance if the first one doesn't exist already.</font>
<br>&nbsp;
<li>
<i><font color="#000000">When does a client use the Component Manager as
opposed to Service Manager</font></i></li>
<br><font color="#000000">When a client wants a private instance of a component,
they call the Component Manager. From the Clients point of view, a new
xpcom object creation happens everytime they call CreateInstance() Anything
else is an implementation detail that the Client need not worry about.</font>
<br>&nbsp;
<li>
<i><font color="#000000">How does a Client know that they have to instantiate
a singleton</font></i></li>
<br><font color="#000000">For now, the Client just has to know. There is
no way of telling which component is a Service and which isn't. In fact,
in todays xpcom (Mar 1999) any component can be accessed as a Service.
Use your judgement until there is a proper method or service manager is
eliminated. There is nothing even in the code that detects Services from
Instances.</font>
<p><b><font color="#CC0000">Need a solution for this. Email suggestion
to <a href="mailto:warren@netscape.com,dp@netscape.com">warren@netscape.com,
dp@netscape.com</a></font></b>
<br>&nbsp;</ul>
<b><i><font color="#000000">Component</font></i></b>
<ul>
<li>
<i><font color="#000000">Can a component enforce use only as a Service</font></i></li>
<br><font color="#000000">No. The notion of the ServiceManager is available
only to Clients.</font>
<p><font color="#000000">Note that at some points when a component wants
another component, it actually behaves as a client and hence follows the
rules of the Client above to either CreateInstance() or GetService() the
needed component.</font>
<p><b><tt><font color="#990000">Workaround:</font></tt></b><font color="#000000">
If however a component wants only one of its instances to exist and cannot
ensure that Clients understand well enough only to use the Service Manager
to get it, it can implement singletonism in its factory. Basically the
factory on first instance creation should hang on to the instance. On subsequence
instance creations, addref the instance it is holding to and return that
instead creating a new one.</font>
<ul>&nbsp;
<br><font color="#000000">E.g preferences does this.</font> Code sample
at
<a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#621">nsPref.cpp
nsPrefFactory::CreateInstance()</a> and&nbsp; <a href="http://lxr.mozilla.org/seamonkey/source/modules/libpref/src/nsPref.cpp#227">nsPref.cpp
nsPref::GetInstance()</a> With this implementation, whether Clients get
to it by calling nsIServiceManager::GetService() or nsIComponentManager::CreateInstance(),
the same object will be returned hence guaranteeing singletonism.</ul>
<li>
<i><font color="#000000">Should a component do anything at creation to
become a Service</font></i></li>
<br><font color="#000000">No. Again, the notion of a ServiceManager is
available only to Clients.</font>
<br>&nbsp;
<li>
<i><font color="#000000">Can a component advertise that it is a service
so clients can use it as one</font></i></li>
<br>No. There isn't a way other than a comment in the interface of the
header file.</ul>
</blockquote>
<h4>
<a NAME="ContractID Vs CLSID"></a>ContractID Vs CLSID</h4>
<blockquote>ClassID or CLSID is the unique indentification of a component.
It is a structure of huge numbers generated by using uuidgen on a windows
box. It is represented as a string in documentation as {108d75a0-bab5-11d2-96c4-0060b0fb9956}
<p>ContractID is the string identification of an implementation of a component
the client is looking for. The representation takes a URI syntax. Eg. <i>@mozilla.org/network/protocol;1?description=Http Protocol Handler&amp;name=http</i>
<br>Some simplify this to, ContractID is a more readable string form of a CLSID.
That is acceptable on the periphery. The ContractID is a Client thing. Components
register with component manager to claim that they are the implementation
for a ContractID. A component can register to be the implementation for multiple
ContractIDs (not implemented yet).
<p><b><i>Client</i></b>
<ul>
<li>
<i>Should CreateInstance() calls use ContractID or CLSID</i></li>
<br>ContractID is what Clients should use to CreateInstances. Clients should
not even know about the CLSID unless they are hell bent on creating a particular
implementation of a component.</ul>
<b><i>Component</i></b>
<ul>
<li>
<i>Should Components register with both a CID and ContractID</i></li>
<br>Absolutely.</ul>
</blockquote>
<h4>
<a NAME="How to set break points in component code"></a>How to set break
points in component code</h4>
<blockquote>
<blockquote>Since components are dynamically loaded only on demand, debugging
them could be a hard. Here are some tips to debugging components.
<p><b><i>Windows: VC5.0 VC6.0</i></b>
<blockquote>Include your component library in the Project->Settings, Additional
Dll. drop down. After that breakpoints can be enabled.</blockquote>
<b><i>Unix: gdb</i></b>
<blockquote>
<ul>
<li>
Let the program run until you are sure that your component is loaded. Type
Control-C. Now all symbols from your component will be available in gdb.
Put your breakpoints and restart the app. Gdb will complain that it cannot
set the breakpoint, and that it is temporarily disabling it, but when the
*.so is loaded, the breakpoint is enabled automatically. - &lt;<a href="mailto:erik@netscape.com">Eric
Van Der Poel</a>></li>
</ul>
<ul>
<li>
I think typing "dir components" (assuming you're in dist/bin) will also
allow you to see the symbols in your stack the first time. - &lt;<a href="mailto:alecf@netscape.com">Alec
Flett</a>></li>
</ul>
<ul>
<li>
Using XPCOM_BREAK_ON_LOAD environment variable:</li>
<p><br><tt>gdb> set env XPCOM_BREAK_ON_LOAD "necko:rdf"</tt>
<br><tt>gdb> r</tt>
<p>This will cause xpcom to break in the debugger after loading any dll
with substrings <tt>necko</tt> or <tt>rdf</tt> in them. At this point,
you could instruct the debugger to load the dll symbols and set breakpoint.
<p><tt>gdb> sha libnecko.so</tt>
<br><tt>gdb> b nsFunctionInNecko</tt></ul>
</blockquote>
<b><i>Mac: Codewarrior</i></b>
<blockquote>Just open the appropriate .xSYM file in the debugger; the debugger
will target the library when the application is run. - &lt;<a href="mailto:sfraser@netscape.com">Simon
Fraser</a>></blockquote>
</blockquote>
</blockquote>
<a NAME="Generating a log from xpcom:"></a><b>Generating a log from xpcom:</b>
<blockquote>XPCOM provides log output. To enable the logging:
<blockquote><tt>[unix]</tt>
<br><tt>setenv NSPR_LOG_MODULES nsComponentManager:5</tt>
<br><tt>setenv NSPR_LOG_FILE xpcom.log</tt>
<p><tt>[win]</tt>
<br><tt>set NSPR_LOG_MODULES=nsComponentManager:5</tt>
<br><tt>set NSPR_LOG_FILE=xpcom.log</tt></blockquote>
Start your application after setting the above environment variables. Debug
log from xpcom would be in the file <tt>xpcom.log</tt></blockquote>
<p><br><a NAME="XPCOM Log analysis"></a><b>XPCOM Log analysis</b>
<blockquote><a href="http://lxr.mozilla.org/seamonkey/source/xpcom/doc/xpcom-log-analyze.sh">xpcom/doc/xpcom-log-analyze.sh</a>
is a script that does analysis of the xpcom log and prints out useful statistics
in html format. Usage is:
<blockquote><tt>xpcom-log-analyze.sh &lt; xpcom.log > xpcom-log.html</tt>
<br><tt></tt>&nbsp;</blockquote>
</blockquote>
<hr WIDTH="100%">
</body>
</html>

View File

@ -1,143 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
</head>
<body>
<center>
<h2>
Component Loaders</h2></center>
<center>Brendan Eich &lt;<a href="mailto:brendan@mozilla.org">brendan@mozilla.org</a>>
<br>John Bandauer &lt;<a href="mailto:jband@netscape.com">jband@netscape.com</a>>
<br>Mike McCabe &lt;<a href="mailto:mccabe@netscape.com">mccabe@netscape.com</a>>
<br>Mike Shaver &lt;<a href="mailto:shaver@mozilla.org">shaver@mozilla.org</a>>
<br>Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>></center>
<h3>
Scope of document</h3>
<ul>
<li>
Component Developers</li>
<li>
Clients of XPCOM (for information only)</li>
</ul>
<h3>
Why Component Loaders</h3>
Currently XPCOM requires all component to be packaged in DLLs and uses
the dynamic loading mechanism available with each platform to accomplish
instantiation of component. This method doesn't blend well with say components
written in java or javascript and packaged different from a DLL. Hence
the proposal for Component Loaders.
<br>&nbsp;
<h3>
Component Loaders</h3>
XPCOM in its simplest form can be viewed as creating instances of objects
given a CONTRACTID or ClassID. How it does this instantiation is specific to
XPCOM and opaque to clients of XPCOM.
<p>Internally XPCOM maps the passed in CONTRACTID to a CID and then the CID
maps into a DLL name. XPCOM loads the DLL assuming the dynamic loading
mechanism to create a factory. Then, asks the factory to create a particular
instance. Here are roughly the steps involved:
<ol>
<li>
CreateInstance(..., CONTRACTID,...)</li>
<li>
Map CONTRACTID to CID</li>
<li>
Map CID to DLL</li>
<li>
factory = Dynamically Load DLL to create Factory</li>
<li>
Use Factory to create object instance</li>
</ol>
The proposal for Component Loaders is to get XPCOM to delegate the loading
to a component loader:
<ul>
<li>
CreateInstance(..., CONTRACTID,...)</li>
<li>
Map CONTRACTID to CID</li>
<li>
<font color="#990000">Map CID to ComponentType</font></li>
<li>
<font color="#990000">If ComponentType is DLL</font></li>
<ul>
<li>
factory = Dynamically Load DLL to create Factory</li>
</ul>
<li>
<font color="#990000">else</font></li>
<ul>
<li>
<font color="#990000">ComponentLoaderServiceCONTRACTID = "<i>@mozilla.org/xpcom/component-loader;1?type=</i>"
+ ComponentType <sup><a href="#* ContractID syntax might change">*</a></sup></font></li>
<li>
<font color="#990000">loaderInstance = GetService(..., ComponentLoaderServiceCONTRACTID,...)</font></li>
<li>
<font color="#990000">factory = loaderInstance->CreateFactory(..., componentLocation,...)</font></li>
</ul>
<li>
Use Factory to create object instance</li>
<h4>
Format of ComponentType</h4>
ComponentType is assumed to be mimetype.
<h4>
Component Registration</h4>
Registration of components in DLLs wont change. ComponentType of DLL is
assumed here. To facilitate registration of components with specifc component
types, the component manager will provide the following API:
<p><tt><font color="#990000">RegisterComponentWithType(const nsCID &amp;aClass,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
const char *aClassName,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
const char *aContractID,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
const char *aComponentType,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
const char *aComponentLocation,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
PRBool aReplace,</font></tt>
<br><tt><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
PRBool aPersist);</font></tt>
<br>&nbsp;
<br>&nbsp;
<h4>
Component Loader Service Registration</h4>
Since the loader is just another component with a special contractid, there
is no special registration of the component loader.&nbsp; Component Loaders
use either the RegisterComponent() api if they are a DLL (most common)
or use RegisterComponentWithType() api if they are themselves of a particular
type (very rare).</ul>
<h3>
Autoregistration of non DLL Components and Component Loaders</h3>
&lt;Need to figure this out>
<br>&nbsp;
<p><a NAME="* ContractID syntax might change"></a><sup><a href="#* ContractID syntax might change">*</a></sup>
ContractID&nbsp;syntax might change
<br>
<hr WIDTH="100%">
<br><i><font size=-1>Last Modified: 1 Aug 1999&nbsp; Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>></font></i>
<br>&nbsp;
</body>
</html>

View File

@ -1,544 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Suresh Duddi">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
<title>XPCOM Dynamic Component Registration</title>
</head>
<body>
<center>
<h2>
XPCOM Dynamic Component Registration</h2></center>
<center>Suresh Duddi &lt;<a href="mailto:dp@netscape.com">dp@netscape.com</a>>
<hr WIDTH="100%"></center>
<p>Dynamic object registration in XPCOM is achieved by interaction of the
following components:
<ul>
<li>
The Component Registry</li>
<li>
The Repository</li>
<li>
The Service Manager</li>
<li>
Component dll implementing <tt>NSRegisterSelf()</tt></li>
</ul>
The registration mechanism for XPCOM components is similar in many ways
to that of COM. The XPCOM component dlls will have the opportunity to register
themselves with the registry. The exact time of installation would be either
at install time or as a result of <b>autodetection</b> by the Repository
Manager at runtime.
<br>
<hr WIDTH="100%">
<h3>
<a NAME="The Registry: XPCOM Hierarchy"></a>The Component Registry</h3>
There are three types of Component Registries:
<ol>
<li>
<b>App-Component-Registry<br>
</b>Each application has its own Component Registry that lives along with
the app in its &lt;exe-dir>/components directory. The Component Registry
is created on installation or first run. It is be used read-only by XPCOM</li>
<li>
<b>User-Component-Registry</b></li>
<br>Each user can install additional components under their user home directory.
These components will be shared across all XPCOM applications that the
user runs.
<li>
<b>Meta-Component-Registry</b></li>
<br>Sharing Components between application: This can happen in two ways.
The installer of an application can find the other application's components
by looking for the application specifically and registering them with this
app's component registry. The second and more preferable approach is to
keep a machine wide Meta-Components-Registry that would aggregate all the
app component registries.</ol>
The difference component registries will be searched in the following order:
<ol>
<li>
User Components Registry</li>
<li>
App Component Registry</li>
<li>
Meta Component Registry</li>
</ol>
The user component registry is the only one that will be updated on the
fly by XPCOM. JS will be given the option to update either the App-Component-Registry
or the User-Component-Registry and this may succeed fail based on write
permission, although the general guideline is to update the User-Component-Registry.
JS will have to do special things to update the App-Component-Registry.
<p>Profiles are a notion of the app (navigator) and xpcom has nothing to
do with it. The app will store app specific data in a Data-Registry that
will be stored under the user's home directory.
<h4>
How does this Solve our problems</h4>
<ol>
<li>
Multiple installations of mozilla and xpcom based apps</li>
<br>Since each installation is going run with their own App-Component-Registry,
basically both apps will work. No inter process locking is essential. Since
both processes will operate on the User-Component-Registry, inter process
locking of the User-Component-Registry will be required.
<li>
Third Party components installation</li>
<br>Third parties can install components in their own directories and update
the App-Component-Registry (preferable) or User-Component-Registry depending
on if the sharing of component needs to be specific to the user or for
all users. Facilities for updating the registry would be to use JS or write
XPCOM code in their installer. The other option would be to add their components
in their own directory, create a App-Component-Registry of their own in
their directory and reference it in the Global Meta-Components-Registry.
This will get their components used by all applications.
<li>
Registry used to store app specific data</li>
<br>This is a totally separate registry: the Data-Registry. The theory
is that this will reside in the user's home directory. The registry hierarchy
is app specific.
<li>
User Specific components</li>
<br>This is basically the User-Component-Registry. Inter process locking
is required as all processes with XPCOM will access the same User-Component-Registry.
<li>
Embedding</li>
<br>This is requires more thought. The fact is when say Gecko is embedded
into an application, Gecko is running most probably in the process space
of that application and hence the XPCOM used will look for components in
this embedding applications directory. The embedding procedure should create
a App-Component-Reqistry for the embedding application that should contain
all the components from different apps this app would like to use. This
is however not required, if the Meta-Component-Registry exists.
<li>
User not having permission to the place where the global registry lives,
if there is one.</li>
<br>First the App-Component-Registry is written to only when there is a
new component or a component has gone away. New components come with installers
or the user calls regFactory.exe with the dll as an argument or clicks
on a button that says "refresh my user components" which will cause autoregistration
of user components. For deleted app components, annotations will be made
in the User-Component-Registry. Deleted user components is a non-issue.
<li>
NFS mounted home directories and app directories</li>
<br>NFS mounted home directories requires inter-machine locking of the
User-Component-Registry.&nbsp; NFS mounted app directories dont have a
problem as the App-Component-Registry is&nbsp; only used read-only by XPCOM.</ol>
So in summary,
<ul>
<li>
App-Component-Registry pretty much solves the top problem of Multiple applications.
With some help from the installer, Third party components will also be
solved.</li>
<li>
User-Component-Registry solves the User Specific Components problem.</li>
<li>
Meta-Component-Registry enables the dynamic sharing of components between
apps which eases embedding.</li>
</ul>
As a first cut, I am going to implement the App-Component-Registry for
M8.
<h4>
Hierarchy Used by Component Registry</h4>
XPCOM uses the nsRegistry to store mappings between CLSIDs and their implementations.
The Registry provides persistent storage of hierarchical keys and name-value
pairs associated with each key. Each key also keeps a default value.
<p>XPCOM will use the following registry hierarchy:
<blockquote><tt>ROOTKEY_COMMON</tt>
<br><tt>&nbsp;&nbsp;&nbsp; Common</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Classes</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CLSID</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></b></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
InprocServer (S)&nbsp; = <font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></nobr></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ContractID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp; = <b><font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font></b></nobr></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ClassName&nbsp;&nbsp;&nbsp; (S)&nbsp; = <b><font color="#CC0000">NFS Protocol
Handler</font></b></nobr></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font></tt>
<br><tt><nobr>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
CLSID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp; = <font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></nobr></tt>
<p><tt><i>&nbsp;&nbsp;&nbsp; </i>Software</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Netscape</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
XPCOM</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
VersionString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (S)&nbsp;
= <font color="#CC0000">alpha0.20</font></tt>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<font color="#CC0000">/home/dp/dist/bin/components/libnfs-protocol.so</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ComponentsCount&nbsp;&nbsp;&nbsp; (Int)&nbsp; = <font color="#CC0000">1</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
FileSize&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Int)&nbsp;
= <font color="#CC0000">78965</font></tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
LastModTimeStamp&nbsp;&nbsp; (S)&nbsp;&nbsp;&nbsp; = <font color="#CC0000">Wed
Feb 24 11:24:06 PST 1999</font></tt>
<p><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#000000">Events</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Startup</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#CC0000">{108d75a0-bab5-11d2-96c4-0060b0fb9956}</font></tt>
<br><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{17894983-ab78-8d75-a0bb-511d296c4006}</font></tt>
<p><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Shutdown</font></tt>
<br><tt><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</font><font color="#CC0000">{748958ea-abab-511d-296c-40060b0fb995}</font></tt>
<br><tt><font color="#CC0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{45617894-983a-b788-d75a-0bab11d296c4}</font></tt>
<br>&nbsp;</blockquote>
<h3>
<hr WIDTH="100%"><a NAME="The Repository: Object instance creation"></a>The
Repository: Object instance creation</h3>
All object creation happens via The Repository.&nbsp; <tt>nsIRepository::CreateInstance()</tt>
will be the primary way of creation of object instances. The steps in instantiation
of an object that implements the IID interface and of class CLSID is as
follows:
<ol>
<li>
The CLSID of the component that would need to create the object instance
is identified.</li>
<ol>Callers use <tt>nsIRepository::ContractIDToCLSID()</tt> to convert the
ContractID string to the CLSID.</ol>
<li>
Load the dll associated with the CLSID after consulting the Registry</li>
<li>
Instantiate the class factory by calling a globally exported dll function
<tt>NSGetFactory()</tt>.
This returns an instance of the class factory that implements the <tt>nsIFactory</tt>
interface.</li>
<li>
The actual object creation is delegated to this <tt>nsIFactory</tt> instance
with a call to <tt>nsIFactory::CreateInstance()</tt>.</li>
</ol>
<h3>
<hr WIDTH="100%"><a NAME="The Service Manager"></a>The Service Manager</h3>
All globally created system services are available via the <tt>nsIServiceManager</tt>,
including the <tt>nsIRepository</tt> and <tt>nsIRegistry</tt>. Although
the <tt>nsIServiceManager</tt> uses the Registry and Repository in the
creation and maintenance of other services, the circular dependency is
broken by not letting the <tt>nsIServiceManager</tt> create the <tt>nsIRepository</tt>
and <tt>nsIRegistry</tt> instance and registering them specially with the
<tt>nsIServiceManager</tt>.
The nsIServiceManager is passed into NSGetFactory() for assisting the DLL
in the Factory creation process.
<h3>
<hr WIDTH="100%"><a NAME="Component Registration"></a>Component Registration</h3>
Either at installation time of the Component or at times when the XPCOM
library autodetect new/changed dlls, component registration is activated.
The autodetection happens at startup time of the navigator or via a javascript
trigger <tt>navigator.repository.autodetect()</tt>. The steps in component
registration would be:
<ol>
<li>
The dll is loaded</li>
<li>
The component is allowed to self register by a call to a globally exported
dll function <tt>NSRegisterSelf()</tt>. The <tt>nsIServiceManager</tt>
and the fullpath of the dll are passed in to assist in the registration
process. The dll is expected to create/modify its entries in the Registry
according to the guidelines of the <a href="#The Registry: XPCOM Hierarchy">XPCOM
hierarchy</a> in the registry. <tt>nsIRepository</tt>, which can be queried
from the <tt>nsIServiceManager</tt>, has useful registration functions
that would easen the process.</li>
<li>
The dll is unloaded</li>
</ol>
<h3>
<hr WIDTH="100%"><a NAME="Autodetection of Components"></a>Autodetection
of Components</h3>
Autodetection of changed dlls happened by storing the dll's last modified
time and its size in the Registry automatically. If either the last modified
time stamp or the filesize differs from that stored in the Registry for
the dll, re-registration takes place. Before re-registration, the existing
instances of the objects created by the classes in the dll are not freed
because the <tt>nsIRepository</tt> has no list of them. The <tt>NSCanUnload()</tt>
will be called with input parameter <i>force</i> set to <tt>true</tt>.
The dll has to prepare for getting unloaded. After this call returns, the
dll <b>will</b> be unloaded if the return value is <tt>true</tt>. If the
dll detects that it cannot properly prepare for unloading, then it can
return <tt>false</tt>. XPCOM will not let the re-registration of the modified
dll proceed in this case. There is nothing much that XPCOM library can
do to salvage this situation other than warning the user of possible instability
and advice a restart upon which the re-registration will happen.
<h3>
<hr WIDTH="100%"><a NAME="ContractID Spec"></a>ContractID Spec</h3>
The general format of ContractIDs is <i><b><font color="#990000">@</font></b>mozilla.org<b><font color="#990000">/</font></b>compname<b><font color="#990000">&amp;</font>version</b><b><font color="#990000">?</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">&amp;</font></b>var<b><font color="#990000">=</font></b>value<b><font color="#990000">&amp;</font></b>var<b><font color="#990000">=</font></b>value...</i>
<p>Let us consider some more examples:
<ol>
<li>
A pluggable protocol that implementes the nfs protocol</li>
<li>
A converter that can handle application/x-zip</li>
<li>
A plugin that can handle image/gif</li>
<li>
A widget that can do a toolbar</li>
<li>
A datasource that can handle mail</li>
<li>
A helperapp that deals with application/postscript</li>
</ol>
All the above have what type they are and one or more arguments on what
they particularly do.
<p>The ContractID for these would look like
<ol>
<li>
<tt>@mozilla.org/network-protocol;1?type=nfs</tt></li>
<li>
<tt>@mozilla.org/data-converter;1?type=application/x-zip</tt></li>
<li>
<tt>@mozilla.org/plugin;1?description=Renders GIF Images....&amp;name=ImageMedia Gif Image Plugin&amp;type=image/gif</tt></li>
<li>
<tt>@mozilla.org/widget;1?type=toolbar</tt></li>
<li>
<tt>@mozilla.org/rdf/datsource;1?type=mail</tt></li>
<li>
<tt>@mozilla.org/helperapp;1?type=application/postscript</tt></li>
</ol>
{Assume proper escaping of all above URI}
<p>The above semantics would let ContractID be an extensible mechanism that
could be searched on multiple ways. And
<br>query on a contractid should match only whatever was passed in. So a query
for
<br>@mozilla.org/plugin;1?type=image/gif should pass for the contractid
specified above. We could extend this
<br>mechanism with wildcards, but I dont want to go there yet... :-)
<br>&nbsp;
<h3>
<hr WIDTH="100%"><a NAME="Startup Components"></a>Components created on
events</h3>
<b><font color="#990000">NOTE: THIS IS NOT BEING DONE. We are going to
expect the apps to this themselves by using the registry.</font></b>
<p>Some dlls have components that want to be created on certain events
namely Startup, Shutdown (for now). Example is xpinstall.
<blockquote>RegisterComponentForEvent(..., RegisterationTime when, ...)
<br>RegisterFactoryForEvent(..., RegistrationTime when,...)</blockquote>
exists for this purpose. When an application wants to Fire the particular
event, it calls
<blockquote>nsComponentManager::FireEvent(RegistrationTime when)</blockquote>
ComponentManager will look for components that are registered to be created
on these events and do the following for each of the components:
<ol>
<li>
CreateInstance(...,CID, knsIStartupComponentIID, &amp;obj);</li>
<br>For a shutdown event, knsIShutdownComponentIID would be used.
<br>&nbsp;
<li>
obj->Release();</li>
<br>The component needs to take adequate measures to keep itself alive
and figure out how it would delete the object, since a Release() happens
immediately after a CreateInstace()</ol>
<b><i>Warning: </i></b>Order of creation of multiple components registered
on the same event is not defined. Component dependencies aren't thought
of yet.
<br>&nbsp;
<h3>
<hr WIDTH="100%"><a NAME="How will all this help me"></a>How will all this
help me</h3>
For Component Developers:
<ul>
<li>
Component dlls developed could be dropped into a directory, a JS function
called after which your component is in business without even a restart
of the browser. Of course, there needs to be someone accessing it.</li>
<li>
No need to export you CLSID or run around finding where to advertise your
CLSID</li>
</ul>
For Component Users:
<blockquote>
<li>
No more hacking in calls to <tt>nsIRepository::RegisterFactory()</tt></li>
<li>
No need to know the CLSID of components that you want to instantiate. Component
creation can happen like this</li>
<br><tt>nsIRepository::CreateInstance(<b>"<font color="#CC0000">@mozilla.org/network-protocol;1?type=nfs</font>"</b>,
NULL, kProtocolIID, &amp;result);</tt>
<br>instead of
<br><strike>nsIRepository::CreateInstance(NFS_PROTOCOL_CID, NULL, domIID,
&amp;result);</strike></blockquote>
<h3>
<hr WIDTH="100%"><a NAME="What has happened so far"></a>What has happened
so far</h3>
<ul>
<li>
Autoregistration implemented to grovel for components from the current
directory</li>
<li>
nsRepository is a global object. Not nsIRepository exists.</li>
<li>
nsRepository::ContractIDToCLSID() implemented</li>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="Changes to XPCOM happening"></a>Changes to XPCOM
happening</h3>
<ul>
<li>
API changes to get ContractID in entire registration process for factories
and components</li>
<li>
ContractID cache to improve performance of ContractID queries</li>
<li>
Notion of Component dlls living in a <b>Components directory </b>and autoregistration
will load/manage only these components. Other components that are linked
in to the app need to call <tt>nsRepository::RegisterFactory()</tt> from
the app. <b>To make this happen we need a list of these.</b></li>
<li>
<b>nsRegistry:</b> Enabling the new nsRegistry developed by Bill Law &lt;law@netscape.com></li>
<li>
Service Manager and Repository: Merge them</li>
<li>
Convenience function to createIntance(contractid)</li>
<li>
Base ContractID in the interface ID header file</li>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="What should I do"></a>What should I do</h3>
<ul><b><font color="#CC0000">Component Developers</font></b>
<ul>
<li>
<font color="#000000">Implement <tt>NSRegisterSelf()</tt> for your component
dlls. Sample implementation that perf</font>
<a href="http://lxr.mozilla.org/mozilla/source/modules/libpref/src/nsPref.cpp#608">http://lxr.mozilla.org/mozilla/source/modules/libpref/src/nsPref.cpp#608</a></li>
<li>
Use <tt>nsRepository::RegisterComponent()</tt> instead of <tt>nsRepository::RegisterFactory()</tt>
if your component lives in a DLL</li>
<li>
<b>Dont use static constructors in loadable components</b></li>
</ul>
<p><br><b><font color="#CC0000">Component Users</font></b>
<ul>
<li>
Create all your components using ContractID rather than CID</li>
<li>
If you were thinking of managing creation of components yourself, think
again. The repository may be already doing that.</li>
</ul>
</ul>
<h3>
<hr WIDTH="100%"><a NAME="Issues"></a>Issues</h3>
<ul>
<li>
Need support for questions like:</li>
<ol>
<li>
Enumerate all CLSIDs that implement a particular interface.</li>
<li>
Let a particular CLSID be the preferable implementation for an interface.</li>
<br>I dont know how this a XPCOM component user could use it unless there
could be a call like:
<br><tt>nsIRepository::CreateInstance(<b>NULL</b>, NULL, nsWidgetIID, &amp;result);</tt>
<li>
Enumerate all interfaces supported by a CLSID</li>
</ol>
<li>
Resolving naming conflicts between ContractID</li>
<li>
Store component specific name-values under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt></li>
<li>
Add a registry entry under <tt>ROOTKEY_COMMON\\<i>component.class.version\\</i></tt>to
indicate the willingness for a CLSID to behave as a Service.</li>
<li>
Add quick registration support functions in <tt>nsIRepository</tt> for
components to use.</li>
<li>
Is the hierarchy <tt>ROOTKEY_COMMON\\<b>Classes</b>\\CLSID </tt>acceptable.</li>
<li>
Should we have a nsIRepository. JS needs it so that they can reflect it
in javascript. Remove &amp;'s in the API.</li>
</ul>
<hr WIDTH="100%">
<br><i><font size=-1>Last Modified: 28 Jan 1998</font></i>
<br><font size=-1><i>Feedback to: </i><a href="news:netscape.public.mozilla.xpcom">netscape.public.mozilla.xpcom</a></font>
</body>
</html>

View File

@ -1,208 +0,0 @@
#!/usr/bin/perl
# Perl script to analyze the log output from xpcom and print
# the results in html.
#
# To get the xpcom log output to a file say xpcom.log:
# setenv NSPR_LOG_MODULES nsComponentManager:5
# setenv NSPR_LOG_FILE xpcom.log
# ./mozilla
# <quit>
#
# To get registry (used to figure out contractid mappings)
# ./regExport component.reg > registry.txt
# Usage:
#
# a) To get simple output
# cat xpcom.log | perl xpcom-log-analyze.pl > xpcom-log.html
#
# b) To get all possible cid->contractid mappings filled in
# cat xpcom.log registry.txt | perl xpcom-log-analyze.pl > xpcom-log.html
#
#
# Author: Suresh Duddi <dp@netscape.com>
# Created Aug 9 2000
while (<>)
{
chomp;
if ( /ContractIDToClassID.*\}/ )
{
# Passed contractid to cid mapping. Add contractid to cid mapping
$cid = GetCID();
$contractid = GetContractID();
$contractid_map{$cid} = $contractid;
$contractid_passed{$contractid}++;
$ncontractid_passed++;
next;
}
if ( /ContractIDToClassID.*FAILED/ )
{
# Failed contractid. Collect it.
$contractid = GetContractID();
$contractid_failed{$contractid}++;
$ncontractid_failed++;
next;
}
if ( /CreateInstance.*succeeded/ )
{
# Successful create instance
$objects{GetCID()}++;
$nobjects++;
next;
}
if ( /CreateInstance.*FAILED/ )
{
# Failed create instance
$objects_failed{GetCID()}++;
$nobjects_failed++;
next;
}
if ( /: loading/ )
{
$dll = GetDll();
# make the name a little pretty
$dll =~ s/^.*bin\///;
$dll_loaded[@dll_loaded] = $dll;
next;
}
if ( / classID - \{/ )
{
# this is from the output of registry. Try to update contractid_map
$cid = GetCID();
# Get the next contractid or classname line until a empty new line
$_ = <STDIN> until (/ContractID|ClassName/ || length == 1);
chomp;
$contractid = $_;
$contractid =~ s/^.*= //;
$contractid_map{$cid} = $contractid;
}
}
PrintHTMLResults();
sub GetContractID() {
# Get a proid from a line
my($contractid) = $_;
$contractid =~ s/^.*\((.*)\).*$/$1/;
# print "Got Progid: $contractid\n";
return $contractid;
}
sub GetCID() {
# Get a CID from a line
my($cid) = $_;
$cid =~ s/^.*\{(.*)\}.*$/$1/;
# print "Got cid: $cid\n";
return $cid;
}
sub GetDll() {
# Get a Dll from a line
my($dll) = $_;
$dll =~ s/^.*\"(.*)\".*$/$1/;
# print "Got dll: $dll\n";
return $dll;
}
#
# Print the results of our log analysis in html
#
sub PrintHTMLResults()
{
$now_time = localtime();
print "<HTML><HEAD><title>XPCOM Log analysis dated: $now_time\n";
print "</TITLE></HEAD>\n";
print "<H1><center>\n";
print "XPCOM Log analysis dated: $now_time\n";
print "</center></H1>\n";
# ========================================================================
# Performance analysis
# ========================================================================
print "<H2>Performance Analysis</H2>\n";
# Number of dlls loaded
$n = @dll_loaded;
print "<H3>Dlls Loaded : $n</H3>\n";
print "<blockquote><pre>\n";
PrintArray(@dll_loaded);
print "</blockquote></pre>\n";
# Objects created with a histogram
print "<H3>Objects created : $nobjects</H3>\n";
print "<blockquote><pre>\n";
@sorted_key = SortKeyByValue(%objects);
foreach $cid (@sorted_key)
{
printf("%5d %s [%s]\n", $objects{$cid}, $cid, $contractid_map{$cid});
}
print "</blockquote></pre>\n";
# Passed contractid calls
print "<H3>Succeeded ContractIDToClassID() : $ncontractid_passed</H3>\n";
print "<blockquote><pre>\n";
@sorted_key = SortKeyByValue(%contractid_passed);
foreach $contractid (@sorted_key)
{
printf("%5d %s\n", $contractid_passed{$contractid}, $contractid);
}
print "</blockquote></pre>\n";
# ========================================================================
# Error analysis
# ========================================================================
print "<H2>Error Analysis</H2>\n";
# CreateInstance() FAILED
print "<H3>Failed CreateInstance() : $nobjects_failed</H3>\n";
print "<blockquote><pre>\n";
@sorted_key = SortKeyByValue(%objects_failed);
foreach $cid (@sorted_key)
{
printf("%5d %s [%s]\n", $objects_failed{$cid}, $cid, $contractid_map{$cid});
}
print "</blockquote></pre>\n";
# ContractIDToClassID() FAILED with a histogram
print "<H3>Failed ContractIDToClassID() : $ncontractid_failed</H3>\n";
print "<blockquote><pre>\n";
@sorted_key = SortKeyByValue(%contractid_failed);
foreach $contractid (@sorted_key)
{
printf("%5d %s\n", $contractid_failed{$contractid}, $contractid);
}
print "</blockquote></pre>\n";
# end the html listing
print "</HTML>\n";
}
sub PrintArray()
{
my(@array) = @_;
for ($i=0; $i<@array; $i++)
{
print "$array[$i]\n";
}
}
#
# Sort a given hash by reverse numeric order of value
# return the sorted keylist
#
sub SortKeyByValue()
{
my(%hash) = @_;
my(@sorted_keys) = sort { $hash{$b} <=> $hash{$a} } keys %hash;
return @sorted_keys;
}

View File

@ -1,105 +0,0 @@
#!/bin/sh
#
# Shell script to analyze the xpcom log file
#
# Usage: xpcom-log-analize.sh [<logfile>] > xpcom-log.html
#
# You can generate the xpcom log file using:
# setenv NSPR_LOG_MODULES nsComponentManager:5
# setenv NSPR_LOG_FILE xpcom.log
# ./mozilla
# <quit>
#
# Contributors:
# Suresh Duddi <dp@netscape.com>
# Vamsee Nalagandla <vamsee9@hotmail.com>
#
if [ $# -gt 0 ]
then
logfile=$1
else
logfile=xpcom.log
fi
# make sure we got the logfile
if [ ! -f $logfile ]
then
echo "Error: Cannot find xpcom logfile $logfile"
exit -1
fi
echo "<HTML>"
echo "<HEAD>"
echo "<TITLE>XPCOM Log analysis dated:"
date
echo "</TITLE></HEAD>"
echo "<H1><center>"
echo "XPCOM Log analysis dated:"
date
echo "</center></H1>"
# ========================================================================
# Performance analysis
# ========================================================================
echo "<H2>Performance Analysis</H2>"
# Number of dlls loaded
n=`grep -i ': loading' ${logfile} | wc -l`
echo "<H3>Dlls Loaded : $n</H3>"
echo "<blockquote><pre>"
grep ': loading' $logfile
echo "</pre></blockquote>"
# Objects created with a histogram
n=`grep -i 'createinstance.*succeeded' ${logfile} | wc -l`
echo "<H3>Objects created : $n</H3>"
echo "<blockquote><pre>"
grep -i 'createinstance.*succeeded' ${logfile} | sort | uniq -c | sort -nr
echo "</pre></blockquote>"
# Number of RegisterFactory
n=`grep 'RegisterFactory' $logfile | wc -l`
echo "<H3>Factory registrations : $n</H3>"
echo "<blockquote><pre>"
grep 'RegisterFactory' $logfile
echo "</pre></blockquote>"
# Number of RegisterComponentCommon.
# XXX Order them by dllname
n=`grep 'RegisterComponentCommon({' $logfile | wc -l`
echo "<H3>Component Registrations : $n</H3>"
echo "<blockquote><pre>"
grep 'RegisterComponentCommon({' $logfile
echo "</pre></blockquote>"
# Number of succeeded calls to ContractIDToClassID() with histogram
n=`grep -i 'contractidtoclassid.*}' $logfile | wc -l`
echo "<H3>Count of succeeded ContractIDToClassID() : $n</H3>"
echo "<blockquote><pre>"
grep -i 'contractidtoclassid.*}' $logfile | sort | uniq -c | sort -nr
echo "</pre></blockquote>"
# ========================================================================
# Error analysis
# ========================================================================
echo "<H2>Error Analysis</H2>"
# CreateInstance() FAILED
n=`grep 'CreateInstance.*FAILED' $logfile | wc -l`
echo "<H3>Failed CreateInstance() : $n</H3>"
echo "<blockquote><pre>"
grep 'CreateInstance.*FAILED' $logfile
echo "</pre></blockquote>"
# ContractIDToClassID() FAILED with a histogram
n=`grep 'ContractIDToClassID.*FAILED' $logfile | wc -l`
echo "<H3>Failed ContractIDToClassID() : $n</H3>"
echo "<blockquote><pre>"
grep 'ContractIDToClassID.*FAILED' $logfile | sort | uniq -c | sort -nr
echo "</pre></blockquote>"
#
# Cleanup
echo "</HTML>"

View File

@ -1,142 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Suresh Duddi">
<meta name="GENERATOR" content="Mozilla/4.71 [en] (X11; U; Linux 2.2.12-20 i686) [Netscape]">
</head>
<body>
<center>
<h2>
Standalone XPCOM v 0.5</h2></center>
<center>Version 0.5
<br>15 May 2000
<br>Suresh Duddi &lt;dp@netscape.com>
<hr WIDTH="100%"></center>
<h3>
1.0&nbsp; Overview</h3>
Standalone XPCOM is a tree configuration, that when built, provides a minimal
set of libraries (shared mostly) that can be used to get all features of
XPCOM. The contents of this standalone XPCOM in general are:
<ul>
<li>
NSPR : mozilla/nsprpub</li>
<li>
Registry : mozilla/modules/libreg</li>
<li>
XPCOM : mozilla/xpcom</li>
</ul>
<b>NOTE 1: xpcom apis are not frozen yet. By XPCOM 1.0 release they will
be.</b>
<br><b>NOTE 2: xpcom standalone differs from the xpcom built with mozilla.
Hence cannot be used with the mozilla browser.</b>
<h3>
2.0&nbsp; Building Standalone XPCOM</h3>
Here are the instructions for building the Standalone XPCOM on Unix or Windows:
<br>&nbsp;
<ol><b>Step 1 : Pull the sources</b>
<li>
<tt>cvs -z 3 co mozilla/client.mk</tt></li>
<li>
<tt>cd mozilla</tt></li>
<li>
<tt>gmake -f client.mk pull_all BUILD_MODULES=xpcom</tt></li>
</ol>
<ol><b>Step 2 : Build XPCOM Standalone</b>
<li>
<tt>configure --enable-standalone-modules=xpcom</tt></li>
<li>
<tt>gmake</tt></li>
</ol>
<h3>
3.0&nbsp; Testing Standalone XPCOM</h3>
<tt>xpcom/sample</tt> contains a sample application and a component. This
should get built by default.
<ul>
<li>
<tt>nsTestSample</tt> is the sample application. This should have been
installed in your <tt>bin/</tt> directory.</li>
<li>
<tt>libsample.so (unix) </tt>is the sample component implementation that
the sample application will try to instantiate. This should have been installed
in your <tt>bin/components</tt> directory</li>
</ul>
To run the test,
<ol>
<li>
cd to your <tt>bin/</tt> directory</li>
<li>
setenv LD_LIBRARY_PATH .</li>
<li>
<tt>./nsTestSample</tt></li>
<br><tt>Warning: MOZILLA_FIVE_HOME not set.</tt>
<br><tt>nsNativeComponentLoader: autoregistering begins.</tt>
<br><tt>nsNativeComponentLoader: autoregistering succeeded</tt>
<br><tt>Inital print: initial value</tt>
<br><tt>Set value to: XPCOM defies gravity</tt>
<br><tt>Final print : XPCOM defies gravity</tt>
<br><b><tt>Test passed.</tt></b></ol>
<h3>
4.0&nbsp; Test FAILED: What went wrong ?</h3>
The most common case of why the sample would have failed if you didn't
run it from the bin directory. Here are some error messsages and possible
ways of fixing them.
<ol>
<li>
<b><tt>./nsTestSample: error in loading shared libraries: libxpcom.so:
cannot open shared object file: No such file or directory</tt></b></li>
<ol>LD_LIBRARY_PATH not set. To fix "<tt>setenv LD_LIBRARY_PATH ."</tt></ol>
<li>
<b>Link errors when building xpcom standalone</b></li>
<ol>This is mostly due to the fact that probably xpcom is not being built
standalone. Make sure you did "<tt>configure --enable-standalone-modules=xpcom"</tt></ol>
</ol>
<h3>
5.0&nbsp; Whats the difference between Standalone and non-Standalone XPCOM</h3>
There is no binary difference between standalone XPCOM and the XPCOM that ships with the Mozilla browser. The one functional difference is that XPT files cannot be read from .zip files in standalone XPCOM.
<h3>
6.0&nbsp; TODO for v 1.0</h3>
<ol>
<li>
Optional exclusion of specific features into standalone XPCOM like
registry, xpconnect. Tweeking these options will cause reduction
in memory requirements and size.</li>
<li>
Get <tt>xpcom/tests</tt> directory upto date and documented.</li>
<li>
Update this document for Mac.</li>
<li>
API freeze and documentation</li>
</ol>
<h3>
7.0&nbsp; Future (post v 1.0)</h3>
mmh! let me think...
<p>
<hr WIDTH="100%">
<br>Suresh Duddi &lt;dp@netscape.com>
</body>
</html>

View File

@ -1,161 +0,0 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="pnunn">
<meta name="GENERATOR" content="Mozilla/4.5 [en]C-NSCP (WinNT; U) [Netscape]">
<title>xpCom FAQ</title>
</head>
<body>
<b><font size=+3>XPCOM FAQ</font></b>
<p>Get out your decoder rings kids!
<p>Having a basic understanding of COM is only the first
<br>step. To get CMonkey code to build and run,
<br>you&nbsp; need to translate your COM ideas into Netscape
<br>speak.
<p>Feel free to add to this document or change incorrect info.
<br>Hopefully more info and more examples will help new
<br>people reach XPCOM nirvana more quickly.
<p><b>To mentally translate XPCOM to COM.</b>
<br>&nbsp;
<table BORDER COLS=2 WIDTH="100%" >
<tr>
<td BGCOLOR="#CCCCCC"><b>vanilla COM</b></td>
<td BGCOLOR="#FFCCCC"><b>XPCOM</b></td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">&nbsp;IUnknown</td>
<td BGCOLOR="#FFCCCC">nsISupports</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">IClassFactory</td>
<td BGCOLOR="#FFCCCC">nsIFactory</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">virtual void _stdcall</td>
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">interface ID = IID</td>
<td BGCOLOR="#FFCCCC">nsID = nsIID = IID</td>
</tr>
<tr>
<td BGCOLOR="#CCCCCC">class ID = CLSID&nbsp;</td>
<td BGCOLOR="#FFCCCC">nsCID = CID</td>
</tr>
</table>
<p>Not too difficult.
<br>But wait. There's more.
<br><b>-------------------------------------------</b>
<p><b><font size=+1>Why don't those classes have AddRef?</font></b>
<p>Actually, those classes do have AddRef. It is hidden
<br>in a macro. There are alot of&nbsp; macros that are alot of&nbsp; help
<br>once you know :
<br>&nbsp;&nbsp;&nbsp; 1) They exist.
<p>&nbsp;&nbsp;&nbsp; 2) Where they are defined. (They aren't always mnemonic
or onomatipeic.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
You might want to print them out.)
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mozilla/xpcom/public/nsCom.h
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mozilla/xpcom/public/nsISupports.h
<p>&nbsp;&nbsp;&nbsp; 3)What they are
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Here's a short list to give you an idea of what you've been missing.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
The include files listed above are the real reference.
<p>&nbsp;&nbsp;&nbsp; 4) A quick way to expand pesky macros:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
For macros in&nbsp; foo.cpp,&nbsp; 'make foo.i'
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This
will pump the foo.cpp file through C preprocessing
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
and expand all the macros for you.&nbsp; The output can be
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
hard to read, but if you search for&nbsp; unique strings
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
in the area you aredebugging, you can navigate
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
the file pretty easily.
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
(thanks to hshaw@netscape.com)
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<table BORDER COLS=2 WIDTH="100%" BGCOLOR="#CCCCCC" >
<tr>
<td BGCOLOR="#FFCCCC"><b><font size=+1>Netscape MACRO</font></b></td>
<td><b><font size=+1>Expansion of macro</font></b></td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NSADDREF(factoryinstname)</td>
<td>Factory->AddRef();</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_IMETHOD</td>
<td>virtual nsresult __stdcall</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_INIT_REFCNT()</td>
<td>mRefCnt = 0</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_INIT_ISUPPORTS()</td>
<td>NS_INIT_REFCNT()</td>
</tr>
<tr>
<td BGCOLOR="#FFCCCC">NS_DECL_ISUPPORTS</td>
<td>public:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD QueryInterface(REFNSIID
aIID,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void** aInstancePtr);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD_(nsrefcnt)
AddRef(void);
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NS_IMETHOD_(nsrefcnt)
Release(void);
<br>&nbsp;&nbsp;&nbsp; protected:
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nsrefcnt mRefCnt;</td>
</tr>
</table>
<p>&nbsp;<font size=+1>Useful Links to COM Documents:</font>
<p><a href="http://www.mozilla.org/projects/xpcom/">XPCOM&nbsp; Page</a>
<br><a href="http://www.mozilla.org/projects/xpcom/nsCOMPtr.html">nsCOMPtr</a>
<br><a href="http://warp.netscape.com/client/raptor/codingconventions.html">Coding
Conventions</a>
<br><a href="http://warp/client/bam/eng/howto.html">Getting BAMmed</a>
<br><a href="http://warp/client/bam/eng/comdoc.html">How to COM</a>
<br><a href="http://www.mozilla.org/docs/tplist/catFlow/modunote.htm">Modularization
Techniques</a>
<br><a href="http://www.mozilla.org/docs/tplist/catBuild/portable-cpp.html">C++
Portability Guide</a>
<br><a href="http://www.mozilla.org/newlayout/">NGLayout</a>
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>