diff options
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/child_thread.cc | 9 | ||||
-rw-r--r-- | chrome/common/child_thread.h | 11 | ||||
-rw-r--r-- | chrome/common/database_util.cc | 78 | ||||
-rw-r--r-- | chrome/common/db_message_filter.cc | 55 | ||||
-rw-r--r-- | chrome/common/db_message_filter.h | 124 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 34 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 46 |
7 files changed, 82 insertions, 275 deletions
diff --git a/chrome/common/child_thread.cc b/chrome/common/child_thread.cc index 877a3af..91d276e 100644 --- a/chrome/common/child_thread.cc +++ b/chrome/common/child_thread.cc @@ -13,6 +13,7 @@ #include "chrome/common/socket_stream_dispatcher.h" #include "ipc/ipc_logging.h" #include "ipc/ipc_message.h" +#include "ipc/ipc_sync_message_filter.h" #include "ipc/ipc_switches.h" #include "webkit/glue/webkit_glue.h" @@ -49,6 +50,10 @@ void ChildThread::Init() { resource_dispatcher_.reset(new ResourceDispatcher(this)); socket_stream_dispatcher_.reset(new SocketStreamDispatcher()); + sync_message_filter_ = + new IPC::SyncMessageFilter(ChildProcess::current()->GetShutDownEvent()); + channel_->AddFilter(sync_message_filter_.get()); + // When running in unit tests, there is already a NotificationService object. // Since only one can exist at a time per thread, check first. if (!NotificationService::current()) @@ -60,6 +65,8 @@ ChildThread::~ChildThread() { IPC::Logging::current()->SetIPCSender(NULL); #endif + channel_->RemoveFilter(sync_message_filter_.get()); + // The ChannelProxy object caches a pointer to the IPC thread, so need to // reset it as it's not guaranteed to outlive this object. // NOTE: this also has the side-effect of not closing the main IPC channel to @@ -126,7 +133,7 @@ void ChildThread::OnMessageReceived(const IPC::Message& msg) { #if defined(IPC_MESSAGE_LOG_ENABLED) IPC_MESSAGE_HANDLER(PluginProcessMsg_SetIPCLoggingEnabled, OnSetIPCLoggingEnabled) -#endif // IPC_MESSAGE_HANDLER +#endif IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h index ee05e11..72af5aa 100644 --- a/chrome/common/child_thread.h +++ b/chrome/common/child_thread.h @@ -15,6 +15,10 @@ class NotificationService; class SocketStreamDispatcher; +namespace IPC { +class SyncMessageFilter; +} + // The main thread of a child process derives from this class. class ChildThread : public IPC::Channel::Listener, public IPC::Message::Sender { @@ -49,6 +53,10 @@ class ChildThread : public IPC::Channel::Listener, return socket_stream_dispatcher_.get(); } + // Safe to call on any thread, as long as it's guaranteed that the thread's + // lifetime is less than the main thread. + IPC::SyncMessageFilter* sync_message_filter() { return sync_message_filter_; } + MessageLoop* message_loop() { return message_loop_; } // Returns the one child thread. @@ -84,6 +92,9 @@ class ChildThread : public IPC::Channel::Listener, std::string channel_name_; scoped_ptr<IPC::SyncChannel> channel_; + // Allows threads other than the main thread to send sync messages. + scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_; + // Implements message routing functionality to the consumers of ChildThread. MessageRouter router_; diff --git a/chrome/common/database_util.cc b/chrome/common/database_util.cc index 7a54724..f149f08 100644 --- a/chrome/common/database_util.cc +++ b/chrome/common/database_util.cc @@ -10,8 +10,9 @@ #include "third_party/sqlite/preprocessed/sqlite3.h" #endif -#include "chrome/common/db_message_filter.h" +#include "chrome/common/child_thread.h" #include "chrome/common/render_messages.h" +#include "ipc/ipc_sync_message_filter.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebKitClient; @@ -20,58 +21,59 @@ using WebKit::WebString; WebKitClient::FileHandle DatabaseUtil::databaseOpenFile( const WebString& vfs_file_name, int desired_flags, WebKitClient::FileHandle* dir_handle) { - DBMessageFilter* db_message_filter = DBMessageFilter::GetInstance(); - int message_id = db_message_filter->GetUniqueID(); - + IPC::PlatformFileForTransit file_handle; #if defined(OS_WIN) - ViewMsg_DatabaseOpenFileResponse_Params default_response = - { base::kInvalidPlatformFileValue }; + file_handle = base::kInvalidPlatformFileValue; #elif defined(OS_POSIX) - ViewMsg_DatabaseOpenFileResponse_Params default_response = - { base::FileDescriptor(base::kInvalidPlatformFileValue, true), - base::FileDescriptor(base::kInvalidPlatformFileValue, true) }; + file_handle = + base::FileDescriptor(base::kInvalidPlatformFileValue, true); + base::FileDescriptor dir_handle_rv = + base::FileDescriptor(base::kInvalidPlatformFileValue, true); #endif - ViewMsg_DatabaseOpenFileResponse_Params result = - db_message_filter->SendAndWait( - new ViewHostMsg_DatabaseOpenFile( - vfs_file_name, desired_flags, message_id), - message_id, default_response); + scoped_refptr<IPC::SyncMessageFilter> filter = + ChildThread::current()->sync_message_filter(); + + filter->Send(new ViewHostMsg_DatabaseOpenFile( + vfs_file_name, + desired_flags, + &file_handle +#if defined(OS_POSIX) + , &dir_handle_rv +#endif + )); #if defined(OS_WIN) - if (dir_handle) - *dir_handle = base::kInvalidPlatformFileValue; - return result.file_handle; + return file_handle; #elif defined(OS_POSIX) if (dir_handle) - *dir_handle = result.dir_handle.fd; - return result.file_handle.fd; + *dir_handle = dir_handle_rv.fd; + return file_handle.fd; #endif } int DatabaseUtil::databaseDeleteFile( const WebString& vfs_file_name, bool sync_dir) { - DBMessageFilter* db_message_filter = DBMessageFilter::GetInstance(); - int message_id = db_message_filter->GetUniqueID(); - return db_message_filter->SendAndWait( - new ViewHostMsg_DatabaseDeleteFile(vfs_file_name, sync_dir, message_id), - message_id, SQLITE_IOERR_DELETE); + int rv = SQLITE_IOERR_DELETE; + scoped_refptr<IPC::SyncMessageFilter> filter = + ChildThread::current()->sync_message_filter(); + filter->Send(new ViewHostMsg_DatabaseDeleteFile( + vfs_file_name, sync_dir, &rv)); + return rv; } -long DatabaseUtil::databaseGetFileAttributes( - const WebString& vfs_file_name) { - DBMessageFilter* db_message_filter = DBMessageFilter::GetInstance(); - int message_id = db_message_filter->GetUniqueID(); - return db_message_filter->SendAndWait( - new ViewHostMsg_DatabaseGetFileAttributes(vfs_file_name, message_id), - message_id, -1L); +long DatabaseUtil::databaseGetFileAttributes(const WebString& vfs_file_name) { + int32 rv = -1; + scoped_refptr<IPC::SyncMessageFilter> filter = + ChildThread::current()->sync_message_filter(); + filter->Send(new ViewHostMsg_DatabaseGetFileAttributes(vfs_file_name, &rv)); + return rv; } -long long DatabaseUtil::databaseGetFileSize( - const WebString& vfs_file_name) { - DBMessageFilter* db_message_filter = DBMessageFilter::GetInstance(); - int message_id = db_message_filter->GetUniqueID(); - return db_message_filter->SendAndWait( - new ViewHostMsg_DatabaseGetFileSize(vfs_file_name, message_id), - message_id, 0LL); +long long DatabaseUtil::databaseGetFileSize(const WebString& vfs_file_name) { + int64 rv = 0LL; + scoped_refptr<IPC::SyncMessageFilter> filter = + ChildThread::current()->sync_message_filter(); + filter->Send(new ViewHostMsg_DatabaseGetFileSize(vfs_file_name, &rv)); + return rv; } diff --git a/chrome/common/db_message_filter.cc b/chrome/common/db_message_filter.cc index 39c4120..8e3bbc6 100644 --- a/chrome/common/db_message_filter.cc +++ b/chrome/common/db_message_filter.cc @@ -1,69 +1,18 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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/common/db_message_filter.h" -#include "chrome/common/child_process.h" #include "chrome/common/render_messages.h" #include "third_party/WebKit/WebKit/chromium/public/WebDatabase.h" -DBMessageFilter* DBMessageFilter::instance_ = NULL; - -DBMessageFilter::DBMessageFilter() - : io_thread_message_loop_(ChildProcess::current()->io_message_loop()), - channel_(NULL), - shutdown_event_(ChildProcess::current()->GetShutDownEvent()), - messages_awaiting_replies_(new IDMap<DBMessageState>()), - unique_id_generator_(new base::AtomicSequenceNumber()) { - DCHECK(!instance_); - instance_ = this; -} - -int DBMessageFilter::GetUniqueID() { - return unique_id_generator_->GetNext(); -} - -static void SendMessageOnIOThread(IPC::Message* message, - IPC::Channel* channel, - Lock* channel_lock) { - AutoLock channel_auto_lock(*channel_lock); - if (channel) - channel->Send(message); - else - delete message; -} - -void DBMessageFilter::Send(IPC::Message* message) { - io_thread_message_loop_->PostTask(FROM_HERE, - NewRunnableFunction(SendMessageOnIOThread, message, channel_, - &channel_lock_)); -} - -void DBMessageFilter::OnFilterAdded(IPC::Channel* channel) { - AutoLock channel_auto_lock(channel_lock_); - channel_ = channel; -} - -void DBMessageFilter::OnChannelError() { - AutoLock channel_auto_lock(channel_lock_); - channel_ = NULL; -} - -void DBMessageFilter::OnChannelClosing() { - AutoLock channel_auto_lock(channel_lock_); - channel_ = NULL; +DBMessageFilter::DBMessageFilter() { } bool DBMessageFilter::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(DBMessageFilter, message) - IPC_MESSAGE_HANDLER(ViewMsg_DatabaseOpenFileResponse, - OnResponse<ViewMsg_DatabaseOpenFileResponse_Params>) - IPC_MESSAGE_HANDLER(ViewMsg_DatabaseDeleteFileResponse, OnResponse<int>) - IPC_MESSAGE_HANDLER(ViewMsg_DatabaseGetFileAttributesResponse, - OnResponse<uint32>) - IPC_MESSAGE_HANDLER(ViewMsg_DatabaseGetFileSizeResponse, OnResponse<int64>) IPC_MESSAGE_HANDLER(ViewMsg_DatabaseUpdateSize, OnDatabaseUpdateSize) IPC_MESSAGE_HANDLER(ViewMsg_DatabaseCloseImmediately, OnDatabaseCloseImmediately) diff --git a/chrome/common/db_message_filter.h b/chrome/common/db_message_filter.h index 41967a0..1cb07d8 100644 --- a/chrome/common/db_message_filter.h +++ b/chrome/common/db_message_filter.h @@ -1,143 +1,27 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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_COMMON_DB_MESSAGE_FILTER_H_ #define CHROME_COMMON_DB_MESSAGE_FILTER_H_ -#include "base/atomic_sequence_num.h" -#include "base/id_map.h" -#include "base/lock.h" -#include "base/scoped_ptr.h" -#include "base/waitable_event.h" #include "ipc/ipc_channel_proxy.h" -class Lock; -class MessageLoop; - -namespace IPC { -class Channel; -} - -// A thread-safe message filter used to send IPCs from DB threads and process -// replies from the browser process. -// -// This class should not be instantianted anywhere but RenderThread::Init(). It -// is meant to be a singleton in each renderer process. To access the singleton, -// use GetInstance(). +// Receives database messages from the browser process and processes them on the +// IO thread. class DBMessageFilter : public IPC::ChannelProxy::MessageFilter { public: - // Returns the DBMessageFilter singleton created in this renderer process. - static DBMessageFilter* GetInstance() { return instance_; } - - // Creates a new DBMessageFilter instance. DBMessageFilter(); - // Returns a unique ID for use when calling the SendAndWait() method. - virtual int GetUniqueID(); - - // Posts a task to the IO thread to send |message| to the browser. - virtual void Send(IPC::Message* message); - - // Sends |message| and blocks the current thread. Returns the result from the - // reply message, or |default_result| if the renderer process is being - // destroyed or the message could not be sent. - template<class ResultType> - ResultType SendAndWait(IPC::Message* message, - int message_id, - ResultType default_result) { - ResultType result = default_result; - base::WaitableEvent waitable_event(false, false); - DBMessageState state = - { reinterpret_cast<intptr_t>(&result), &waitable_event }; - { - AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); - messages_awaiting_replies_->AddWithID(&state, message_id); - } - - Send(message); - - base::WaitableEvent* events[2] = { shutdown_event_, &waitable_event }; - base::WaitableEvent::WaitMany(events, 2); - - // Locking on messages_awaiting_replies_ guarantees that either the IO - // thread won't enter OnResponse(), or if it's already in OnResponse(), - // then WaitableEvent::Signal() will get a chance to do all its work - // before waitable_event is deleted. - AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); - messages_awaiting_replies_->Remove(message_id); - return result; - } - - // Processes incoming message |message| from the browser process. - virtual bool OnMessageReceived(const IPC::Message& message); - private: - // The state we store for each message we send. - struct DBMessageState { - intptr_t result_address_; - base::WaitableEvent* waitable_event_; - }; - - // This is a RefCounted class, do not allow anybody to destroy it directly. - virtual ~DBMessageFilter() { instance_ = NULL; } - - // Invoked when this filter is added to |channel|. - virtual void OnFilterAdded(IPC::Channel* channel); - - // Called when the channel encounters a problem. The filter should clean up - // its internal data and not accept any more messages. - virtual void OnChannelError(); - - // Called when the channel is closing. The filter should clean up its internal - // and not accept any more messages. - virtual void OnChannelClosing(); - - // Processes the reply to a sync DB request. - template<class ResultType> - void OnResponse(int32 message_id, ResultType result) { - AutoLock msgs_awaiting_replies_autolock(messages_awaiting_replies_lock_); - DBMessageState *state = messages_awaiting_replies_->Lookup(message_id); - if (state) { - *reinterpret_cast<ResultType*>(state->result_address_) = result; - state->waitable_event_->Signal(); - } - } + virtual bool OnMessageReceived(const IPC::Message& message); - // Processes IPCs that indicate a change in the size of a DB file. void OnDatabaseUpdateSize(const string16& origin_identifier, const string16& database_name, int64 database_size, int64 space_available); - - // Processes IPCs that ask for a DB to be closed immediately. void OnDatabaseCloseImmediately(const string16& origin_identifier, const string16& database_name); - - // The message loop for the IO thread. - MessageLoop* io_thread_message_loop_; - - // The channel to which this filter was added. - IPC::Channel* channel_; - - // A lock around the channel. - Lock channel_lock_; - - // The shutdown event. - base::WaitableEvent* shutdown_event_; - - // The list of messages awaiting replies. For each such message we store a - // DBMessageState instance. - scoped_ptr<IDMap<DBMessageState> > messages_awaiting_replies_; - - // The lock for 'messages_awaiting_replies_'. - Lock messages_awaiting_replies_lock_; - - // A thread-safe unique number generator. - scoped_ptr<base::AtomicSequenceNumber> unique_id_generator_; - - // The singleton. - static DBMessageFilter* instance_; }; #endif // CHROME_COMMON_DB_MESSAGE_FILTER_H_ diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index a2db04f..211297a 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -422,13 +422,6 @@ struct ViewMsg_PrintPages_Params { std::vector<int> pages; }; -struct ViewMsg_DatabaseOpenFileResponse_Params { - IPC::PlatformFileForTransit file_handle; // DB file handle -#if defined(OS_POSIX) - base::FileDescriptor dir_handle; // DB directory handle -#endif -}; - // Parameters to describe a rendered page. struct ViewHostMsg_DidPrintPage_Params { // A shared memory handle to the EMF data. This data can be quite large so a @@ -2038,33 +2031,6 @@ struct ParamTraits<ViewMsg_StopFinding_Params> { }; template <> -struct ParamTraits<ViewMsg_DatabaseOpenFileResponse_Params> { - typedef ViewMsg_DatabaseOpenFileResponse_Params param_type; - static void Write(Message* m, const param_type& p) { - WriteParam(m, p.file_handle); -#if defined(OS_POSIX) - WriteParam(m, p.dir_handle); -#endif - } - static bool Read(const Message* m, void** iter, param_type* p) { - bool ret = ReadParam(m, iter, &p->file_handle); -#if defined(OS_POSIX) - ret = ret && ReadParam(m, iter, &p->dir_handle); -#endif - return ret; - } - static void Log(const param_type& p, std::wstring* l) { - l->append(L"("); - LogParam(p.file_handle, l); -#if defined(OS_POSIX) - l->append(L", "); - LogParam(p.dir_handle, l); -#endif - l->append(L")"); - } -}; - -template <> struct ParamTraits<appcache::Status> { typedef appcache::Status param_type; static void Write(Message* m, const param_type& p) { diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 5730588..b1222f1 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -821,26 +821,6 @@ IPC_BEGIN_MESSAGES(View) IPC_MESSAGE_ROUTED1(ViewMsg_ExecuteCode, ViewMsg_ExecuteCode_Params) - // Returns a file handle - IPC_MESSAGE_CONTROL2(ViewMsg_DatabaseOpenFileResponse, - int32 /* the ID of the message we're replying to */, - ViewMsg_DatabaseOpenFileResponse_Params) - - // Returns a SQLite error code - IPC_MESSAGE_CONTROL2(ViewMsg_DatabaseDeleteFileResponse, - int32 /* the ID of the message we're replying to */, - int /* SQLite error code */) - - // Returns the attributes of a file - IPC_MESSAGE_CONTROL2(ViewMsg_DatabaseGetFileAttributesResponse, - int32 /* the ID of the message we're replying to */, - int32 /* the attributes for the given DB file */) - - // Returns the size of a file - IPC_MESSAGE_CONTROL2(ViewMsg_DatabaseGetFileSizeResponse, - int32 /* the ID of the message we're replying to */, - int64 /* the size of the given DB file */) - // Notifies the child process of the new database size IPC_MESSAGE_CONTROL4(ViewMsg_DatabaseUpdateSize, string16 /* the origin */, @@ -2126,27 +2106,35 @@ IPC_BEGIN_MESSAGES(ViewHost) unsigned long /* estimated size */, bool /* result */) - // Asks the browser process to open a DB file with the given name - IPC_MESSAGE_CONTROL3(ViewHostMsg_DatabaseOpenFile, + // Asks the browser process to open a DB file with the given name. +#if defined (OS_WIN) + IPC_SYNC_MESSAGE_CONTROL2_1(ViewHostMsg_DatabaseOpenFile, + string16 /* vfs file name */, + int /* desired flags */, + IPC::PlatformFileForTransit /* file_handle */) +#elif defined(OS_POSIX) + IPC_SYNC_MESSAGE_CONTROL2_2(ViewHostMsg_DatabaseOpenFile, string16 /* vfs file name */, int /* desired flags */, - int32 /* a unique message ID */) + IPC::PlatformFileForTransit /* file_handle */, + base::FileDescriptor /* dir_handle */) +#endif // Asks the browser process to delete a DB file - IPC_MESSAGE_CONTROL3(ViewHostMsg_DatabaseDeleteFile, + IPC_SYNC_MESSAGE_CONTROL2_1(ViewHostMsg_DatabaseDeleteFile, string16 /* vfs file name */, bool /* whether or not to sync the directory */, - int32 /* a unique message ID */) + int /* SQLite error code */) // Asks the browser process to return the attributes of a DB file - IPC_MESSAGE_CONTROL2(ViewHostMsg_DatabaseGetFileAttributes, + IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_DatabaseGetFileAttributes, string16 /* vfs file name */, - int32 /* a unique message ID */) + int32 /* the attributes for the given DB file */) // Asks the browser process to return the size of a DB file - IPC_MESSAGE_CONTROL2(ViewHostMsg_DatabaseGetFileSize, + IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_DatabaseGetFileSize, string16 /* vfs file name */, - int32 /* a unique message ID */) + int64 /* the size of the given DB file */) // Notifies the browser process that a new database has been opened IPC_MESSAGE_CONTROL4(ViewHostMsg_DatabaseOpened, |