| 73 | } |
| 74 | |
| 75 | class ScopedHandle { |
| 76 | public: |
| 77 | ScopedHandle(HANDLE handle) : handle_(handle) {} |
| 78 | ScopedHandle(const ScopedHandle&) = delete; |
| 79 | ScopedHandle(ScopedHandle&& other) noexcept : handle_(other.Release()) {} |
| 80 | ~ScopedHandle() { Close(); } |
| 81 | |
| 82 | ScopedHandle& operator=(const ScopedHandle&) = delete; |
| 83 | |
| 84 | ScopedHandle& operator=(ScopedHandle&& rhs) noexcept { |
| 85 | if (this != &rhs) handle_ = rhs.Release(); |
| 86 | return *this; |
| 87 | } |
| 88 | |
| 89 | bool Close() { |
| 90 | if (!is_valid()) { |
| 91 | return true; |
| 92 | } |
| 93 | HANDLE h = handle_; |
| 94 | handle_ = INVALID_HANDLE_VALUE; |
| 95 | return ::CloseHandle(h); |
| 96 | } |
| 97 | |
| 98 | bool is_valid() const { |
| 99 | return handle_ != INVALID_HANDLE_VALUE && handle_ != nullptr; |
| 100 | } |
| 101 | |
| 102 | HANDLE get() const { return handle_; } |
| 103 | |
| 104 | HANDLE Release() { |
| 105 | HANDLE h = handle_; |
| 106 | handle_ = INVALID_HANDLE_VALUE; |
| 107 | return h; |
| 108 | } |
| 109 | |
| 110 | private: |
| 111 | HANDLE handle_; |
| 112 | }; |
| 113 | |
| 114 | // Helper class to limit resource usage to avoid exhaustion. |
| 115 | // Currently used to limit read-only file descriptors and mmap file usage |