1 | //===-- SelectHelper.h ------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_UTILITY_SELECTHELPER_H |
10 | #define LLDB_UTILITY_SELECTHELPER_H |
11 | |
12 | #include "lldb/Utility/Status.h" |
13 | #include "lldb/lldb-types.h" |
14 | |
15 | #include "llvm/ADT/DenseMap.h" |
16 | |
17 | #include <chrono> |
18 | #include <optional> |
19 | |
20 | class SelectHelper { |
21 | public: |
22 | // Defaults to infinite wait for select unless you call SetTimeout() |
23 | SelectHelper(); |
24 | |
25 | // Call SetTimeout() before calling SelectHelper::Select() to set the timeout |
26 | // based on the current time + the timeout. This allows multiple calls to |
27 | // SelectHelper::Select() without having to worry about the absolute timeout |
28 | // as this class manages to set the relative timeout correctly. |
29 | void SetTimeout(const std::chrono::microseconds &timeout); |
30 | |
31 | // Call the FDSet*() functions before calling SelectHelper::Select() to set |
32 | // the file descriptors that we will watch for when calling select. This will |
33 | // cause FD_SET() to be called prior to calling select using the "fd" |
34 | // provided. |
35 | void FDSetRead(lldb::socket_t fd); |
36 | void FDSetWrite(lldb::socket_t fd); |
37 | void FDSetError(lldb::socket_t fd); |
38 | |
39 | // Call the FDIsSet*() functions after calling SelectHelper::Select() to |
40 | // check which file descriptors are ready for read/write/error. This will |
41 | // contain the result of FD_ISSET after calling select for a given file |
42 | // descriptor. |
43 | bool FDIsSetRead(lldb::socket_t fd) const; |
44 | bool FDIsSetWrite(lldb::socket_t fd) const; |
45 | bool FDIsSetError(lldb::socket_t fd) const; |
46 | |
47 | // Call the system's select() to wait for descriptors using timeout provided |
48 | // in a call the SelectHelper::SetTimeout(), or infinite wait if no timeout |
49 | // was set. |
50 | lldb_private::Status Select(); |
51 | |
52 | protected: |
53 | struct FDInfo { |
54 | FDInfo() |
55 | : read_set(false), write_set(false), error_set(false), |
56 | read_is_set(false), write_is_set(false), error_is_set(false) {} |
57 | |
58 | void PrepareForSelect() { |
59 | read_is_set = false; |
60 | write_is_set = false; |
61 | error_is_set = false; |
62 | } |
63 | |
64 | bool read_set : 1, write_set : 1, error_set : 1, read_is_set : 1, |
65 | write_is_set : 1, error_is_set : 1; |
66 | }; |
67 | llvm::DenseMap<lldb::socket_t, FDInfo> m_fd_map; |
68 | std::optional<std::chrono::steady_clock::time_point> m_end_time; |
69 | }; |
70 | |
71 | #endif // LLDB_UTILITY_SELECTHELPER_H |
72 | |