1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <sys/epoll.h> 20 21 #include <memory> 22 #include <optional> 23 #include <set> 24 #include <shared_mutex> 25 26 #include "common/libs/fs/shared_fd.h" 27 #include "common/libs/utils/result.h" 28 29 namespace cuttlefish { 30 31 struct EpollEvent { 32 SharedFD fd; 33 uint32_t events; 34 }; 35 36 class Epoll { 37 public: 38 static Result<Epoll> Create(); 39 Epoll(); // Invalid instance 40 Epoll(Epoll&&); 41 Epoll& operator=(Epoll&&); 42 43 Result<void> Add(SharedFD fd, uint32_t events); 44 Result<void> Modify(SharedFD fd, uint32_t events); 45 Result<void> AddOrModify(SharedFD fd, uint32_t events); 46 Result<void> Delete(SharedFD fd); 47 Result<std::optional<EpollEvent>> Wait(); 48 49 private: 50 Epoll(SharedFD); 51 52 /** 53 * This read-write mutex is read-locked to perform epoll operations, and 54 * write-locked to replace the file descriptor. 55 * 56 * A read-write mutex is used here to make it possible to update the watched 57 * set while the epoll resource is being waited on by another thread, while 58 * excluding the possibility of the move constructor or assignment constructor 59 * from stealing the file descriptor out from under waiting threads. 60 */ 61 std::shared_mutex epoll_mutex_; 62 SharedFD epoll_fd_; 63 /** 64 * This read-write mutex is read-locked when interacting with it as a const 65 * std::set, and write-locked when interacting with it as a std::set. 66 */ 67 std::shared_mutex watched_mutex_; 68 std::set<SharedFD> watched_; 69 }; 70 71 } // namespace cuttlefish 72