xref: /aosp_15_r20/external/cronet/net/socket/udp_socket_global_limits.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_
6 #define NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_
7 
8 #include "net/base/net_errors.h"
9 #include "net/base/net_export.h"
10 
11 namespace net {
12 
13 // Helper class for RAII-style management of the global count of "open UDP
14 // sockets" [1] in the process.
15 //
16 // Keeping OwnedUDPSocketCount alive increases the global socket counter by 1.
17 // When it goes out of scope - or is explicitly Reset() - the reference is
18 // returned to the global counter.
19 class NET_EXPORT OwnedUDPSocketCount {
20  public:
21   // The default constructor builds an empty OwnedUDPSocketCount (does not own a
22   // count).
23   OwnedUDPSocketCount();
24 
25   // Any count held by OwnedUDPSocketCount is transferred when moving.
26   OwnedUDPSocketCount(OwnedUDPSocketCount&&);
27   OwnedUDPSocketCount& operator=(OwnedUDPSocketCount&&);
28 
29   // This is a move-only type.
30   OwnedUDPSocketCount(const OwnedUDPSocketCount&) = delete;
31   OwnedUDPSocketCount& operator=(const OwnedUDPSocketCount&) = delete;
32 
33   ~OwnedUDPSocketCount();
34 
35   // Returns false if this instance "owns" a socket count. In
36   // other words, when |empty()|, destruction of |this| will
37   // not change the global socket count.
empty()38   bool empty() const { return empty_; }
39 
40   // Resets |this| to an empty state (|empty()| becomes true after
41   // calling this). If |this| was previously |!empty()|, the global
42   // socket count will be decremented.
43   void Reset();
44 
45  private:
46   // Only TryAcquireGlobalUDPSocketCount() is allowed to construct a non-empty
47   // OwnedUDPSocketCount.
48   friend NET_EXPORT OwnedUDPSocketCount TryAcquireGlobalUDPSocketCount();
49   explicit OwnedUDPSocketCount(bool empty);
50 
51   bool empty_;
52 };
53 
54 // Attempts to increase the global "open UDP socket" [1] count.
55 //
56 // * On failure returns an OwnedUDPSocketCount that is |empty()|. This happens
57 //   if the global socket limit has been reached.
58 // * On success returns an OwnedUDPSocketCount that is |!empty()|. This
59 //   OwnedUDPSocketCount should be kept alive until the socket resource is
60 //   released.
61 //
62 // [1] For simplicity, an "open UDP socket" is defined as a net::UDPSocket that
63 // successfully called Open(), and has not yet called Close(). This is
64 // analogous to the number of open platform socket handles, and in practice
65 // should also be a good proxy for the number of consumed UDP ports.
66 [[nodiscard]] NET_EXPORT OwnedUDPSocketCount TryAcquireGlobalUDPSocketCount();
67 
68 // Returns the current count of open UDP sockets (for testing only).
69 NET_EXPORT int GetGlobalUDPSocketCountForTesting();
70 
71 }  // namespace net
72 
73 #endif  // NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_
74