Replace MSG_PEEK with a pre-received data interface.
[folly.git] / folly / io / async / AsyncSocket.h
index 54b37705ae9b5879107485756fea1ed7df5f02e7..3e2adbce0f71a5e839b29f7016bbe26ab22ac451 100644 (file)
@@ -189,6 +189,14 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
    */
   AsyncSocket(EventBase* evb, int fd);
 
    */
   AsyncSocket(EventBase* evb, int fd);
 
+  /**
+   * Create an AsyncSocket from a different, already connected AsyncSocket.
+   *
+   * Similar to AsyncSocket(evb, fd) when fd was previously owned by an
+   * AsyncSocket.
+   */
+  explicit AsyncSocket(AsyncSocket::UniquePtr);
+
   /**
    * Helper function to create a shared_ptr<AsyncSocket>.
    *
   /**
    * Helper function to create a shared_ptr<AsyncSocket>.
    *
@@ -264,6 +272,10 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
    * error.  The AsyncSocket may no longer be used after the file descriptor
    * has been extracted.
    *
    * error.  The AsyncSocket may no longer be used after the file descriptor
    * has been extracted.
    *
+   * This method should be used with care as the resulting fd is not guaranteed
+   * to perfectly reflect the state of the AsyncSocket (security state,
+   * pre-received data, etc.).
+   *
    * Returns the file descriptor.  The caller assumes ownership of the
    * descriptor, and it will not be closed when the AsyncSocket is destroyed.
    */
    * Returns the file descriptor.  The caller assumes ownership of the
    * descriptor, and it will not be closed when the AsyncSocket is destroyed.
    */
@@ -601,8 +613,16 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
     return setsockopt(fd_, level, optname, optval, sizeof(T));
   }
 
     return setsockopt(fd_, level, optname, optval, sizeof(T));
   }
 
-  virtual void setPeek(bool peek) {
-    peek_ = peek;
+  /**
+   * Set pre-received data, to be returned to read callback before any data
+   * from the socket.
+   */
+  virtual void setPreReceivedData(std::unique_ptr<IOBuf> data) {
+    if (preReceivedData_) {
+      preReceivedData_->prependChain(std::move(data));
+    } else {
+      preReceivedData_ = std::move(data);
+    }
   }
 
   /**
   }
 
   /**
@@ -998,7 +1018,9 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
   size_t appBytesWritten_;               ///< Num of bytes written to socket
   bool isBufferMovable_{false};
 
   size_t appBytesWritten_;               ///< Num of bytes written to socket
   bool isBufferMovable_{false};
 
-  bool peek_{false}; // Peek bytes.
+  // Pre-received data, to be returned to read callback before any data from the
+  // socket.
+  std::unique_ptr<IOBuf> preReceivedData_;
 
   int8_t readErr_{READ_NO_ERROR};       ///< The read error encountered, if any.
 
 
   int8_t readErr_{READ_NO_ERROR};       ///< The read error encountered, if any.