OpenVPN 3 Core Library
Loading...
Searching...
No Matches
cancelable_handle.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2025- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#include <openvpn/io/io.hpp>
14
15namespace openvpn {
16
23{
24 public:
29 CancelableHandle(openvpn_io::io_context &io_context)
30 : handle_(io_context)
31 {
32 }
33
39
45 {
46 DWORD status = ::WaitForSingleObject(handle_.native_handle(), 0);
47 const Win::LastError err;
48 switch (status)
49 {
50 case WAIT_TIMEOUT: // expected status
51 break;
52 case WAIT_OBJECT_0:
53 throw Exception("CancelableHandle: destroy event is already signaled");
54 case WAIT_ABANDONED:
55 throw Exception("CancelableHandle: destroy event is abandoned");
56 default:
57 OPENVPN_THROW_EXCEPTION("CancelableHandle: WaitForSingleObject failed: " << err.message());
58 }
59 }
60
63 {
64 if (!*is_closed_)
65 {
66 *is_closed_ = true;
67 try
68 {
69 handle_.cancel();
70 }
71 catch (const openvpn_io::system_error &)
72 {
73 // this is fine, handle is likely not yet initialized
74 }
75
76 handle_.close();
77 }
78 }
79
84 void assign(HANDLE handle)
85 {
86 handle_.assign(handle);
87 is_closed_ = std::make_shared<bool>(false);
88 }
89
94 template <typename Handler>
95 void async_wait(Handler &&handler)
96 {
97 handle_.async_wait([is_closed = is_closed_, handler = std::forward<Handler>(handler)](const openvpn_io::error_code &ec)
98 {
99 if (!*is_closed)
100 {
101 handler(ec);
102 } });
103 }
104
105 private:
106 openvpn_io::windows::object_handle handle_;
107 std::shared_ptr<bool> is_closed_ = std::make_shared<bool>(false);
108};
109
110} // namespace openvpn
Wrapper for an asynchronous handle supporting cancellation and closure.
void check_is_already_signalled()
Checks if the handle's event is already signaled.
void async_wait(Handler &&handler)
Initiates an asynchronous wait on the handle.
~CancelableHandle()
Destructor ensures handle cancellation and closure.
CancelableHandle(openvpn_io::io_context &io_context)
Constructs with the given I/O context.
openvpn_io::windows::object_handle handle_
Asynchronous Windows object handle.
std::shared_ptr< bool > is_closed_
Indicates if handle is closed.
void cancel_and_close()
Cancels and closes the handle if not already closed.
void assign(HANDLE handle)
Assigns a native Windows handle.
static void handler(int signum)
Definition cli.cpp:961
#define OPENVPN_THROW_EXCEPTION(stuff)