Re: Runnables and thread-unsafe members

2015-04-15 Thread Ehsan Akhgari

Sounds good to me as well.

On 2015-04-14 5:44 PM, Bobby Holley wrote:

+1.

On Tue, Apr 14, 2015 at 2:42 PM, Kyle Huey m...@kylehuey.com wrote:


On Tue, Apr 14, 2015 at 2:39 PM, Randell Jesup rjesup.n...@jesup.org
wrote:

(was: Re: Proposal to ban the usage of refcounted objects inside C++
lambdas in Gecko)

tl;dr: We should make DispatchToMainThread take already_AddRefed and
move away from raw ptrs for Dispatches in general.


Agreed.

- Kyle
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform



___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: Runnables and thread-unsafe members

2015-04-14 Thread Jan-Ivar Bruaroey

On 4/14/15 5:39 PM, Randell Jesup wrote:

I wonder if we could move to requiring already_AddRefed for
DispatchToMainThread (and Dispatch?), and thus block all attempts to do
DispatchToMainThread(new FooRunnable), etc.  :-)


Yes! +1.

I like the .forget() semantics, but just to have options, here's a 
variation that might even be simpler: https://bugzil.la/1154337#c13


.: Jan-Ivar :.

___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Runnables and thread-unsafe members

2015-04-14 Thread Randell Jesup
(was: Re: Proposal to ban the usage of refcounted objects inside C++
lambdas in Gecko)

tl;dr: We should make DispatchToMainThread take already_AddRefed and
move away from raw ptrs for Dispatches in general.

So:

What I want to avoid is this pattern for runnables that hold
thread-restricted pointers (mostly MainThread-restricted, such as JS
callbacks):

 FooRunnable::FooRunnable(nsCOMPtrnsIFoo aFoo)
 {
   mFoo.swap(aFoo); // Never AddRef/Release off MainThread
 }
...
{
  nsRefPtrFooRunnable foo = new FooRunnable(myFoo);
  // RefCnt == 1, myFoo.get() == nullptr now
  NS_DispatchToMainThread(foo); // infallible (soon), takes a ref to foo 
(refcnt 2)

  // XXX what is foo's refcnt here?  You don't know!
}

The reason is that foo may go out of scope here *after* it has Run() and
had the event ref dropped on mainthread.  I.e.: at the XXX comment, it
may usually be 2, but sometimes may be 1, and when foo goes out of
scope we delete it here, and violate thread-safety for mFoo.

Blindly taking an NS_DispatchToMainThread(new FooRunnable) and
converting it to the pattern above (with nsRefPtr) will introduce a
timing-based thread safety violation IF it holds thread-locked items
(which isn't super-common).  But also, it's extra thread-safe
addref/releasing when we don't need to.

A safe pattern is this:
{
  nsRefPtrFooRunnable foo = new FooRunnable(myFoo);
  // RefCnt == 1, myFoo.get() == nullptr now
  // This requires adding a version of
  // NS_DispatchToMainThread(already_AddRefednsIRunnable) or some such
  NS_DispatchToMainThread(foo.forget()); // infallible (soon)
  // foo is nullptr
}

And to be honest, that's generally a better pattern for runnables
anyways - we *want* to give them away on Dispatch()/DispatchToMainThread().

Note that you can also do ehsan's trick for safety instead:

   ~FooRunnable()
   {
 if (!NS_IsMainThread()) {
   // get mainthread
   NS_ProxyRelease(mainthread, mFoo);
 }
   }

I don't love this though.  It adds almost-never-executed code, we
addref/release extra times, it could bitrot or forget to grow new
mainthread-only refs.  And it wastes code and adds semantic boilerplate
to ignore when reading code.

You could add a macro to build these and hide the boilerplate some, but
that's not wonderful either.

So, if I have my druthers:  (And really only #1 is needed, probably)

1) Add already_AddRefed variants of Dispatch/DispatchToMainThread, and
   convert things as needed to .forget() (Preferably most
   Dispatch/DispatchToMainThreads would become this.)  If the Dispatch()
   can fail and it's not a logic error somewhere (due to Dispatch to a
   doomed thread perhaps in some race conditions), then live with a leak
   - we can't send it there to die.  DispatchToMainThread() isn't
   affected by this and will be infallible soon.

2) If you're building a runnable with a complex lifetime and a
   MainThread or thread-locked object, also add the ProxyRelease
   destructor.  Otherwise consider simple boilerplate (for
   MainThread-only runnables) to do:
   
 ~FooRunnable() { if (!NS_IsMainThread()) { MOZ_CRASH(); } }

   (Perhaps DESTROYED_ON_MAINTHREAD_ONLY(FooRunnable)).  Might not be a
   bad thing to have in our pockets for other reasons.
   
3) Consider replacing nsCOMPtrnsIFoo mFoo in the runnable with
   nsReleaseOnMainThreadnsCOMPtrnsIFoo mFoo and have
   ~nsReleaseOnMainThread() do NS_ProxyRelease, and also have
   nsReleaseOnMainThread block attempts to do assignments that AddRef
   (only set via swap or assign from already_AddRefed).  Unlike the
   MainThreadPtrHolder this could be created on other threads since it
   never AddRefs; it only inherits references and releases them on MainThread

I wonder if we could move to requiring already_AddRefed for
DispatchToMainThread (and Dispatch?), and thus block all attempts to do
DispatchToMainThread(new FooRunnable), etc.  :-)

-- 
Randell Jesup, Mozilla Corp
remove news for personal email
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: Runnables and thread-unsafe members

2015-04-14 Thread Kyle Huey
On Tue, Apr 14, 2015 at 2:39 PM, Randell Jesup rjesup.n...@jesup.org wrote:
 (was: Re: Proposal to ban the usage of refcounted objects inside C++
 lambdas in Gecko)

 tl;dr: We should make DispatchToMainThread take already_AddRefed and
 move away from raw ptrs for Dispatches in general.

Agreed.

- Kyle
___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform


Re: Runnables and thread-unsafe members

2015-04-14 Thread Bobby Holley
+1.

On Tue, Apr 14, 2015 at 2:42 PM, Kyle Huey m...@kylehuey.com wrote:

 On Tue, Apr 14, 2015 at 2:39 PM, Randell Jesup rjesup.n...@jesup.org
 wrote:
  (was: Re: Proposal to ban the usage of refcounted objects inside C++
  lambdas in Gecko)
 
  tl;dr: We should make DispatchToMainThread take already_AddRefed and
  move away from raw ptrs for Dispatches in general.

 Agreed.

 - Kyle
 ___
 dev-platform mailing list
 dev-platform@lists.mozilla.org
 https://lists.mozilla.org/listinfo/dev-platform

___
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform