Bug 821292 - Clean up runnables when RUN_ON_THREAD runs on the same thread. r=jesup

This commit is contained in:
EKR 2012-12-21 07:11:02 -08:00
Родитель 4ccc635ab9
Коммит 693c7463fa
2 изменённых файлов: 53 добавлений и 6 удалений

Просмотреть файл

@ -10,13 +10,13 @@
#define runnable_utils_h__
#include "nsThreadUtils.h"
#include "mozilla/RefPtr.h"
// Abstract base class for all of our templates
namespace mozilla {
class runnable_args_base : public nsRunnable {
public:
NS_IMETHOD Run() = 0;
};
@ -39,7 +39,16 @@ class runnable_args_base : public nsRunnable {
#include "runnable_utils_generated.h"
// Temporary hack. Really we want to have a template which will do this
#define RUN_ON_THREAD(t, r, h) ((t && (t != nsRefPtr<nsIThread>(do_GetCurrentThread()))) ? t->Dispatch(r, h) : r->Run())
static inline nsresult RUN_ON_THREAD(nsIEventTarget *thread, nsIRunnable *runnable, uint32_t flags) {
RefPtr<nsIRunnable> runnable_ref(runnable);
if (thread && (thread != nsRefPtr<nsIThread>(do_GetCurrentThread()))) {
return thread->Dispatch(runnable_ref, flags);
}
return runnable_ref->Run();
}
#define ASSERT_ON_THREAD(t) do { \
if (t) { \
bool on; \

Просмотреть файл

@ -1,4 +1,3 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
@ -15,6 +14,7 @@
#include "nsXPCOM.h"
#include "nsXPCOMGlue.h"
#include "mozilla/RefPtr.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIIOService.h"
@ -37,6 +37,20 @@ MtransportTestUtils *test_utils;
namespace {
class Destructor {
public:
Destructor(bool* destroyed) : destroyed_(destroyed) {}
~Destructor() {
std::cerr << "Destructor called" << std::endl;
*destroyed_ = true;
}
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Destructor);
private:
bool *destroyed_;
};
class TargetClass {
public:
TargetClass(int *ran) : ran_(ran) {}
@ -59,10 +73,16 @@ class TargetClass {
std::cerr << __FUNCTION__ << std::endl;
return x;
}
void destructor_target(Destructor*) {
}
void destructor_target_ref(RefPtr<Destructor> destructor) {
}
int *ran_;
};
class RunnableArgsTest : public ::testing::Test {
public:
RunnableArgsTest() : ran_(0), cl_(&ran_){}
@ -84,7 +104,6 @@ class RunnableArgsTest : public ::testing::Test {
TargetClass cl_;
};
class DispatchTest : public ::testing::Test {
public:
DispatchTest() : ran_(0), cl_(&ran_) {}
@ -126,8 +145,6 @@ class DispatchTest : public ::testing::Test {
protected:
int ran_;
TargetClass cl_;
private:
nsCOMPtr<nsIEventTarget> target_;
};
@ -183,6 +200,27 @@ TEST_F(DispatchTest, TestNonMethodRet) {
ASSERT_EQ(10, z);
}
TEST_F(DispatchTest, TestDestructor) {
bool destroyed = false;
RefPtr<Destructor> destructor = new Destructor(&destroyed);
target_->Dispatch(WrapRunnable(&cl_, &TargetClass::destructor_target,
destructor),
NS_DISPATCH_SYNC);
ASSERT_FALSE(destroyed);
destructor = nullptr;
ASSERT_TRUE(destroyed);
}
TEST_F(DispatchTest, TestDestructorRef) {
bool destroyed = false;
RefPtr<Destructor> destructor = new Destructor(&destroyed);
target_->Dispatch(WrapRunnable(&cl_, &TargetClass::destructor_target_ref,
destructor),
NS_DISPATCH_SYNC);
ASSERT_FALSE(destroyed);
destructor = nullptr;
ASSERT_TRUE(destroyed);
}
} // end of namespace