MiniTransceiver.h (3647B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* vim: set ts=8 sts=4 et sw=4 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef __MINITRANSCEIVER_H_ 7 #define __MINITRANSCEIVER_H_ 8 9 #include "chrome/common/ipc_message.h" 10 11 struct msghdr; 12 13 namespace mozilla { 14 namespace ipc { 15 16 enum class DataBufferClear { None, AfterReceiving }; 17 18 /** 19 * This simple implementation handles the transmissions of IPC 20 * messages. 21 * 22 * It works according to a strict request-response paradigm, no 23 * concurrent messaging is allowed. Sending a message from A to B must 24 * be followed by another one from B to A. Because of this we don't 25 * need to handle data crossing the boundaries of a 26 * message. Transmission is done via blocking I/O to avoid the 27 * complexity of asynchronous I/O. 28 */ 29 class MiniTransceiver { 30 public: 31 /** 32 * \param aFd should be a blocking, no O_NONBLOCK, fd. 33 * \param aClearDataBuf is true to clear data buffers after 34 * receiving a message. 35 */ 36 explicit MiniTransceiver( 37 int aFd, DataBufferClear aDataBufClear = DataBufferClear::None); 38 39 bool Send(IPC::Message& aMsg); 40 inline bool SendInfallible(IPC::Message& aMsg, const char* aCrashMessage) { 41 bool Ok = Send(aMsg); 42 if (!Ok) { 43 MOZ_CRASH_UNSAFE(aCrashMessage); 44 } 45 return Ok; 46 } 47 48 /** 49 * \param aMsg will hold the content of the received message. 50 * \return false if the fd is closed or with an error. 51 */ 52 bool Recv(UniquePtr<IPC::Message>& aMsg); 53 inline bool RecvInfallible(UniquePtr<IPC::Message>& aMsg, 54 const char* aCrashMessage) { 55 bool Ok = Recv(aMsg); 56 if (!Ok) { 57 MOZ_CRASH_UNSAFE(aCrashMessage); 58 } 59 return Ok; 60 } 61 62 int GetFD() { return mFd; } 63 64 private: 65 /** 66 * Set control buffer to make file descriptors ready to be sent 67 * through a socket. 68 */ 69 void PrepareFDs(msghdr* aHdr, IPC::Message& aMsg); 70 /** 71 * Collect buffers of the message and make them ready to be sent. 72 * 73 * \param aHdr is the structure going to be passed to sendmsg(). 74 * \param aMsg is the Message to send. 75 */ 76 size_t PrepareBuffers(msghdr* aHdr, IPC::Message& aMsg); 77 /** 78 * Collect file descriptors received. 79 * 80 * \param aAllFds is where to store file descriptors. 81 * \param aMaxFds is how many file descriptors can be stored in aAllFds. 82 * \return the number of received file descriptors. 83 */ 84 unsigned RecvFDs(msghdr* aHdr, int* aAllFds, unsigned aMaxFds); 85 /** 86 * Received data from the socket. 87 * 88 * \param aDataBuf is where to store the data from the socket. 89 * \param aBufSize is the size of the buffer. 90 * \param aMsgSize returns how many bytes were readed from the socket. 91 * \param aFdsBuf is the buffer to return file desriptors received. 92 * \param aMaxFds is the number of file descriptors that can be held. 93 * \param aNumFds returns the number of file descriptors received. 94 * \return true if sucess, or false for error. 95 */ 96 bool RecvData(char* aDataBuf, size_t aBufSize, uint32_t* aMsgSize, 97 int* aFdsBuf, unsigned aMaxFds, unsigned* aNumFds); 98 99 int mFd; // The file descriptor of the socket for IPC. 100 101 #ifdef DEBUG 102 enum State { 103 STATE_NONE, 104 STATE_SENDING, 105 STATE_RECEIVING, 106 }; 107 State mState; 108 #endif 109 110 // Clear all received data in temp buffers to avoid data leaking. 111 DataBufferClear mDataBufClear; 112 }; 113 114 } // namespace ipc 115 } // namespace mozilla 116 117 #endif // __MINITRANSCEIVER_H_