Split out the raw system access functions (HANDLE) from the handy "wrapper" functions. Turn the wrapper functionality into an object class that includes ScopedHANDLEs with destructors, etc.
Consider RAII (Resource Acquisition Is Initialization).
Ref: https://codereview.chromium.org/2507263002/
In case the above gets deleted, I'm noting the below in this ticket:
ScopedHANDLE.h:
48 // ScopedHANDLE wraps a generic Windows HANDLE (with an invalid value of
49 // nullptr), allowing it to be closed automatically (via NtClose) when the
50 // object goes out of scope. Use is_valid() function to check validity of
51 // internal HANDLE. This class may not be used with HANDLEs that have an invalid
52 // value of INVALID_HANDLE_VALUE (e.g. CreateFile()).
53 class ScopedHANDLE {
54 public:
55 ScopedHANDLE();
56 explicit ScopedHANDLE(HANDLE handle);
57 ScopedHANDLE(ScopedHANDLE&& rvalue) : handle_(rvalue.release()) {}
58 ScopedHANDLE(const ScopedHANDLE&) = delete;
59 void operator=(const ScopedHANDLE&) = delete;
60 ~ScopedHANDLE();
61
62 HANDLE get() { return handle_; }
63 bool is_valid() const;
64
65 private:
66 // Transfers ownership. If the returned is non-null, it needs to be closed by
67 // the caller.
68 HANDLE release();
69
70 HANDLE handle_;
71 };
ScopedHANDLE.cc:
568 ScopedHANDLE::ScopedHANDLE() : handle_(nullptr) {}
569
570 ScopedHANDLE::ScopedHANDLE(HANDLE handle) : handle_(handle) {}
571
572 ScopedHANDLE::~ScopedHANDLE() {
573 if (!g_initialized)
574 InitNativeRegApi();
575 if (is_valid())
576 g_nt_close(handle_);
577 }
578
579 bool ScopedHANDLE::is_valid() const {
580 // This class should only be used for HANDLEs that have an invalid value of
581 // nullptr.
582 assert(handle_ != INVALID_HANDLE_VALUE);
583
584 return handle_ != nullptr;
585 }
586
587 HANDLE ScopedHANDLE::release() {
588 HANDLE result = handle_;
589 handle_ = nullptr;
590 return result;
591 }
Comment 1 by penny...@chromium.org
, Feb 23 2017