Farewell PRLock; I hardly knew thee

The landing of bugs 58904 and 456272 have brought a new synchronization API to the Mozilla platform. I think I’m safe in saying that the old API (PRLock, nsAutoLock, and friends) is deprecated in favor of the new. But this is a good thing; you’ll prefer the new one, trust me.

The carrots

We’ve improved the API in the following ways

  • all classes are in the mozilla namespace
  • the “bare” primitives (Mutex, Monitor, CondVar) can now be allocated on the stack or as direct class members. Their constructors use a proto-non-failing malloc, so your code will never see out-of-memory errors.
  • the primitives and their RAII wrappers (MutexAutoLock/Unlock, MonitorAutoEnter) provide methods to assert that the primitive is “owned,” or not, by the currently executing thread. These should be used liberally in your code to enforce locking invariants (the assertions disappear in optimized builds).
  • the deadlock detector used by the new primitives in debug builds is asymptotically (and practically) more efficient than the old, should catch more deadlocks, and is now thread safe (!).

The sticks

As with any change to core APIs, this one will require a lot of rewriting. We’ll keep the old one around for a while, but new patches should use the new API. (Aside: Shawn Wilsher has been an early adopter, for the storage code. Check out what he’s been doing for some real-world examples.)

We’ve been extending our static analysis/refactoring tools to make upgrading old code easier. Hopefully, few people will need to worry about this. I’ll soon be blogging about our work; I think it’s a good example of how sweeping changes to existing code can be done quite easily, by one or two guys, in a matter of weeks.

The main change to the API that may cause some consternation is the removal of the nsAutoLock::lock/unlock and nsAutoMonitor::Enter/Exit methods from MutexAutoLock and MonitorAutoEnter. It has been decreed that they are bad news. Unfortunately, these are fairly difficult to rewrite automatically, so we may need to recruit a few module owners to help out.

Further reference

Most of the new API is documented on MDC. But please ping cjones on IRC if you have more questions or concerns.

[EDIT I see from PMO that I should be h4 and below.]

Comments (5)

  1. Christian Biesinger wrote::

    > Their constructors use a proto-non-failing malloc, so your code will never see out-of-memory errors.

    The patch looks like the way it doesn’t fail is by aborting:
    + mLock = PR_NewLock();
    + if (!mLock)
    + NS_RUNTIMEABORT(“Can’t allocate mozilla::Mutex”);

    seems like a horrible idea to me, but whatever…

    Tuesday, May 5, 2009 at 15:15 #
  2. cjones wrote::

    Hey, I said *proto*-non-failing, didn’t I? :) BTW, it’s not all that bad of an idea, especially for sync primitives.

    Tuesday, May 5, 2009 at 16:43 #
  3. Mook wrote::

    There is no plans to expand the API beyond what NSPR provides, correct? (In particular, a trylock would be awesome, but isn’t exposed by NSPR.)

    Do the magic rewriting tools 1) have a useful install that can run outside of the environment of whoever runs them now, and 2) run on non-libxul (i.e. external) code?

    Tuesday, May 5, 2009 at 22:09 #
  4. cjones wrote::

    There are no plans to extend the API at the moment, but we could add |Trylock()| pretty easily. NSPR already has it, but it’s private to NSPR. You can file a bug on it if you’d find it really useful.

    > 1) have a useful install that can run outside of the environment of whoever runs them now

    Sort of. The install is a little tedious, but it’s documented here:

    https://developer.mozilla.org/En/Pork

    However, there’s a “magic” new tool that hasn’t landed yet. It should happen soon. I’ll blog about it in the near future.

    > 2) run on non-libxul (i.e. external) code?

    Yup, nothing Mozilla-specific here.

    Tuesday, May 5, 2009 at 22:40 #
  5. dbradley wrote::

    I very much agree, a try lock would be great and seems like a good time to add it given these changes.

    Friday, April 1, 2011 at 07:03 #