Comments: Back to Basics: Defining XPCOM Services

Very good, MacLeod.

However, I don't see why XPCOMUtils.jsm can't be changed to just support this out of the box.

(From Alex: I did file a bug for that, and posted a patch... nothing.)

Posted by Blair McBride at October 2, 2008 7:08 PM

Actually, your C++ is incorrect...

First you must initialize mService somewhere or you will most likely crash.

Then, what if someone calls CreateInstance on your service and releases it (the case you're trying to avoid)? Your mService will point to freed memory and the next time any consumer calls GetService or CreateInstance you will most likely crash.

You must double-AddRef in your first GetSingleton call and then find some way of releasing the extra reference before shutdown to avoid leaking. This is usually done via the Observer service.

(From Alex: Thanks for the corrections - I'll rework the example code later today.)

Posted by bent at October 2, 2008 10:58 PM

Have/can you put this up on MDC? I was looking for it months ago and could never find the thing I needed, either in the source or in documentation.

Posted by DigDug at October 3, 2008 4:53 AM

Please at least mark the C++ source code as wrong, so that people don't copy it without reading the comments.

And I don't see why something that is satisfactory for the rest of the Mozilla codebase is not enough for you. You can put an assertion in the constructor that checks that the component is only instantiated once.

Everything's better than allow users to use createInstance if they feel like it - since this makes the client code _seem_ it creates a new instance when in fact it reuses the only one.

Posted by Nickolay Ponomarev at October 9, 2008 11:47 PM

Actually, there's a much easier way to do this in JavaScript with a constructor like this one:

var gFooInstance = null;
function FooServiceConstructor() {
  if (gFooInstance) // enforce singleton/service
    return gFooInstance;
  gFooInstance = this;
 
  // whatever you also want to do in your constructor
}

When a constructor function returns an object, the new operator will use that returned object instead of creating a new one. So when the component's constructor is first called you don't return anything, but on every subsequent you return the one instance initiated at first call. (I hope this is understandable.)

(From Alex: Oh, it's perfectly understandable... and functionally, not much different from what I did. :-) )

Posted by malte at October 12, 2008 1:51 PM

Nice post!

I looked at bugzilla, but didn't seem to find the bug and patch you filed.

seems it got lost.

cheers,
André

Posted by Andre at June 17, 2009 11:27 AM
Post a comment









Remember personal info?