summaryrefslogtreecommitdiffstats
path: root/chrome_frame/sync_msg_reply_dispatcher.h
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/sync_msg_reply_dispatcher.h
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/sync_msg_reply_dispatcher.h')
-rw-r--r--chrome_frame/sync_msg_reply_dispatcher.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/chrome_frame/sync_msg_reply_dispatcher.h b/chrome_frame/sync_msg_reply_dispatcher.h
new file mode 100644
index 0000000..05e5162
--- /dev/null
+++ b/chrome_frame/sync_msg_reply_dispatcher.h
@@ -0,0 +1,96 @@
+// Copyright (c) 2009 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_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_
+#define CHROME_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_
+
+#include <deque>
+
+#include "base/lock.h"
+#include "ipc/ipc_channel_proxy.h"
+
+// Base class used to allow synchronous IPC messages to be sent and
+// received in an asynchronous manner. To use this class add it as a filter to
+// your IPC channel using ChannelProxy::AddFilter(). From then on, before
+// sending a synchronous message, call SyncMessageReplyDispatcher::Push() with
+// a callback and a key. This class will then handle the message response and
+// will call the callback when it is received.
+//
+// This class is intended to be extended by classes implementing
+// HandleMessageType with delegation for the messages they expect to receive in
+// cases where you care about the return values of synchronous messages.
+//
+// Sample usage pattern:
+//
+// // Add handling for desired message types.
+// class SyncMessageReplyDispatcherImpl : public SyncMessageReplyDispatcher {
+// virtual bool HandleMessageType(const IPC::Message& msg,
+// const MessageSent& origin) {
+// switch (origin.type) {
+// case AutomationMsg_CreateExternalTab::ID:
+// InvokeCallback<Tuple3<HWND, HWND, int> >(msg, origin);
+// break;
+// [HANDLING FOR OTHER EXPECTED MESSAGE TYPES]
+// }
+// }
+//
+// // Add the filter
+// IPC::SyncChannel channel_;
+// channel_.AddFilter(new SyncMessageReplyDispatcherImpl());
+//
+// sync_->Push(msg, NewCallback(this, CallbackMethod, this);
+// channel_->ChannelProxy::Send(msg);
+//
+class SyncMessageReplyDispatcher : public IPC::ChannelProxy::MessageFilter {
+ public:
+ SyncMessageReplyDispatcher() {}
+ void Push(IPC::SyncMessage* msg, void* callback, void* key);
+ void Cancel(void* key);
+
+ protected:
+ struct MessageSent {
+ MessageSent() {}
+ MessageSent(int id, uint16 type, void* callback, void* key)
+ : id(id), callback(callback), type(type), key(key) {}
+ int id;
+ void* callback;
+ void* key;
+ uint16 type;
+ };
+
+ typedef std::deque<MessageSent> PendingSyncMessageQueue;
+
+ bool Pop(const IPC::Message& msg, MessageSent* t);
+ virtual bool OnMessageReceived(const IPC::Message& msg);
+
+ // Child classes must implement a handler for the message types they are
+ // interested in handling responses for. If you don't care about the replies
+ // to any of the sync messages you are handling, then you don't have to
+ // implement this.
+ virtual bool HandleMessageType(const IPC::Message& msg,
+ const MessageSent& origin);
+
+ template <typename T>
+ void InvokeCallback(const IPC::Message& msg, const MessageSent& origin) {
+ // Ensure we delete the callback
+ scoped_ptr<CallbackRunner<T> > c(
+ reinterpret_cast<CallbackRunner<T>*>(origin.callback));
+ if (origin.key == NULL) { // Canceled
+ return;
+ }
+
+ T tmp; // Acts as "initializer" for output parameters.
+ IPC::ParamDeserializer<T> deserializer(tmp);
+ if (deserializer.MessageReplyDeserializer::SerializeOutputParameters(msg)) {
+ c->RunWithParams(deserializer.out_);
+ } else {
+ // TODO(stoyan): How to handle errors?
+ }
+ }
+
+ PendingSyncMessageQueue message_queue_;
+ Lock message_queue_lock_;
+};
+
+#endif // CHROME_FRAME_SYNC_MSG_REPLY_DISPATCHER_H_