1 /* 2 * Copyright 2019 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 #include <atomic> 21 #include <functional> 22 #include <list> 23 #include <mutex> 24 #include <thread> 25 26 #include "os/utils.h" 27 28 namespace bluetooth { 29 namespace os { 30 31 // Format of closure to be used in the entire stack 32 using Closure = std::function<void()>; 33 34 // A simple implementation of reactor-style looper. 35 // When a reactor is running, the main loop is polling and blocked until at least one registered reactable is ready to 36 // read or write. It will invoke on_read_ready() or on_write_ready(), which is registered with the reactor. Then, it 37 // blocks again until ready event. 38 class Reactor { 39 public: 40 // An object used for Unregister() and ModifyRegistration() 41 class Reactable; 42 43 // Construct a reactor on the current thread 44 Reactor(); 45 46 // Destruct this reactor and release its resources 47 ~Reactor(); 48 49 DISALLOW_COPY_AND_ASSIGN(Reactor); 50 51 // Start the reactor. The current thread will be blocked until Stop() is invoked and handled. 52 void Run(); 53 54 // Stop the reactor. Must be invoked from a different thread. Note: all registered reactables will not be unregistered 55 // by Stop(). If the reactor is not running, it will be stopped once it's started. 56 void Stop(); 57 58 // Register a reactable fd to this reactor. Returns a pointer to a Reactable. Caller must use this object to 59 // unregister or modify registration. Ownership of the memory space is NOT transferred to user. 60 Reactable* Register(int fd, Closure on_read_ready, Closure on_write_ready); 61 62 // Unregister a reactable from this reactor 63 void Unregister(Reactable* reactable); 64 65 // Modify the registration for a reactable with given reactable 66 void ModifyRegistration(Reactable* reactable, Closure on_read_ready, Closure on_write_ready); 67 68 private: 69 mutable std::mutex mutex_; 70 int epoll_fd_; 71 int control_fd_; 72 std::atomic<bool> is_running_; 73 std::list<Reactable*> invalidation_list_; 74 bool reactable_removed_; 75 }; 76 77 } // namespace os 78 } // namespace bluetooth 79