Commit 0a179f96 authored by dmaclach@chromium.org's avatar dmaclach@chromium.org

Fix up notifications so that they aren't only on Browser IOThread.

I wasn't thinking and realized I need to get rid of the dependency on Browser IOThread, because the service process doesn't have one.
This means I can move this back to chrome/common, but I won't do that until you have finished your implementations.

BUG=NONE
TEST=BUILD

Review URL: http://codereview.chromium.org/6312007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71961 0039d316-1c4b-4281-b951-d872f2087c98
parent af05a799
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h" #include "base/scoped_ptr.h"
#include "base/task.h" #include "base/task.h"
...@@ -95,8 +96,15 @@ class Listener { ...@@ -95,8 +96,15 @@ class Listener {
~Listener(); ~Listener();
// A listener is not considered valid until Start() returns true and its // A listener is not considered valid until Start() returns true and its
// delegate's OnListenerStarted method is called with |success| == true // delegate's OnListenerStarted method is called with |success| == true.
bool Start(); // |io_loop_to_listen_on| is the message loop to register the listener on.
// All callbacks will be made in the same thread that "Start" is called on,
// not the thread that owns io_loop_to_listen_on.
// |io_loop_to_listen_on| must be of type TYPE_IO.
bool Start(MessageLoop* io_loop_to_listen_on);
std::string name() const;
Domain domain() const;
private: private:
scoped_ptr<ListenerImpl> impl_; scoped_ptr<ListenerImpl> impl_;
......
...@@ -20,7 +20,10 @@ class ListenerImpl { ...@@ -20,7 +20,10 @@ class ListenerImpl {
Domain domain, Domain domain,
Listener::Delegate* delegate); Listener::Delegate* delegate);
bool Start(); bool Start(MessageLoop* io_loop_to_listen_on);
std::string name() const { return name_; }
Domain domain() const { return domain_; }
private: private:
std::string name_; std::string name_;
...@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name, ...@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name,
: name_(name), domain_(domain), delegate_(delegate) { : name_(name), domain_(domain), delegate_(delegate) {
} }
bool ListenerImpl::Start() { bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
// TODO(dmaclach): Implement // TODO(dmaclach): Implement
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false; return false;
...@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name, ...@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name,
Listener::~Listener() { Listener::~Listener() {
} }
bool Listener::Start() { bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
return impl_->Start(); return impl_->Start(io_loop_to_listen_on);
}
std::string Listener::name() const {
return impl_->name();
}
Domain Listener::domain() const {
return impl_->domain();
} }
} // namespace multi_process_notification } // namespace multi_process_notification
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "base/sys_string_conversions.h" #include "base/sys_string_conversions.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/threading/simple_thread.h" #include "base/threading/simple_thread.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
// Enable this to build with leopard_switchboard_thread // Enable this to build with leopard_switchboard_thread
...@@ -175,7 +174,11 @@ class ListenerImpl : public base::MessagePumpLibevent::Watcher { ...@@ -175,7 +174,11 @@ class ListenerImpl : public base::MessagePumpLibevent::Watcher {
Listener::Delegate* delegate); Listener::Delegate* delegate);
virtual ~ListenerImpl(); virtual ~ListenerImpl();
bool Start(); bool Start(MessageLoop* io_loop_to_listen_on);
std::string name() const { return name_; }
Domain domain() const { return domain_; }
void OnListen(); void OnListen();
// Watcher overrides // Watcher overrides
...@@ -430,9 +433,13 @@ ListenerImpl::~ListenerImpl() { ...@@ -430,9 +433,13 @@ ListenerImpl::~ListenerImpl() {
} }
} }
bool ListenerImpl::Start() { bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
DCHECK_EQ(fd_, -1); DCHECK_EQ(fd_, -1);
DCHECK_EQ(token_, -1); DCHECK_EQ(token_, -1);
if (io_loop_to_listen_on->type() != MessageLoop::TYPE_IO) {
DLOG(ERROR) << "io_loop_to_listen_on must be TYPE_IO";
return false;
}
message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread(); message_loop_proxy_ = base::MessageLoopProxy::CreateForCurrentThread();
Task* task; Task* task;
if(UseLeopardSwitchboardThread()) { if(UseLeopardSwitchboardThread()) {
...@@ -440,12 +447,13 @@ bool ListenerImpl::Start() { ...@@ -440,12 +447,13 @@ bool ListenerImpl::Start() {
} else { } else {
task = NewRunnableMethod(this, &ListenerImpl::StartSnowLeopard); task = NewRunnableMethod(this, &ListenerImpl::StartSnowLeopard);
} }
return BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task); io_loop_to_listen_on->PostTask(FROM_HERE, task);
return true;
} }
void ListenerImpl::StartLeopard() { void ListenerImpl::StartLeopard() {
DCHECK(UseLeopardSwitchboardThread()); DCHECK(UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
bool success = true; bool success = true;
{ {
base::AutoLock autolock(switchboard_lock_); base::AutoLock autolock(switchboard_lock_);
...@@ -474,7 +482,7 @@ void ListenerImpl::StartLeopard() { ...@@ -474,7 +482,7 @@ void ListenerImpl::StartLeopard() {
void ListenerImpl::StartSnowLeopard() { void ListenerImpl::StartSnowLeopard() {
DCHECK(!UseLeopardSwitchboardThread()); DCHECK(!UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
bool success = true; bool success = true;
std::string notification = AddPrefixToNotification(name_, domain_); std::string notification = AddPrefixToNotification(name_, domain_);
uint32_t status = notify_register_file_descriptor( uint32_t status = notify_register_file_descriptor(
...@@ -496,7 +504,7 @@ void ListenerImpl::StartSnowLeopard() { ...@@ -496,7 +504,7 @@ void ListenerImpl::StartSnowLeopard() {
void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) { void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) {
DCHECK(!UseLeopardSwitchboardThread()); DCHECK(!UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
DCHECK_EQ(fd, fd_); DCHECK_EQ(fd, fd_);
int token; int token;
int status = HANDLE_EINTR(read(fd, &token, sizeof(token))); int status = HANDLE_EINTR(read(fd, &token, sizeof(token)));
...@@ -518,7 +526,7 @@ void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) { ...@@ -518,7 +526,7 @@ void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) {
} }
void ListenerImpl::OnListen() { void ListenerImpl::OnListen() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
Task* task = Task* task =
new Listener::NotificationReceivedTask(name_, domain_, delegate_); new Listener::NotificationReceivedTask(name_, domain_, delegate_);
CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); CHECK(message_loop_proxy_->PostTask(FROM_HERE, task));
...@@ -536,8 +544,16 @@ Listener::Listener( ...@@ -536,8 +544,16 @@ Listener::Listener(
Listener::~Listener() { Listener::~Listener() {
} }
bool Listener::Start() { bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
return impl_->Start(); return impl_->Start(io_loop_to_listen_on);
}
std::string Listener::name() const {
return impl_->name();
}
Domain Listener::domain() const {
return impl_->domain();
} }
} // namespace multi_process_notification } // namespace multi_process_notification
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/test/multiprocess_test.h" #include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h" #include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "base/time.h" #include "base/time.h"
#include "chrome/browser/browser_thread.h"
#include "testing/multiprocess_func_list.h" #include "testing/multiprocess_func_list.h"
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
...@@ -97,14 +97,14 @@ void QuitterDelegate::OnNotificationReceived( ...@@ -97,14 +97,14 @@ void QuitterDelegate::OnNotificationReceived(
} }
int MultiProcessNotificationMain(multi_process_notification::Domain domain) { int MultiProcessNotificationMain(multi_process_notification::Domain domain) {
BrowserThread browser_thread(BrowserThread::IO); base::Thread thread("MultiProcessNotificationMainIOThread");
base::Thread::Options options(MessageLoop::TYPE_IO, 0); base::Thread::Options options(MessageLoop::TYPE_IO, 0);
EXPECT_TRUE(browser_thread.StartWithOptions(options)); EXPECT_TRUE(thread.StartWithOptions(options));
MessageLoop loop; MessageLoop loop;
QuitterDelegate quitter; QuitterDelegate quitter;
multi_process_notification::Listener listener( multi_process_notification::Listener listener(
kQuitNotificationName, domain, &quitter); kQuitNotificationName, domain, &quitter);
EXPECT_TRUE(listener.Start()); EXPECT_TRUE(listener.Start(thread.message_loop()));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
EXPECT_TRUE(quitter.WasStartedReceived()); EXPECT_TRUE(quitter.WasStartedReceived());
EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName, EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName,
...@@ -123,27 +123,22 @@ class MultiProcessNotificationTest : public base::MultiProcessTest { ...@@ -123,27 +123,22 @@ class MultiProcessNotificationTest : public base::MultiProcessTest {
void PostNotificationTest(multi_process_notification::Domain domain); void PostNotificationTest(multi_process_notification::Domain domain);
void CrossPostNotificationTest(multi_process_notification::Domain domain); void CrossPostNotificationTest(multi_process_notification::Domain domain);
static void SetUpTestCase(); virtual void SetUp();
static void TearDownTestCase(); MessageLoop* IOMessageLoop() { return io_thread_.message_loop(); };
private: private:
MessageLoop loop_; MessageLoop loop_;
static BrowserThread* g_io_thread; base::Thread io_thread_;
}; };
MultiProcessNotificationTest::MultiProcessNotificationTest() { MultiProcessNotificationTest::MultiProcessNotificationTest()
: io_thread_("MultiProcessNotificationTestThread") {
} }
BrowserThread* MultiProcessNotificationTest::g_io_thread = NULL;
void MultiProcessNotificationTest::SetUpTestCase() { void MultiProcessNotificationTest::SetUp() {
g_io_thread = new BrowserThread(BrowserThread::IO);
base::Thread::Options options(MessageLoop::TYPE_IO, 0); base::Thread::Options options(MessageLoop::TYPE_IO, 0);
ASSERT_TRUE(g_io_thread->StartWithOptions(options)); ASSERT_TRUE(io_thread_.StartWithOptions(options));
}
void MultiProcessNotificationTest::TearDownTestCase() {
delete g_io_thread;
} }
void MultiProcessNotificationTest::PostNotificationTest( void MultiProcessNotificationTest::PostNotificationTest(
...@@ -151,7 +146,7 @@ void MultiProcessNotificationTest::PostNotificationTest( ...@@ -151,7 +146,7 @@ void MultiProcessNotificationTest::PostNotificationTest(
QuitterDelegate process_started; QuitterDelegate process_started;
multi_process_notification::Listener listener( multi_process_notification::Listener listener(
kStartedNotificationName, domain, &process_started); kStartedNotificationName, domain, &process_started);
ASSERT_TRUE(listener.Start()); ASSERT_TRUE(listener.Start(IOMessageLoop()));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(process_started.WasStartedReceived()); ASSERT_TRUE(process_started.WasStartedReceived());
std::string process_name; std::string process_name;
...@@ -201,13 +196,14 @@ void MultiProcessNotificationTest::CrossPostNotificationTest( ...@@ -201,13 +196,14 @@ void MultiProcessNotificationTest::CrossPostNotificationTest(
final_notification, multi_process_notification::UserDomain, final_notification, multi_process_notification::UserDomain,
&final_quitter); &final_quitter);
ASSERT_TRUE(profile_listener.Start()); MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(profile_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(profile_quitter.WasStartedReceived()); ASSERT_TRUE(profile_quitter.WasStartedReceived());
ASSERT_TRUE(user_listener.Start()); ASSERT_TRUE(user_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(user_quitter.WasStartedReceived()); ASSERT_TRUE(user_quitter.WasStartedReceived());
ASSERT_TRUE(system_listener.Start()); ASSERT_TRUE(system_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(system_quitter.WasStartedReceived()); ASSERT_TRUE(system_quitter.WasStartedReceived());
...@@ -218,7 +214,7 @@ void MultiProcessNotificationTest::CrossPostNotificationTest( ...@@ -218,7 +214,7 @@ void MultiProcessNotificationTest::CrossPostNotificationTest(
// after the local_notification and make sure that all listeners have had a // after the local_notification and make sure that all listeners have had a
// chance to process local_notification before we check to see if they // chance to process local_notification before we check to see if they
// were called. // were called.
ASSERT_TRUE(final_listener.Start()); ASSERT_TRUE(final_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
EXPECT_TRUE(final_quitter.WasStartedReceived()); EXPECT_TRUE(final_quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post( ASSERT_TRUE(multi_process_notification::Post(
...@@ -250,14 +246,20 @@ TEST_F(MultiProcessNotificationTest, BasicCreationTest) { ...@@ -250,14 +246,20 @@ TEST_F(MultiProcessNotificationTest, BasicCreationTest) {
QuitterDelegate quitter; QuitterDelegate quitter;
multi_process_notification::Listener local_listener( multi_process_notification::Listener local_listener(
"BasicCreationTest", multi_process_notification::UserDomain, &quitter); "BasicCreationTest", multi_process_notification::UserDomain, &quitter);
ASSERT_TRUE(local_listener.Start()); MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(local_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived()); ASSERT_TRUE(quitter.WasStartedReceived());
multi_process_notification::Listener system_listener( multi_process_notification::Listener system_listener(
"BasicCreationTest", multi_process_notification::SystemDomain, &quitter); "BasicCreationTest", multi_process_notification::SystemDomain, &quitter);
ASSERT_TRUE(system_listener.Start()); ASSERT_TRUE(system_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived()); ASSERT_TRUE(quitter.WasStartedReceived());
multi_process_notification::Listener local_listener2(
"BasicCreationTest", multi_process_notification::UserDomain, &quitter);
// Should fail because current message loop should not be an IOMessageLoop.
ASSERT_FALSE(local_listener2.Start(MessageLoop::current()));
} }
TEST_F(MultiProcessNotificationTest, PostInProcessNotification) { TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
...@@ -265,8 +267,8 @@ TEST_F(MultiProcessNotificationTest, PostInProcessNotification) { ...@@ -265,8 +267,8 @@ TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
QuitterDelegate quitter; QuitterDelegate quitter;
multi_process_notification::Listener listener( multi_process_notification::Listener listener(
local_notification, multi_process_notification::UserDomain, &quitter); local_notification, multi_process_notification::UserDomain, &quitter);
MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(listener.Start()); ASSERT_TRUE(listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived()); ASSERT_TRUE(quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post( ASSERT_TRUE(multi_process_notification::Post(
...@@ -292,14 +294,14 @@ TEST_F(MultiProcessNotificationTest, MultiListener) { ...@@ -292,14 +294,14 @@ TEST_F(MultiProcessNotificationTest, MultiListener) {
multi_process_notification::Listener quit_listener(quit_local_notification, multi_process_notification::Listener quit_listener(quit_local_notification,
multi_process_notification::UserDomain, &quitter); multi_process_notification::UserDomain, &quitter);
MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(local_listener1.Start()); ASSERT_TRUE(local_listener1.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(delegate1.WasStartedReceived()); ASSERT_TRUE(delegate1.WasStartedReceived());
ASSERT_TRUE(local_listener2.Start()); ASSERT_TRUE(local_listener2.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(delegate2.WasStartedReceived()); ASSERT_TRUE(delegate2.WasStartedReceived());
ASSERT_TRUE(quit_listener.Start()); ASSERT_TRUE(quit_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms()); SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived()); ASSERT_TRUE(quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post( ASSERT_TRUE(multi_process_notification::Post(
......
...@@ -20,7 +20,10 @@ class ListenerImpl { ...@@ -20,7 +20,10 @@ class ListenerImpl {
Domain domain, Domain domain,
Listener::Delegate* delegate); Listener::Delegate* delegate);
bool Start(); bool Start(MessageLoop* io_loop_to_listen_on);
std::string name() const { return name_; }
Domain domain() const { return domain_; }
private: private:
std::string name_; std::string name_;
...@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name, ...@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name,
: name_(name), domain_(domain), delegate_(delegate) { : name_(name), domain_(domain), delegate_(delegate) {
} }
bool ListenerImpl::Start() { bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
// TODO(dmaclach): Implement // TODO(dmaclach): Implement
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false; return false;
...@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name, ...@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name,
Listener::~Listener() { Listener::~Listener() {
} }
bool Listener::Start() { bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
return impl_->Start(); return impl_->Start(io_loop_to_listen_on);
}
std::string Listener::name() const {
return impl_->name();
}
Domain Listener::domain() const {
return impl_->domain();
} }
} // namespace multi_process_notification } // namespace multi_process_notification
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment