1 // Copyright (C) 2021 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 #include <stdint.h> // for uint64_t, uint8_t 16 #include <sys/types.h> // for ssize_t 17 18 #include <atomic> // for atomic_bool 19 20 #include "net/async_data_channel.h" // for AsyncDataChannel, ReadCallback 21 22 namespace rootcanal { 23 class AsyncManager; 24 } // namespace rootcanal 25 26 namespace android { 27 namespace net { 28 29 using rootcanal::AsyncManager; 30 31 // A Posix compliant implementation of the AsyncDataChannel interface. 32 // 33 // Supports both Darwin and Linux. 34 class PosixAsyncSocket : public AsyncDataChannel { 35 public: 36 // The AsyncManager must support the following: 37 // 38 // - If a callback happens on thread t, and 39 // am->StopWatchingFileDescriptor(fd) 40 // is called from t then am will never fire an event for fd upon return. 41 PosixAsyncSocket(int fd, AsyncManager* am); 42 PosixAsyncSocket(const PosixAsyncSocket& other) = delete; 43 PosixAsyncSocket(PosixAsyncSocket&& other); 44 45 // Make sure to close the socket before hand. 46 ~PosixAsyncSocket(); 47 48 // Receive data in the given buffer. Returns the number of bytes read, 49 // or a negative number in case of failure. Check the errno variable to 50 // learn why the call failed. 51 ssize_t Recv(uint8_t* buffer, uint64_t bufferSize) override; 52 53 // Send data in the given buffer. Returns the number of bytes read, 54 // or a negative number in case of failure. Check the errno variable to 55 // learn why the call failed. Note: This can be EAGAIN if we cannot 56 // write to the socket at this time as it would block. 57 ssize_t Send(const uint8_t* buffer, uint64_t bufferSize) override; 58 59 // True if this socket is connected 60 bool Connected() override; 61 62 // Closes this socket. You must call this before deleting the socket. 63 // 64 // - On Linux, the socket is always closed when this function returns 65 // - On OS X, whether the socket the underlying fd becomes available seems 66 // pretty much random! (You might want to drain the socket first.) 67 void Close() override; 68 69 // Registers the given callback to be invoked when a recv call can be made 70 // to read data from this socket. 71 // Only one callback can be registered per socket. 72 bool WatchForNonBlockingRead( 73 const ReadCallback& on_read_ready_callback) override; 74 75 void StopWatching() override; 76 fd()77 int fd() const { return fd_; } 78 79 private: 80 void OnReadCallback(); 81 82 int fd_; 83 AsyncManager* am_; 84 std::atomic_bool watching_; 85 }; 86 } // namespace net 87 } // namespace android 88 89 // Re-run |fn| system call until the system call doesn't cause EINTR. 90 #define REPEAT_UNTIL_NO_INTR(fn) \ 91 do { \ 92 } while ((fn) == -1 && errno == EINTR) 93