diff options
author | dmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 16:14:20 +0000 |
---|---|---|
committer | dmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-02 16:14:20 +0000 |
commit | 3a987718a3468c24d1ac9cfa378ff0cc0c5b3490 (patch) | |
tree | adddde27c2925d9b5d346c1f8cf628447bf5eb4f /chrome | |
parent | 36bc34c3d65c69abf4197b597dda1f6eddaaf022 (diff) | |
download | chromium_src-3a987718a3468c24d1ac9cfa378ff0cc0c5b3490.zip chromium_src-3a987718a3468c24d1ac9cfa378ff0cc0c5b3490.tar.gz chromium_src-3a987718a3468c24d1ac9cfa378ff0cc0c5b3490.tar.bz2 |
Remove multi_process_notifications
BUG=none
TEST=build
Review URL: http://codereview.chromium.org/6250100
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73461 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/multi_process_notification.cc | 42 | ||||
-rw-r--r-- | chrome/browser/multi_process_notification.h | 117 | ||||
-rw-r--r-- | chrome/browser/multi_process_notification_linux.cc | 69 | ||||
-rw-r--r-- | chrome/browser/multi_process_notification_mac.mm | 572 | ||||
-rw-r--r-- | chrome/browser/multi_process_notification_unittest.cc | 354 | ||||
-rw-r--r-- | chrome/browser/multi_process_notification_win.cc | 69 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 5 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
8 files changed, 0 insertions, 1229 deletions
diff --git a/chrome/browser/multi_process_notification.cc b/chrome/browser/multi_process_notification.cc deleted file mode 100644 index 6b7cf49..0000000 --- a/chrome/browser/multi_process_notification.cc +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/multi_process_notification.h" - -#include "base/task.h" - -namespace multi_process_notification { - -Listener::Delegate::~Delegate() { -} - -void Listener::Delegate::OnListenerStarted( - const std::string& name, Domain domain, bool success) { -} - -Listener::ListenerStartedTask::ListenerStartedTask(const std::string& name, - Domain domain, Listener::Delegate* delegate, bool success) - : name_(name), domain_(domain), delegate_(delegate), success_(success) { -} - -Listener::ListenerStartedTask::~ListenerStartedTask() { -} - -void Listener::ListenerStartedTask::Run() { - delegate_->OnListenerStarted(name_, domain_, success_); -} - -Listener::NotificationReceivedTask::NotificationReceivedTask( - const std::string& name, Domain domain, Listener::Delegate* delegate) - : name_(name), domain_(domain), delegate_(delegate) { -} - -Listener::NotificationReceivedTask::~NotificationReceivedTask() { -} - -void Listener::NotificationReceivedTask::Run() { - delegate_->OnNotificationReceived(name_, domain_); -} - -} // namespace multi_process_notification diff --git a/chrome/browser/multi_process_notification.h b/chrome/browser/multi_process_notification.h deleted file mode 100644 index 6aa2fc6..0000000 --- a/chrome/browser/multi_process_notification.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_MULTI_PROCESS_NOTIFICATION_H_ -#define CHROME_BROWSER_MULTI_PROCESS_NOTIFICATION_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/message_loop.h" -#include "base/scoped_ptr.h" -#include "base/task.h" - -class Task; -class MessageLoop; - -// Platform abstraction for a notification that can be sent between processes. -// Notifications are strings. The string will be prefixed accordingly per -// platform (so on Mac OS X a "Happy" notification will become -// "org.chromium.Happy"). -namespace multi_process_notification { - -class ListenerImpl; - -enum Domain { - // Notifications intended to be received by processes running with the - // same uid and same profile. - ProfileDomain, - // Notifications intended to be received by processes running with the - // same uid. - UserDomain, - // Notifications intended to be received by processes running on the - // same system. - SystemDomain -}; - -// Posts a notification |name| to |domain|. -// Returns true if the notification was posted. -bool Post(const std::string& name, Domain domain); - -// A notification listener. Will listen for a given notification and -// call the delegate. Note that the delegate is not owned by the listener. -class Listener { - public: - class Delegate { - public: - virtual ~Delegate(); - - // OnNotificationReceived is called on the thread that called Start() on the - // Listener associated with this delegate. - virtual void OnNotificationReceived(const std::string& name, - Domain domain) = 0; - - // OnListenerStarted is called on the thread that called Start() on the - // Listener associated with this delegate. If success is false, there - // was an error starting the listener, and it is invalid. - virtual void OnListenerStarted( - const std::string& name, Domain domain, bool success); - }; - - class ListenerStartedTask : public Task { - public: - ListenerStartedTask(const std::string& name, Domain domain, - Delegate* delegate, bool success); - virtual ~ListenerStartedTask(); - virtual void Run(); - - private: - std::string name_; - Domain domain_; - Delegate* delegate_; - bool success_; - DISALLOW_COPY_AND_ASSIGN(ListenerStartedTask); - }; - - class NotificationReceivedTask : public Task { - public: - NotificationReceivedTask( - const std::string& name, Domain domain, Delegate* delegate); - virtual ~NotificationReceivedTask(); - virtual void Run(); - - private: - std::string name_; - Domain domain_; - Delegate* delegate_; - DISALLOW_COPY_AND_ASSIGN(NotificationReceivedTask); - }; - - Listener(const std::string& name, Domain domain, Delegate* delegate); - - // A destructor is required for scoped_ptr to compile. - ~Listener(); - - // A listener is not considered valid until Start() returns true and its - // 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_; - - DISALLOW_COPY_AND_ASSIGN(Listener); -}; - -} // namespace multi_process_notification - -#endif // CHROME_BROWSER_MULTI_PROCESS_NOTIFICATION_H_ diff --git a/chrome/browser/multi_process_notification_linux.cc b/chrome/browser/multi_process_notification_linux.cc deleted file mode 100644 index 940556f..0000000 --- a/chrome/browser/multi_process_notification_linux.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/multi_process_notification.h" - -#include "base/logging.h" - -namespace multi_process_notification { - -bool Post(const std::string& name, Domain domain) { - // TODO(dmaclach): Implement - NOTIMPLEMENTED(); - return false; -} - -class ListenerImpl { - public: - ListenerImpl(const std::string& name, - Domain domain, - Listener::Delegate* delegate); - - bool Start(MessageLoop* io_loop_to_listen_on); - - std::string name() const { return name_; } - Domain domain() const { return domain_; } - - private: - std::string name_; - Domain domain_; - Listener::Delegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(ListenerImpl); -}; - -ListenerImpl::ListenerImpl(const std::string& name, - Domain domain, - Listener::Delegate* delegate) - : name_(name), domain_(domain), delegate_(delegate) { -} - -bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) { - // TODO(dmaclach): Implement - NOTIMPLEMENTED(); - return false; -} - -Listener::Listener(const std::string& name, - Domain domain, - Listener::Delegate* delegate) - : impl_(new ListenerImpl(name, domain, delegate)) { -} - -Listener::~Listener() { -} - -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 diff --git a/chrome/browser/multi_process_notification_mac.mm b/chrome/browser/multi_process_notification_mac.mm deleted file mode 100644 index 2861a14..0000000 --- a/chrome/browser/multi_process_notification_mac.mm +++ /dev/null @@ -1,572 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/multi_process_notification.h" - -#import <Foundation/Foundation.h> -#include <notify.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <unistd.h> - -#include <algorithm> - -#include "base/basictypes.h" -#include "base/eintr_wrapper.h" -#include "base/file_path.h" -#include "base/logging.h" -#include "base/mac/mac_util.h" -#include "base/mac/scoped_nsautorelease_pool.h" -#include "base/message_loop_proxy.h" -#include "base/message_pump_libevent.h" -#include "base/path_service.h" -#include "base/ref_counted.h" -#include "base/stringprintf.h" -#include "base/synchronization/lock.h" -#include "base/sys_string_conversions.h" -#include "base/sys_info.h" -#include "base/threading/simple_thread.h" -#include "chrome/common/chrome_paths.h" - -// Enable this to build with leopard_switchboard_thread -// #define USE_LEOPARD_SWITCHBOARD_THREAD 1 - -namespace { - -std::string AddPrefixToNotification(const std::string& name, - multi_process_notification::Domain domain) { - // The ordering of the components in the string returned by this function - // is important. Read "NAMESPACE CONVENTIONS" in 'man 3 notify' for details. - base::mac::ScopedNSAutoreleasePool pool; - NSBundle* bundle = base::mac::MainAppBundle(); - NSString* ns_bundle_id = [bundle bundleIdentifier]; - std::string bundle_id = base::SysNSStringToUTF8(ns_bundle_id); - std::string domain_string; - switch (domain) { - case multi_process_notification::ProfileDomain: { - FilePath user_data_dir; - if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { - NOTREACHED(); - } - domain_string = StringPrintf("user.uid.%u.%s.", - getuid(), user_data_dir.value().c_str()); - break; - } - - case multi_process_notification::UserDomain: - domain_string = StringPrintf("user.uid.%u.", getuid()); - break; - - case multi_process_notification::SystemDomain: - break; - } - return domain_string + bundle_id + "." + name; -} - -bool UseLeopardSwitchboardThread() { -#if USE_LEOPARD_SWITCHBOARD_THREAD - return true; -#endif // USE_LEOPARD_SWITCHBOARD_THREAD - int32 major_version, minor_version, bugfix_version; - base::SysInfo::OperatingSystemVersionNumbers( - &major_version, &minor_version, &bugfix_version); - return major_version < 10 || (major_version == 10 && minor_version <= 5); -} - -} // namespace - -namespace multi_process_notification { - -bool Post(const std::string& name, Domain domain) { - std::string notification = AddPrefixToNotification(name, domain); - uint32_t status = notify_post(notification.c_str()); - DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); - return status == NOTIFY_STATUS_OK; -} - -#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 -#error LeopardSwitchboardThread can be removed -#endif // MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 - -// LeopardSwitchboardThread exists because the file descriptors returned by -// notify_register_file_descriptor can't be monitored using kqueues on 10.5 -// ( http://openradar.appspot.com/8854692 ) and libevent uses kqueue to watch -// file descriptors in IOMessageLoop. -// This solution is to have a separate thread that monitors the file descriptor -// returned by notify_register_file_descriptor using select, and then to -// notify the MessageLoopForIO using a different file descriptor allocated by -// socketpair that can be monitored using kqueues in libevent. This thread -// only runs on 10.5, as 10.6 kqueues can monitor the notify file descriptors -// without any problems. - -// LeopardSwitchboardThread creates three file descriptors: -// internal_fd_: which communicates from the switchboard thread to other threads -// external_fd_: which communicates from other threads to the switchboard thread -// notify_fd_: which is the file descriptor returned from -// notify_register_file_descriptor -// -// The thread itself sits in a select loop waiting on internal_fd_, and -// notify_fd_ for input. If it gets ANY input on internal_fd_ it exits. -// If it gets input on notify_fd_ it sends the input through to external_fd_. -// External_fd_ is monitored by MessageLoopForIO so that the lookup of any -// matching listeners in entries_, and the triggering of those listeners, -// occurs in the MessageLoopForIO thread. -// -// Lookups are linear right now, and could be optimized if they ever become -// a performance issue. -class LeopardSwitchboardThread - : public base::MessagePumpLibevent::Watcher, - public base::SimpleThread, - public MessageLoop::DestructionObserver { - public: - LeopardSwitchboardThread(); - virtual ~LeopardSwitchboardThread(); - - bool Init(); - - bool AddListener(ListenerImpl* listener, - const std::string& notification); - bool RemoveListener(ListenerImpl* listener, const std::string& notification); - - bool finished() const { return finished_; } - - // SimpleThread overrides - virtual void Run(); - - // Watcher overrides - virtual void OnFileCanReadWithoutBlocking(int fd); - virtual void OnFileCanWriteWithoutBlocking(int fd); - - // DestructionObserver overrides - virtual void WillDestroyCurrentMessageLoop(); - - private: - // Used to match tokens to notifications and vice-versa. - struct SwitchboardEntry { - int token_; - std::string notification_; - ListenerImpl* listener_; - }; - - enum { - kKillThreadMessage = 0xdecea5e - }; - - int internal_fd_; - int external_fd_; - int notify_fd_; - int notify_fd_token_; - mutable bool finished_; - fd_set fd_set_; - - // all accesses to entries_ must be controlled by entries_lock_. - std::vector<SwitchboardEntry> entries_; - base::Lock entries_lock_; - base::MessagePumpLibevent::FileDescriptorWatcher watcher_; -}; - -class ListenerImpl : public base::MessagePumpLibevent::Watcher { - public: - ListenerImpl(const std::string& name, - Domain domain, - Listener::Delegate* delegate); - virtual ~ListenerImpl(); - - bool Start(MessageLoop* io_loop_to_listen_on); - - std::string name() const { return name_; } - Domain domain() const { return domain_; } - - void OnListen(); - - // Watcher overrides - virtual void OnFileCanReadWithoutBlocking(int fd); - virtual void OnFileCanWriteWithoutBlocking(int fd); - - private: - std::string name_; - Domain domain_; - Listener::Delegate* delegate_; - bool started_; - int fd_; - int token_; - base::Lock switchboard_lock_; - static LeopardSwitchboardThread* g_switchboard_thread_; - base::MessagePumpLibevent::FileDescriptorWatcher watcher_; - scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; - - void StartLeopard(); - void StartSnowLeopard(); - DISALLOW_COPY_AND_ASSIGN(ListenerImpl); -}; - - -LeopardSwitchboardThread::LeopardSwitchboardThread() - : base::SimpleThread("LeopardSwitchboardThread"), internal_fd_(-1), - external_fd_(-1), notify_fd_(-1), notify_fd_token_(-1), finished_(false) { -} - -LeopardSwitchboardThread::~LeopardSwitchboardThread() { - if (internal_fd_ != -1) { - close(internal_fd_); - } - if (external_fd_ != -1) { - close(external_fd_); - } - if (notify_fd_ != -1) { - // Cancelling this notification takes care of closing notify_fd_. - uint32_t status = notify_cancel(notify_fd_token_); - DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); - } -} - -bool LeopardSwitchboardThread::Init() { - // Create a pair of sockets for communicating with the thread - // The file descriptors returned from socketpair can be kqueue'd on 10.5. - int sockets[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { - PLOG(ERROR) << "socketpair"; - return false; - } - internal_fd_ = sockets[0]; - external_fd_ = sockets[1]; - - // Register a bogus notification so that there is single notify_fd_ to - // monitor. This runs a small risk of overflowing the notification buffer - // if notifications are used heavily (see man 3 notify), however it greatly - // simplifies the select loop code as there are only 2 file descriptors - // that need to be monitored, and there is no need to add/remove file - // descriptors from fd_set_ as listeners are added and removed. - // This also keep the total fd usage on 10.5 to three for all - // notifications. The 10.6 implementation will use one fd per notification, - // but doesn't run the risk of notification buffer overflow. If fds ever - // become tight, the 10.6 code could be changed to use only one fd for - // all notifications. - std::string notification = StringPrintf("LeopardSwitchboardThread.%d", - getpid()); - notification = AddPrefixToNotification(notification, ProfileDomain); - uint32_t status = notify_register_file_descriptor( - notification.c_str(), ¬ify_fd_, 0, ¬ify_fd_token_); - if (status != NOTIFY_STATUS_OK) { - return false; - } - - FD_ZERO(&fd_set_); - FD_SET(internal_fd_, &fd_set_); - FD_SET(notify_fd_, &fd_set_); - - MessageLoopForIO* io_loop = MessageLoopForIO::current(); - // Watch for destruction of the BrowserThread::IO message loop so that - // the thread can be stopped cleanly. - io_loop->AddDestructionObserver(this); - return io_loop->WatchFileDescriptor( - external_fd_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); -} - -void LeopardSwitchboardThread::WillDestroyCurrentMessageLoop() { - DCHECK_EQ(MessageLoop::current(), MessageLoopForIO::current()); - watcher_.StopWatchingFileDescriptor(); - - // Send the appropriate message to end our thread, and then wait for it - // to finish before continuing. - int message = kKillThreadMessage; - write(external_fd_, &message, sizeof(message)); - Join(); -} - -void LeopardSwitchboardThread::Run() { - DCHECK(!finished_); - int nfds = std::max(internal_fd_, notify_fd_) + 1; - while (1) { - fd_set working_set; - FD_COPY(&fd_set_, &working_set); - int count = HANDLE_EINTR(select(nfds, &working_set, NULL, NULL, NULL)); - if (count < 0) { - PLOG(ERROR) << "select"; - break; - } else if (count == 0) { - DLOG(INFO) << "select timed out"; - continue; - } - if (FD_ISSET(notify_fd_, &working_set)) { - int token; - int status = HANDLE_EINTR(read(notify_fd_, &token, sizeof(token))); - if (status < 0) { - PLOG(ERROR) << "read"; - break; - } else if (status == 0) { - LOG(ERROR) << "notify fd closed"; - break; - } else if (status != sizeof(token)) { - LOG(ERROR) << "read wrong size: " << status; - break; - } else if (token == notify_fd_token_) { - LOG(ERROR) << "invalid token: " << token; - } - status = HANDLE_EINTR(write(internal_fd_, &token, sizeof(token))); - if (status < 0) { - PLOG(ERROR) << "write"; - break; - } else if (status == 0) { - LOG(ERROR) << "external_fd_ closed"; - break; - } else if (status != sizeof(token)) { - LOG(ERROR) << "write wrong size: " << status; - break; - } - } - if (FD_ISSET(internal_fd_, &working_set)) { - int value; - int status = HANDLE_EINTR(read(internal_fd_, &value, sizeof(value))); - if (status < 0) { - PLOG(ERROR) << "read"; - } else if (status == 0) { - LOG(ERROR) << "internal_fd_ closed"; - } else if (value != kKillThreadMessage) { - LOG(ERROR) << "unknown message sent: " << value; - } - break; - } - } - finished_ = true; -} - -bool LeopardSwitchboardThread::AddListener(ListenerImpl* listener, - const std::string& notification) { - DCHECK(!finished()); - base::AutoLock autolock(entries_lock_); - for (std::vector<SwitchboardEntry>::iterator i = entries_.begin(); - i < entries_.end(); ++i) { - if (i->listener_ == listener && i->notification_ == notification) { - LOG(ERROR) << "listener " << listener - << " already registered for '" << notification << "'"; - return false; - } - } - int token; - uint32_t status = notify_register_file_descriptor( - notification.c_str(), ¬ify_fd_, NOTIFY_REUSE, &token); - if (status != NOTIFY_STATUS_OK) { - LOG(ERROR) << "unable to notify_register_file_descriptor for '" - << notification << "' status: " << status; - return false; - } - SwitchboardEntry entry; - entry.token_ = token; - entry.notification_ = notification; - entry.listener_ = listener; - entries_.push_back(entry); - return true; -} - -bool LeopardSwitchboardThread::RemoveListener(ListenerImpl* listener, - const std::string& notification) { - DCHECK(!finished()); - base::AutoLock autolock(entries_lock_); - for (std::vector<SwitchboardEntry>::iterator i = entries_.begin(); - i < entries_.end(); ++i) { - if (i->listener_ == listener && i->notification_ == notification) { - uint32_t status = notify_cancel(i->token_); - DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); - entries_.erase(i); - return true; - } - } - LOG(ERROR) << "unable to remove listener '" << listener - << "' for '" << notification << "'."; - return false; -} - -void LeopardSwitchboardThread::OnFileCanReadWithoutBlocking(int fd) { - DCHECK_EQ(MessageLoop::current(), MessageLoopForIO::current()); - DCHECK_EQ(fd, external_fd_); - int token; - int status = HANDLE_EINTR(read(fd, &token, sizeof(token))); - if (status < 0) { - PLOG(ERROR) << "read"; - } else if (status == 0) { - LOG(ERROR) << "external_fd_ closed"; - } else if (status != sizeof(token)) { - LOG(ERROR) << "unexpected read size " << status; - } else { - // Have to swap to native endianness <http://openradar.appspot.com/8821081>. - token = static_cast<int>(ntohl(token)); - base::AutoLock autolock(entries_lock_); - bool found_token = false; - for (std::vector<SwitchboardEntry>::iterator i = entries_.begin(); - i < entries_.end(); ++i) { - if (i->token_ == token) { - found_token = true; - i->listener_->OnListen(); - } - } - if (!found_token) { - LOG(ERROR) << "read unknown token " << token; - } - } -} - -void LeopardSwitchboardThread::OnFileCanWriteWithoutBlocking(int fd) { - NOTREACHED(); -} - -LeopardSwitchboardThread* ListenerImpl::g_switchboard_thread_ = NULL; - -ListenerImpl::ListenerImpl( - const std::string& name, Domain domain, Listener::Delegate* delegate) - : name_(name), domain_(domain), delegate_(delegate), started_(false), - fd_(-1), token_(-1) { -} - -ListenerImpl::~ListenerImpl() { - if (started_) { - if (!UseLeopardSwitchboardThread()) { - if (fd_ != -1) { - uint32_t status = notify_cancel(token_); - DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); - } - } else { - base::AutoLock autolock(switchboard_lock_); - if (g_switchboard_thread_) { - std::string notification = AddPrefixToNotification(name_, domain_); - CHECK(g_switchboard_thread_->RemoveListener(this, notification)); - } - } - } -} - -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()) { - task = NewRunnableMethod(this, &ListenerImpl::StartLeopard); - } else { - task = NewRunnableMethod(this, &ListenerImpl::StartSnowLeopard); - } - io_loop_to_listen_on->PostTask(FROM_HERE, task); - return true; -} - -void ListenerImpl::StartLeopard() { - DCHECK(UseLeopardSwitchboardThread()); - DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); - bool success = true; - { - base::AutoLock autolock(switchboard_lock_); - if (g_switchboard_thread_ && g_switchboard_thread_->HasBeenJoined()) { - // The only time this should ever occur is in unit tests. - delete g_switchboard_thread_; - g_switchboard_thread_ = NULL; - } - DCHECK(!(g_switchboard_thread_ && g_switchboard_thread_->finished())); - if (!g_switchboard_thread_) { - g_switchboard_thread_ = new LeopardSwitchboardThread(); - success = g_switchboard_thread_->Init(); - if (success) { - g_switchboard_thread_->Start(); - } - } - if (success) { - std::string notification = AddPrefixToNotification(name_, domain_); - success = g_switchboard_thread_->AddListener(this, notification); - } - } - started_ = success; - Task* task = - new Listener::ListenerStartedTask(name_, domain_, delegate_, success); - CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); -} - -void ListenerImpl::StartSnowLeopard() { - DCHECK(!UseLeopardSwitchboardThread()); - DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); - bool success = true; - std::string notification = AddPrefixToNotification(name_, domain_); - uint32_t status = notify_register_file_descriptor( - notification.c_str(), &fd_, 0, &token_); - if (status != NOTIFY_STATUS_OK) { - LOG(ERROR) << "unable to notify_register_file_descriptor for '" - << notification << "' Status: " << status; - success = false; - } - if (success) { - MessageLoopForIO* io_loop = MessageLoopForIO::current(); - success = io_loop->WatchFileDescriptor( - fd_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); - if (!success) { - uint32_t status = notify_cancel(token_); - DCHECK_EQ(status, static_cast<uint32_t>(NOTIFY_STATUS_OK)); - fd_ = -1; - } - } - started_ = success; - Task* task = - new Listener::ListenerStartedTask(name_, domain_, delegate_, success); - CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); -} - -void ListenerImpl::OnFileCanReadWithoutBlocking(int fd) { - DCHECK(!UseLeopardSwitchboardThread()); - DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); - DCHECK_EQ(fd, fd_); - int token; - int status = HANDLE_EINTR(read(fd, &token, sizeof(token))); - if (status < 0) { - PLOG(ERROR) << "read"; - } else if (status == 0) { - LOG(ERROR) << "external_fd_ closed"; - } else if (status != sizeof(token)) { - LOG(ERROR) << "unexpected read size " << status; - } else { - // Have to swap to native endianness <http://openradar.appspot.com/8821081>. - token = static_cast<int>(ntohl(token)); - if (token == token_) { - OnListen(); - } else { - LOG(ERROR) << "unexpected value " << token; - } - } -} - -void ListenerImpl::OnListen() { - DCHECK_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); - Task* task = - new Listener::NotificationReceivedTask(name_, domain_, delegate_); - CHECK(message_loop_proxy_->PostTask(FROM_HERE, task)); -} - -void ListenerImpl::OnFileCanWriteWithoutBlocking(int fd) { - NOTREACHED(); -} - -Listener::Listener( - const std::string& name, Domain domain, Listener::Delegate* delegate) - : impl_(new ListenerImpl(name, domain, delegate)) { -} - -Listener::~Listener() { -} - -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 - -DISABLE_RUNNABLE_METHOD_REFCOUNT(multi_process_notification::ListenerImpl); diff --git a/chrome/browser/multi_process_notification_unittest.cc b/chrome/browser/multi_process_notification_unittest.cc deleted file mode 100644 index 771b05a..0000000 --- a/chrome/browser/multi_process_notification_unittest.cc +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/multi_process_notification.h" - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/environment.h" -#include "base/logging.h" -#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 "testing/multiprocess_func_list.h" - -#if defined(OS_MACOSX) -// TODO(dmaclach): Remove defined(OS_MACOSX) once -// MultiProcessNotification is implemented on Win/Linux. - -namespace { - -const char kStartedNotificationName[] = "MultiProcessTestStartedNotification"; -const char kQuitNotificationName[] = "MultiProcessTestQuitNotification"; - -void SpinRunLoop(int milliseconds) { - MessageLoop *loop = MessageLoop::current(); - - // Post a quit task so that this loop eventually ends and we don't hang - // in the case of a bad test. Usually, the run loop will quit sooner than - // that because all tests use a MultiProcessNotificationTestQuit which quits - // the current run loop when it gets a notification. - loop->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), milliseconds); - loop->Run(); -} - -class SimpleDelegate - : public multi_process_notification::Listener::Delegate { - public: - SimpleDelegate() - : notification_received_(false), started_received_(false) { } - virtual ~SimpleDelegate(); - - virtual void OnNotificationReceived( - const std::string& name, - multi_process_notification::Domain domain) OVERRIDE; - virtual void OnListenerStarted( - const std::string& name, multi_process_notification::Domain domain, - bool success) OVERRIDE; - - bool WasNotificationReceived() { return notification_received_; } - bool WasStartedReceived() { return started_received_; } - - private: - bool notification_received_; - bool started_received_; - DISALLOW_COPY_AND_ASSIGN(SimpleDelegate); -}; - -SimpleDelegate::~SimpleDelegate() { -} - -void SimpleDelegate::OnNotificationReceived( - const std::string& name, multi_process_notification::Domain domain) { - notification_received_ = true; -} - -void SimpleDelegate::OnListenerStarted( - const std::string& name, multi_process_notification::Domain domain, - bool success) { - ASSERT_TRUE(success); - started_received_ = true; - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); -} - -class QuitterDelegate : public SimpleDelegate { - public: - QuitterDelegate() : SimpleDelegate() { } - virtual ~QuitterDelegate(); - - virtual void OnNotificationReceived( - const std::string& name, - multi_process_notification::Domain domain) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(QuitterDelegate); -}; - -QuitterDelegate::~QuitterDelegate() { -} - -void QuitterDelegate::OnNotificationReceived( - const std::string& name, multi_process_notification::Domain domain) { - SimpleDelegate::OnNotificationReceived(name, domain); - MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); -} - -int MultiProcessNotificationMain(multi_process_notification::Domain domain) { - base::Thread thread("MultiProcessNotificationMainIOThread"); - base::Thread::Options options(MessageLoop::TYPE_IO, 0); - EXPECT_TRUE(thread.StartWithOptions(options)); - MessageLoop loop; - QuitterDelegate quitter; - multi_process_notification::Listener listener( - kQuitNotificationName, domain, &quitter); - EXPECT_TRUE(listener.Start(thread.message_loop())); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - EXPECT_TRUE(quitter.WasStartedReceived()); - EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName, - domain)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - EXPECT_TRUE(quitter.WasNotificationReceived()); - return 0; -} - -} // namespace - -class MultiProcessNotificationTest : public base::MultiProcessTest { - public: - MultiProcessNotificationTest(); - - void PostNotificationTest(multi_process_notification::Domain domain); - void CrossPostNotificationTest(multi_process_notification::Domain domain); - - virtual void SetUp(); - MessageLoop* IOMessageLoop() { return io_thread_.message_loop(); }; - - private: - MessageLoop loop_; - base::Thread io_thread_; -}; - -MultiProcessNotificationTest::MultiProcessNotificationTest() - : io_thread_("MultiProcessNotificationTestThread") { -} - - -void MultiProcessNotificationTest::SetUp() { - base::Thread::Options options(MessageLoop::TYPE_IO, 0); - ASSERT_TRUE(io_thread_.StartWithOptions(options)); -} - -void MultiProcessNotificationTest::PostNotificationTest( - multi_process_notification::Domain domain) { - QuitterDelegate process_started; - multi_process_notification::Listener listener( - kStartedNotificationName, domain, &process_started); - ASSERT_TRUE(listener.Start(IOMessageLoop())); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(process_started.WasStartedReceived()); - std::string process_name; - switch (domain) { - case multi_process_notification::ProfileDomain: - process_name = "MultiProcessProfileNotificationMain"; - break; - - case multi_process_notification::UserDomain: - process_name = "MultiProcessUserNotificationMain"; - break; - - case multi_process_notification::SystemDomain: - process_name = "MultiProcessSystemNotificationMain"; - break; - } - base::ProcessHandle handle = SpawnChild(process_name, false); - ASSERT_TRUE(handle); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(process_started.WasNotificationReceived()); - ASSERT_TRUE(multi_process_notification::Post(kQuitNotificationName, domain)); - int exit_code = 0; - EXPECT_TRUE(base::WaitForExitCodeWithTimeout( - handle, &exit_code, TestTimeouts::action_max_timeout_ms())); -} - -void MultiProcessNotificationTest::CrossPostNotificationTest( - multi_process_notification::Domain domain) { - // Check to make sure notifications sent to user domain aren't picked up - // by system domain listeners and vice versa. - std::string local_notification("QuitLocalNotification"); - std::string final_notification("FinalQuitLocalNotification"); - QuitterDelegate profile_quitter; - QuitterDelegate user_quitter; - QuitterDelegate system_quitter; - QuitterDelegate final_quitter; - multi_process_notification::Listener profile_listener( - local_notification, multi_process_notification::ProfileDomain, - &profile_quitter); - multi_process_notification::Listener user_listener( - local_notification, multi_process_notification::UserDomain, - &user_quitter); - multi_process_notification::Listener system_listener( - local_notification, multi_process_notification::SystemDomain, - &system_quitter); - multi_process_notification::Listener final_listener( - final_notification, multi_process_notification::UserDomain, - &final_quitter); - - 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(message_loop)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(user_quitter.WasStartedReceived()); - ASSERT_TRUE(system_listener.Start(message_loop)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(system_quitter.WasStartedReceived()); - - ASSERT_TRUE(multi_process_notification::Post(local_notification, domain)); - SpinRunLoop(TestTimeouts::action_timeout_ms()); - - // Now send out a final_notification to queue up a notification - // 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(message_loop)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - EXPECT_TRUE(final_quitter.WasStartedReceived()); - ASSERT_TRUE(multi_process_notification::Post( - final_notification, multi_process_notification::UserDomain)); - SpinRunLoop(TestTimeouts::action_timeout_ms()); - ASSERT_TRUE(final_quitter.WasNotificationReceived()); - switch (domain) { - case multi_process_notification::ProfileDomain: - ASSERT_TRUE(profile_quitter.WasNotificationReceived()); - ASSERT_FALSE(user_quitter.WasNotificationReceived()); - ASSERT_FALSE(system_quitter.WasNotificationReceived()); - break; - - case multi_process_notification::UserDomain: - ASSERT_FALSE(profile_quitter.WasNotificationReceived()); - ASSERT_TRUE(user_quitter.WasNotificationReceived()); - ASSERT_FALSE(system_quitter.WasNotificationReceived()); - break; - - case multi_process_notification::SystemDomain: - ASSERT_FALSE(profile_quitter.WasNotificationReceived()); - ASSERT_FALSE(user_quitter.WasNotificationReceived()); - ASSERT_TRUE(system_quitter.WasNotificationReceived()); - break; - } -} - -TEST_F(MultiProcessNotificationTest, BasicCreationTest) { - QuitterDelegate quitter; - multi_process_notification::Listener local_listener( - "BasicCreationTest", multi_process_notification::UserDomain, &quitter); - 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(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) { - std::string local_notification("QuitLocalNotification"); - QuitterDelegate quitter; - multi_process_notification::Listener listener( - local_notification, multi_process_notification::UserDomain, &quitter); - 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( - local_notification, multi_process_notification::UserDomain)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(quitter.WasNotificationReceived()); -} - -TEST_F(MultiProcessNotificationTest, MultiListener) { - std::string local_notification("LocalNotification"); - std::string quit_local_notification("QuitLocalNotification"); - - SimpleDelegate delegate1; - SimpleDelegate delegate2; - multi_process_notification::Listener local_listener1( - local_notification, multi_process_notification::UserDomain, - &delegate1); - multi_process_notification::Listener local_listener2( - local_notification, multi_process_notification::UserDomain, - &delegate2); - - QuitterDelegate quitter; - - multi_process_notification::Listener quit_listener(quit_local_notification, - multi_process_notification::UserDomain, &quitter); - 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(message_loop)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(delegate2.WasStartedReceived()); - ASSERT_TRUE(quit_listener.Start(message_loop)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(quitter.WasStartedReceived()); - ASSERT_TRUE(multi_process_notification::Post( - local_notification, multi_process_notification::UserDomain)); - ASSERT_TRUE(multi_process_notification::Post( - quit_local_notification, multi_process_notification::UserDomain)); - SpinRunLoop(TestTimeouts::action_max_timeout_ms()); - ASSERT_TRUE(delegate1.WasNotificationReceived()); - ASSERT_TRUE(delegate2.WasNotificationReceived()); - ASSERT_TRUE(quitter.WasNotificationReceived()); -} - -TEST_F(MultiProcessNotificationTest, PostProfileNotification) { - PostNotificationTest(multi_process_notification::ProfileDomain); -} - -TEST_F(MultiProcessNotificationTest, PostUserNotification) { - PostNotificationTest(multi_process_notification::UserDomain); -} - -TEST_F(MultiProcessNotificationTest, PostSystemNotification) { - PostNotificationTest(multi_process_notification::SystemDomain); -} - -TEST_F(MultiProcessNotificationTest, ProfileCrossDomainPosting) { - CrossPostNotificationTest(multi_process_notification::ProfileDomain); -} - -TEST_F(MultiProcessNotificationTest, UserCrossDomainPosting) { - CrossPostNotificationTest(multi_process_notification::UserDomain); -} - -TEST_F(MultiProcessNotificationTest, SystemCrossDomainPosting) { - CrossPostNotificationTest(multi_process_notification::SystemDomain); -} - -MULTIPROCESS_TEST_MAIN(MultiProcessProfileNotificationMain) { - return MultiProcessNotificationMain( - multi_process_notification::ProfileDomain); -} - -MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) { - return MultiProcessNotificationMain(multi_process_notification::UserDomain); -} - -MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) { - return MultiProcessNotificationMain(multi_process_notification::SystemDomain); -} - -#endif // defined(OS_MACOSX) diff --git a/chrome/browser/multi_process_notification_win.cc b/chrome/browser/multi_process_notification_win.cc deleted file mode 100644 index 940556f..0000000 --- a/chrome/browser/multi_process_notification_win.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/multi_process_notification.h" - -#include "base/logging.h" - -namespace multi_process_notification { - -bool Post(const std::string& name, Domain domain) { - // TODO(dmaclach): Implement - NOTIMPLEMENTED(); - return false; -} - -class ListenerImpl { - public: - ListenerImpl(const std::string& name, - Domain domain, - Listener::Delegate* delegate); - - bool Start(MessageLoop* io_loop_to_listen_on); - - std::string name() const { return name_; } - Domain domain() const { return domain_; } - - private: - std::string name_; - Domain domain_; - Listener::Delegate* delegate_; - - DISALLOW_COPY_AND_ASSIGN(ListenerImpl); -}; - -ListenerImpl::ListenerImpl(const std::string& name, - Domain domain, - Listener::Delegate* delegate) - : name_(name), domain_(domain), delegate_(delegate) { -} - -bool ListenerImpl::Start(MessageLoop* io_loop_to_listen_on) { - // TODO(dmaclach): Implement - NOTIMPLEMENTED(); - return false; -} - -Listener::Listener(const std::string& name, - Domain domain, - Listener::Delegate* delegate) - : impl_(new ListenerImpl(name, domain, delegate)) { -} - -Listener::~Listener() { -} - -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 diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 32e0fe0..17c57a3 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1543,11 +1543,6 @@ 'browser/mime_registry_message_filter.h', 'browser/modal_html_dialog_delegate.cc', 'browser/modal_html_dialog_delegate.h', - 'browser/multi_process_notification.cc', - 'browser/multi_process_notification.h', - 'browser/multi_process_notification_linux.cc', - 'browser/multi_process_notification_mac.mm', - 'browser/multi_process_notification_win.cc', 'browser/nacl_host/nacl_broker_host_win.cc', 'browser/nacl_host/nacl_broker_host_win.h', 'browser/nacl_host/nacl_broker_service_win.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 6c115b9..23149df 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1279,7 +1279,6 @@ 'browser/metrics/metrics_service_unittest.cc', 'browser/mock_plugin_exceptions_table_model.cc', 'browser/mock_plugin_exceptions_table_model.h', - 'browser/multi_process_notification_unittest.cc', 'browser/net/connection_tester_unittest.cc', 'browser/net/gaia/token_service_unittest.cc', 'browser/net/gaia/token_service_unittest.h', |