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 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/message_loop.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
......@@ -95,8 +96,15 @@ class Listener {
~Listener();
// A listener is not considered valid until Start() returns true and its
// delegate's OnListenerStarted method is called with |success| == true
bool Start();
// delegate's OnListenerStarted method is called with |success| == true.
// |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:
scoped_ptr<ListenerImpl> impl_;
......
......@@ -20,7 +20,10 @@ class ListenerImpl {
Domain domain,
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:
std::string name_;
......@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name,
: name_(name), domain_(domain), delegate_(delegate) {
}
bool ListenerImpl::Start() {
bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
// TODO(dmaclach): Implement
NOTIMPLEMENTED();
return false;
......@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name,
Listener::~Listener() {
}
bool Listener::Start() {
return impl_->Start();
bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
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
......@@ -28,7 +28,6 @@
#include "base/sys_string_conversions.h"
#include "base/sys_info.h"
#include "base/threading/simple_thread.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/common/chrome_paths.h"
// Enable this to build with leopard_switchboard_thread
......@@ -175,7 +174,11 @@ class ListenerImpl : public base::MessagePumpLibevent::Watcher {
Listener::Delegate* delegate);
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();
// Watcher overrides
......@@ -430,9 +433,13 @@ ListenerImpl::~ListenerImpl() {
}
}
bool ListenerImpl::Start() {
bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
DCHECK_EQ(fd_, -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();
Task* task;
if(UseLeopardSwitchboardThread()) {
......@@ -440,12 +447,13 @@ bool ListenerImpl::Start() {
} else {
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() {
DCHECK(UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
bool success = true;
{
base::AutoLock autolock(switchboard_lock_);
......@@ -474,7 +482,7 @@ void ListenerImpl::StartLeopard() {
void ListenerImpl::StartSnowLeopard() {
DCHECK(!UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
bool success = true;
std::string notification = AddPrefixToNotification(name_, domain_);
uint32_t status = notify_register_file_descriptor(
......@@ -496,7 +504,7 @@ void ListenerImpl::StartSnowLeopard() {
void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) {
DCHECK(!UseLeopardSwitchboardThread());
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
DCHECK_EQ(fd, fd_);
int token;
int status = HANDLE_EINTR(read(fd, &token, sizeof(token)));
......@@ -518,7 +526,7 @@ void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) {
}
void ListenerImpl::OnListen() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type());
Task* task =
new Listener::NotificationReceivedTask(name_, domain_, delegate_);
CHECK(message_loop_proxy_->PostTask(FROM_HERE, task));
......@@ -536,8 +544,16 @@ Listener::Listener(
Listener::~Listener() {
}
bool Listener::Start() {
return impl_->Start();
bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
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
......
......@@ -11,8 +11,8 @@
#include "base/message_loop.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "base/time.h"
#include "chrome/browser/browser_thread.h"
#include "testing/multiprocess_func_list.h"
#if defined(OS_MACOSX)
......@@ -97,14 +97,14 @@ void QuitterDelegate::OnNotificationReceived(
}
int MultiProcessNotificationMain(multi_process_notification::Domain domain) {
BrowserThread browser_thread(BrowserThread::IO);
base::Thread thread("MultiProcessNotificationMainIOThread");
base::Thread::Options options(MessageLoop::TYPE_IO, 0);
EXPECT_TRUE(browser_thread.StartWithOptions(options));
EXPECT_TRUE(thread.StartWithOptions(options));
MessageLoop loop;
QuitterDelegate quitter;
multi_process_notification::Listener listener(
kQuitNotificationName, domain, &quitter);
EXPECT_TRUE(listener.Start());
EXPECT_TRUE(listener.Start(thread.message_loop()));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
EXPECT_TRUE(quitter.WasStartedReceived());
EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName,
......@@ -123,27 +123,22 @@ class MultiProcessNotificationTest : public base::MultiProcessTest {
void PostNotificationTest(multi_process_notification::Domain domain);
void CrossPostNotificationTest(multi_process_notification::Domain domain);
static void SetUpTestCase();
static void TearDownTestCase();
virtual void SetUp();
MessageLoop* IOMessageLoop() { return io_thread_.message_loop(); };
private:
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() {
g_io_thread = new BrowserThread(BrowserThread::IO);
void MultiProcessNotificationTest::SetUp() {
base::Thread::Options options(MessageLoop::TYPE_IO, 0);
ASSERT_TRUE(g_io_thread->StartWithOptions(options));
}
void MultiProcessNotificationTest::TearDownTestCase() {
delete g_io_thread;
ASSERT_TRUE(io_thread_.StartWithOptions(options));
}
void MultiProcessNotificationTest::PostNotificationTest(
......@@ -151,7 +146,7 @@ void MultiProcessNotificationTest::PostNotificationTest(
QuitterDelegate process_started;
multi_process_notification::Listener listener(
kStartedNotificationName, domain, &process_started);
ASSERT_TRUE(listener.Start());
ASSERT_TRUE(listener.Start(IOMessageLoop()));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(process_started.WasStartedReceived());
std::string process_name;
......@@ -201,13 +196,14 @@ void MultiProcessNotificationTest::CrossPostNotificationTest(
final_notification, multi_process_notification::UserDomain,
&final_quitter);
ASSERT_TRUE(profile_listener.Start());
MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(profile_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(profile_quitter.WasStartedReceived());
ASSERT_TRUE(user_listener.Start());
ASSERT_TRUE(user_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(user_quitter.WasStartedReceived());
ASSERT_TRUE(system_listener.Start());
ASSERT_TRUE(system_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(system_quitter.WasStartedReceived());
......@@ -218,7 +214,7 @@ void MultiProcessNotificationTest::CrossPostNotificationTest(
// 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
// were called.
ASSERT_TRUE(final_listener.Start());
ASSERT_TRUE(final_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
EXPECT_TRUE(final_quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post(
......@@ -250,14 +246,20 @@ TEST_F(MultiProcessNotificationTest, BasicCreationTest) {
QuitterDelegate quitter;
multi_process_notification::Listener local_listener(
"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());
ASSERT_TRUE(quitter.WasStartedReceived());
multi_process_notification::Listener system_listener(
"BasicCreationTest", multi_process_notification::SystemDomain, &quitter);
ASSERT_TRUE(system_listener.Start());
ASSERT_TRUE(system_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
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) {
......@@ -265,8 +267,8 @@ TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
QuitterDelegate quitter;
multi_process_notification::Listener listener(
local_notification, multi_process_notification::UserDomain, &quitter);
ASSERT_TRUE(listener.Start());
MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post(
......@@ -292,14 +294,14 @@ TEST_F(MultiProcessNotificationTest, MultiListener) {
multi_process_notification::Listener quit_listener(quit_local_notification,
multi_process_notification::UserDomain, &quitter);
ASSERT_TRUE(local_listener1.Start());
MessageLoop* message_loop = IOMessageLoop();
ASSERT_TRUE(local_listener1.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(delegate1.WasStartedReceived());
ASSERT_TRUE(local_listener2.Start());
ASSERT_TRUE(local_listener2.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(delegate2.WasStartedReceived());
ASSERT_TRUE(quit_listener.Start());
ASSERT_TRUE(quit_listener.Start(message_loop));
SpinRunLoop(TestTimeouts::action_max_timeout_ms());
ASSERT_TRUE(quitter.WasStartedReceived());
ASSERT_TRUE(multi_process_notification::Post(
......
......@@ -20,7 +20,10 @@ class ListenerImpl {
Domain domain,
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:
std::string name_;
......@@ -36,7 +39,7 @@ ListenerImpl::ListenerImpl(const std::string& name,
: name_(name), domain_(domain), delegate_(delegate) {
}
bool ListenerImpl::Start() {
bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) {
// TODO(dmaclach): Implement
NOTIMPLEMENTED();
return false;
......@@ -51,8 +54,16 @@ Listener::Listener(const std::string& name,
Listener::~Listener() {
}
bool Listener::Start() {
return impl_->Start();
bool Listener::Start(MessageLoop* io_loop_to_listen_on) {
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
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