Bug 977819 - 'Allow PBackgroundChild implementors to hook into the threadlocal space'. r=mrbkap.

This commit is contained in:
Ben Turner 2014-03-31 19:55:36 -07:00
parent 97fce92de5
commit 096fff6e73
5 changed files with 96 additions and 0 deletions

View File

@ -150,6 +150,7 @@ using namespace mozilla::system;
#endif
#ifdef ENABLE_TESTS
#include "BackgroundChildImpl.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#endif
@ -241,6 +242,10 @@ private:
bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);
BackgroundChildImpl::ThreadLocal* threadLocal =
BackgroundChildImpl::GetThreadLocalForCurrentThread();
MOZ_RELEASE_ASSERT(threadLocal);
// Callback 2.
ok = BackgroundChild::GetOrCreateForCurrentThread(this);
MOZ_RELEASE_ASSERT(ok);

View File

@ -132,6 +132,9 @@ for var in ('MOZ_PERMISSIONS', 'MOZ_CHILD_PERMISSIONS'):
if CONFIG['ENABLE_TESTS']:
DEFINES['ENABLE_TESTS'] = 1
LOCAL_INCLUDES += [
'ipc/glue',
]
JAR_MANIFESTS += ['jar.mn']

View File

@ -35,6 +35,28 @@ class TestChild MOZ_FINAL : public mozilla::ipc::PBackgroundTestChild
namespace mozilla {
namespace ipc {
// -----------------------------------------------------------------------------
// BackgroundChildImpl::ThreadLocal
// -----------------------------------------------------------------------------
BackgroundChildImpl::
ThreadLocal::ThreadLocal()
{
// May happen on any thread!
MOZ_COUNT_CTOR(mozilla::ipc::BackgroundChildImpl::ThreadLocal);
}
BackgroundChildImpl::
ThreadLocal::~ThreadLocal()
{
// May happen on any thread!
MOZ_COUNT_DTOR(mozilla::ipc::BackgroundChildImpl::ThreadLocal);
}
// -----------------------------------------------------------------------------
// BackgroundChildImpl
// -----------------------------------------------------------------------------
BackgroundChildImpl::BackgroundChildImpl()
{
// May happen on any thread!

View File

@ -8,6 +8,8 @@
#include "mozilla/Attributes.h"
#include "mozilla/ipc/PBackgroundChild.h"
template <class> class nsAutoPtr;
namespace mozilla {
namespace ipc {
@ -15,6 +17,17 @@ namespace ipc {
// to be inherited in BackgroundImpl.
class BackgroundChildImpl : public PBackgroundChild
{
public:
class ThreadLocal;
// Get the ThreadLocal for the current thread if
// BackgroundChild::GetOrCreateForCurrentThread() has been called and true was
// returned (e.g. a valid PBackgroundChild actor has been created or is in the
// process of being created). Otherwise this function returns null.
// This functions is implemented in BackgroundImpl.cpp.
static ThreadLocal*
GetThreadLocalForCurrentThread();
protected:
BackgroundChildImpl();
virtual ~BackgroundChildImpl();
@ -29,6 +42,20 @@ protected:
DeallocPBackgroundTestChild(PBackgroundTestChild* aActor) MOZ_OVERRIDE;
};
class BackgroundChildImpl::ThreadLocal
{
friend class nsAutoPtr<ThreadLocal>;
// Add any members needed here.
public:
ThreadLocal();
private:
// Only destroyed by nsAutoPtr<ThreadLocal>.
~ThreadLocal();
};
} // namespace ipc
} // namespace mozilla

View File

@ -302,6 +302,7 @@ private:
class ChildImpl MOZ_FINAL : public BackgroundChildImpl
{
friend class mozilla::ipc::BackgroundChild;
friend class mozilla::ipc::BackgroundChildImpl;
typedef base::ProcessId ProcessId;
typedef mozilla::ipc::Transport Transport;
@ -330,6 +331,7 @@ class ChildImpl MOZ_FINAL : public BackgroundChildImpl
nsRefPtr<ChildImpl> mActor;
nsTArray<nsCOMPtr<nsIIPCBackgroundChildCreateCallback>> mCallbacks;
nsAutoPtr<BackgroundChildImpl::ThreadLocal> mConsumerThreadLocal;
};
// This is only modified on the main thread. It is a FIFO queue for actors
@ -393,6 +395,10 @@ private:
static bool
GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback);
// Forwarded from BackgroundChildImpl.
static BackgroundChildImpl::ThreadLocal*
GetThreadLocalForCurrentThread();
static void
ThreadLocalDestructor(void* aThreadLocal)
{
@ -827,6 +833,17 @@ BackgroundChild::GetOrCreateForCurrentThread(
return ChildImpl::GetOrCreateForCurrentThread(aCallback);
}
// -----------------------------------------------------------------------------
// BackgroundChildImpl Public Methods
// -----------------------------------------------------------------------------
// static
BackgroundChildImpl::ThreadLocal*
BackgroundChildImpl::GetThreadLocalForCurrentThread()
{
return ChildImpl::GetThreadLocalForCurrentThread();
}
// -----------------------------------------------------------------------------
// ParentImpl Static Members
// -----------------------------------------------------------------------------
@ -1623,6 +1640,28 @@ ChildImpl::GetOrCreateForCurrentThread(
return true;
}
// static
BackgroundChildImpl::ThreadLocal*
ChildImpl::GetThreadLocalForCurrentThread()
{
MOZ_ASSERT(sThreadLocalIndex != kBadThreadLocalIndex,
"BackgroundChild::Startup() was never called!");
auto threadLocalInfo =
static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex));
if (!threadLocalInfo) {
return nullptr;
}
if (!threadLocalInfo->mConsumerThreadLocal) {
threadLocalInfo->mConsumerThreadLocal =
new BackgroundChildImpl::ThreadLocal();
}
return threadLocalInfo->mConsumerThreadLocal;
}
ChildImpl::CreateCallbackRunnable::~CreateCallbackRunnable()
{
if (mActor) {