diff options
Diffstat (limited to 'ipc/glue/MiniTransceiver.h')
-rw-r--r-- | ipc/glue/MiniTransceiver.h | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/ipc/glue/MiniTransceiver.h b/ipc/glue/MiniTransceiver.h new file mode 100644 index 0000000000..9568dc2685 --- /dev/null +++ b/ipc/glue/MiniTransceiver.h @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=8 sts=4 et sw=4 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef __MINITRANSCEIVER_H_ +#define __MINITRANSCEIVER_H_ + +#include "chrome/common/ipc_message.h" +#include "mozilla/Assertions.h" + +struct msghdr; + +namespace mozilla { +namespace ipc { + +enum class DataBufferClear { None, AfterReceiving }; + +/** + * This simple implementation handles the transmissions of IPC + * messages. + * + * It works according to a strict request-response paradigm, no + * concurrent messaging is allowed. Sending a message from A to B must + * be followed by another one from B to A. Because of this we don't + * need to handle data crossing the boundaries of a + * message. Transmission is done via blocking I/O to avoid the + * complexity of asynchronous I/O. + */ +class MiniTransceiver { + public: + /** + * \param aFd should be a blocking, no O_NONBLOCK, fd. + * \param aClearDataBuf is true to clear data buffers after + * receiving a message. + */ + explicit MiniTransceiver( + int aFd, DataBufferClear aDataBufClear = DataBufferClear::None); + + bool Send(IPC::Message& aMsg); + inline bool SendInfallible(IPC::Message& aMsg, const char* aCrashMessage) { + bool Ok = Send(aMsg); + if (!Ok) { + MOZ_CRASH_UNSAFE(aCrashMessage); + } + return Ok; + } + + /** + * \param aMsg will hold the content of the received message. + * \return false if the fd is closed or with an error. + */ + bool Recv(UniquePtr<IPC::Message>& aMsg); + inline bool RecvInfallible(UniquePtr<IPC::Message>& aMsg, + const char* aCrashMessage) { + bool Ok = Recv(aMsg); + if (!Ok) { + MOZ_CRASH_UNSAFE(aCrashMessage); + } + return Ok; + } + + int GetFD() { return mFd; } + + private: + /** + * Set control buffer to make file descriptors ready to be sent + * through a socket. + */ + void PrepareFDs(msghdr* aHdr, IPC::Message& aMsg); + /** + * Collect buffers of the message and make them ready to be sent. + * + * \param aHdr is the structure going to be passed to sendmsg(). + * \param aMsg is the Message to send. + */ + size_t PrepareBuffers(msghdr* aHdr, IPC::Message& aMsg); + /** + * Collect file descriptors received. + * + * \param aAllFds is where to store file descriptors. + * \param aMaxFds is how many file descriptors can be stored in aAllFds. + * \return the number of received file descriptors. + */ + unsigned RecvFDs(msghdr* aHdr, int* aAllFds, unsigned aMaxFds); + /** + * Received data from the socket. + * + * \param aDataBuf is where to store the data from the socket. + * \param aBufSize is the size of the buffer. + * \param aMsgSize returns how many bytes were readed from the socket. + * \param aFdsBuf is the buffer to return file desriptors received. + * \param aMaxFds is the number of file descriptors that can be held. + * \param aNumFds returns the number of file descriptors received. + * \return true if sucess, or false for error. + */ + bool RecvData(char* aDataBuf, size_t aBufSize, uint32_t* aMsgSize, + int* aFdsBuf, unsigned aMaxFds, unsigned* aNumFds); + + int mFd; // The file descriptor of the socket for IPC. + +#ifdef DEBUG + enum State { + STATE_NONE, + STATE_SENDING, + STATE_RECEIVING, + }; + State mState; +#endif + + // Clear all received data in temp buffers to avoid data leaking. + DataBufferClear mDataBufClear; +}; + +} // namespace ipc +} // namespace mozilla + +#endif // __MINITRANSCEIVER_H_ |