15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPC_IPC_SYNC_MESSAGE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_IPC_SYNC_MESSAGE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WaitableEvent;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageReplyDeserializer;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPC_EXPORT SyncMessage : public Message {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SyncMessage(int32 routing_id, uint32 type, PriorityValue priority,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              MessageReplyDeserializer* deserializer);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SyncMessage();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this to get a deserializer for the output parameters.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that this can only be called once, and the caller is responsible
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for deleting the deserializer when they're done.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReplyDeserializer* GetReplyDeserializer();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this message can cause the receiver to block while waiting for user
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // input (i.e. by calling MessageBox), then the caller needs to pump window
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // messages and dispatch asynchronous messages while waiting for the reply.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this event is passed in, then window messages will start being pumped
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when it's set.  Note that this behavior will continue even if the event is
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // later reset.  The event must be valid until after the Send call returns.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_pump_messages_event(base::WaitableEvent* event) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pump_messages_event_ = event;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header()->flags |= PUMPING_MSGS_BIT;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      header()->flags &= ~PUMPING_MSGS_BIT;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this if you always want to pump messages.  You can call this method
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or set_pump_messages_event but not both.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnableMessagePumping();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* pump_messages_event() const {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pump_messages_event_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the message is a reply to the given request id.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsMessageReplyTo(const Message& msg, int request_id);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a reply message, returns an iterator to the beginning of the data
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (i.e. skips over the synchronous specific data).
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static PickleIterator GetDataIterator(const Message* msg);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given a synchronous message (or its reply), returns its id.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int GetMessageId(const Message& msg);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generates a reply message to the given message.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static Message* GenerateReply(const Message* msg);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SyncHeader {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // unique ID (unique per sender)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int message_id;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ReadSyncHeader(const Message& msg, SyncHeader* header);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool WriteSyncHeader(Message* msg, const SyncHeader& header);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MessageReplyDeserializer> deserializer_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* pump_messages_event_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used to deserialize parameters from a reply to a synchronous message
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPC_EXPORT MessageReplyDeserializer {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MessageReplyDeserializer() {}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SerializeOutputParameters(const Message& msg);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Derived classes need to implement this, using the given iterator (which
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is skipped past the header for synchronous messages).
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SerializeOutputParameters(const Message& msg,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         PickleIterator iter) = 0;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When sending a synchronous message, this structure contains an object
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that knows how to deserialize the response.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PendingSyncMsg {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSyncMsg(int id,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 MessageReplyDeserializer* d,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::WaitableEvent* e)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : id(id), deserializer(d), done_event(e), send_result(false) { }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int id;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageReplyDeserializer* deserializer;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* done_event;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool send_result;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace IPC
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // IPC_IPC_SYNC_MESSAGE_H_
112