110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel//
210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// Copyright 2016 The Android Open Source Project
310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel//
410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// Licensed under the Apache License, Version 2.0 (the "License");
510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// you may not use this file except in compliance with the License.
610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// You may obtain a copy of the License at
710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel//
810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// http://www.apache.org/licenses/LICENSE-2.0
910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel//
1010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// Unless required by applicable law or agreed to in writing, software
1110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// distributed under the License is distributed on an "AS IS" BASIS,
1210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// See the License for the specific language governing permissions and
1410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel// limitations under the License.
1510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel//
1610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
1710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel#pragma once
1810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
1910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel#include <map>
2010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel#include <mutex>
2110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel#include <thread>
2210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
2310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelnamespace android {
2410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelnamespace hardware {
2510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelnamespace bluetooth {
2610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelnamespace async {
2710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
2810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelusing ReadCallback = std::function<void(int)>;
2910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelusing TimeoutCallback = std::function<void(void)>;
3010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
3110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patelclass AsyncFdWatcher {
3210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel public:
3310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  AsyncFdWatcher() = default;
3410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  ~AsyncFdWatcher();
3510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
3610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int WatchFdForNonBlockingReads(int file_descriptor,
3710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel                                 const ReadCallback& on_read_fd_ready_callback);
3810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int ConfigureTimeout(const std::chrono::milliseconds timeout,
3910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel                       const TimeoutCallback& on_timeout_callback);
4010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  void StopWatchingFileDescriptors();
4110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
4210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel private:
4310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  AsyncFdWatcher(const AsyncFdWatcher&) = delete;
4410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  AsyncFdWatcher& operator=(const AsyncFdWatcher&) = delete;
4510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
4610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int tryStartThread();
4710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int stopThread();
4810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int notifyThread();
4910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  void ThreadRoutine();
5010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
5110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::atomic_bool running_{false};
5210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::thread thread_;
5310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::mutex internal_mutex_;
5410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::mutex timeout_mutex_;
5510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
5610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::map<int, ReadCallback> watched_fds_;
5710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int notification_listen_fd_;
5810589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  int notification_write_fd_;
5910589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  TimeoutCallback timeout_cb_;
6010589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel  std::chrono::milliseconds timeout_ms_;
6110589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel};
6210589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
6310589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel
6410589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel} // namespace async
6510589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel} // namespace bluetooth
6610589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel} // namespace hardware
6710589c71bbda1493597c9e5a2bcf6bef54c4740bSatish Patel} // namespace android
68