blob: c02f0e6b04076ccf7bdad985be88476852be116f [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
[email protected]0840cc72009-11-24 16:14:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_SYNC_SOCKET_H_
6#define BASE_SYNC_SOCKET_H_
7
8// A socket abstraction used for sending and receiving plain
[email protected]5d272092012-04-19 10:23:039// data. Because the receiving is blocking, they can be used to perform
[email protected]0840cc72009-11-24 16:14:5310// rudimentary cross-process synchronization with low latency.
11
avi9b6f42932015-12-26 22:15:1412#include <stddef.h>
13
14#include "base/base_export.h"
Austin Sullivanedf168fd2024-01-17 21:37:2015#include "base/containers/span.h"
Robert Sesek6ab73b022020-02-13 16:42:3916#include "base/files/platform_file.h"
avi9b6f42932015-12-26 22:15:1417#include "base/synchronization/waitable_event.h"
18#include "base/time/time.h"
19#include "build/build_config.h"
20
Xiaohan Wang38e4ebb2022-01-19 06:57:4321#if BUILDFLAG(IS_WIN)
[email protected]0840cc72009-11-24 16:14:5322#include <windows.h>
23#endif
24#include <sys/types.h>
25
26namespace base {
27
[email protected]0bea7252011-08-05 15:34:0028class BASE_EXPORT SyncSocket {
[email protected]0840cc72009-11-24 16:14:5329 public:
Robert Sesek6ab73b022020-02-13 16:42:3930 using Handle = PlatformFile;
31 using ScopedHandle = ScopedPlatformFile;
[email protected]5895ee12011-12-22 19:33:2732 static const Handle kInvalidHandle;
[email protected]0840cc72009-11-24 16:14:5333
[email protected]532e9bd2012-01-25 12:04:1734 SyncSocket();
[email protected]0840cc72009-11-24 16:14:5335
Robert Sesek6ab73b022020-02-13 16:42:3936 // Creates a SyncSocket from a Handle.
37 explicit SyncSocket(Handle handle);
38 explicit SyncSocket(ScopedHandle handle);
David Bienvenu5f4d4f02020-09-27 16:55:0339 SyncSocket(const SyncSocket&) = delete;
40 SyncSocket& operator=(const SyncSocket&) = delete;
[email protected]532e9bd2012-01-25 12:04:1741 virtual ~SyncSocket();
42
43 // Initializes and connects a pair of sockets.
44 // |socket_a| and |socket_b| must not hold a valid handle. Upon successful
45 // return, the sockets will both be valid and connected.
46 static bool CreatePair(SyncSocket* socket_a, SyncSocket* socket_b);
[email protected]0840cc72009-11-24 16:14:5347
Robert Sesek6ab73b022020-02-13 16:42:3948 // Closes the SyncSocket.
49 virtual void Close();
[email protected]0840cc72009-11-24 16:14:5350
51 // Sends the message to the remote peer of the SyncSocket.
52 // Note it is not safe to send messages from the same socket handle by
53 // multiple threads simultaneously.
Austin Sullivanedf168fd2024-01-17 21:37:2054 // `data` must be non-empty.
[email protected]0840cc72009-11-24 16:14:5355 // Returns the number of bytes sent, or 0 upon failure.
Austin Sullivanedf168fd2024-01-17 21:37:2056 virtual size_t Send(span<const uint8_t> data);
[email protected]0840cc72009-11-24 16:14:5357
58 // Receives a message from an SyncSocket.
Austin Sullivanedf168fd2024-01-17 21:37:2059 // The data will be received in `buffer`, which must be non-empty.
[email protected]0840cc72009-11-24 16:14:5360 // Returns the number of bytes received, or 0 upon failure.
Austin Sullivanedf168fd2024-01-17 21:37:2061 virtual size_t Receive(span<uint8_t> buffer);
[email protected]0840cc72009-11-24 16:14:5362
Austin Sullivanedf168fd2024-01-17 21:37:2063 // Same as Receive() but only blocks for data until `timeout` has elapsed or
64 // `buffer` is exhausted. Currently only timeouts less than one second are
65 // allowed. Returns the number of bytes read.
66 virtual size_t ReceiveWithTimeout(span<uint8_t> buffer, TimeDelta timeout);
[email protected]62558f12013-10-19 22:13:1967
[email protected]d8b65912009-12-04 22:53:2268 // Returns the number of bytes available. If non-zero, Receive() will not
grunell8d9071d2015-09-10 15:24:4269 // not block when called.
70 virtual size_t Peek();
[email protected]d8b65912009-12-04 22:53:2271
Robert Sesek6ab73b022020-02-13 16:42:3972 // Returns true if the Handle is valid, and false if it is not.
73 bool IsValid() const;
74
[email protected]0840cc72009-11-24 16:14:5375 // Extracts the contained handle. Used for transferring between
76 // processes.
Robert Sesek6ab73b022020-02-13 16:42:3977 Handle handle() const;
[email protected]0840cc72009-11-24 16:14:5378
maxmorind4bcb112017-04-13 11:43:1379 // Extracts and takes ownership of the contained handle.
80 Handle Release();
Robert Sesek6ab73b022020-02-13 16:42:3981 ScopedHandle Take();
maxmorind4bcb112017-04-13 11:43:1382
[email protected]532e9bd2012-01-25 12:04:1783 protected:
Robert Sesek6ab73b022020-02-13 16:42:3984 ScopedHandle handle_;
[email protected]0840cc72009-11-24 16:14:5385};
86
[email protected]532e9bd2012-01-25 12:04:1787// Derives from SyncSocket and adds support for shutting down the socket from
[email protected]5d272092012-04-19 10:23:0388// another thread while a blocking Receive or Send is being done from the
89// thread that owns the socket.
[email protected]532e9bd2012-01-25 12:04:1790class BASE_EXPORT CancelableSyncSocket : public SyncSocket {
91 public:
92 CancelableSyncSocket();
93 explicit CancelableSyncSocket(Handle handle);
Robert Sesek6ab73b022020-02-13 16:42:3994 explicit CancelableSyncSocket(ScopedHandle handle);
David Bienvenu5f4d4f02020-09-27 16:55:0395 CancelableSyncSocket(const CancelableSyncSocket&) = delete;
96 CancelableSyncSocket& operator=(const CancelableSyncSocket&) = delete;
Chris Watkins091d6292017-12-13 04:25:5897 ~CancelableSyncSocket() override = default;
[email protected]532e9bd2012-01-25 12:04:1798
99 // Initializes a pair of cancelable sockets. See documentation for
100 // SyncSocket::CreatePair for more details.
101 static bool CreatePair(CancelableSyncSocket* socket_a,
102 CancelableSyncSocket* socket_b);
103
104 // A way to shut down a socket even if another thread is currently performing
105 // a blocking Receive or Send.
106 bool Shutdown();
107
Xiaohan Wang38e4ebb2022-01-19 06:57:43108#if BUILDFLAG(IS_WIN)
[email protected]532e9bd2012-01-25 12:04:17109 // Since the Linux and Mac implementations actually use a socket, shutting
110 // them down from another thread is pretty simple - we can just call
111 // shutdown(). However, the Windows implementation relies on named pipes
112 // and there isn't a way to cancel a blocking synchronous Read that is
113 // supported on <Vista. So, for Windows only, we override these
114 // SyncSocket methods in order to support shutting down the 'socket'.
Robert Sesek6ab73b022020-02-13 16:42:39115 void Close() override;
Austin Sullivanedf168fd2024-01-17 21:37:20116 size_t Receive(span<uint8_t> buffer) override;
Austin Sullivanedf168fd2024-01-17 21:37:20117 size_t ReceiveWithTimeout(span<uint8_t> buffer, TimeDelta timeout) override;
[email protected]532e9bd2012-01-25 12:04:17118#endif
119
[email protected]5d272092012-04-19 10:23:03120 // Send() is overridden to catch cases where the remote end is not responding
Austin Sullivanedf168fd2024-01-17 21:37:20121 // and we fill the local socket buffer. When `data` is full, this
[email protected]5d272092012-04-19 10:23:03122 // implementation of Send() will not block indefinitely as
123 // SyncSocket::Send will, but instead return 0, as no bytes could be sent.
124 // Note that the socket will not be closed in this case.
Austin Sullivanedf168fd2024-01-17 21:37:20125 size_t Send(span<const uint8_t> data) override;
[email protected]5d272092012-04-19 10:23:03126
[email protected]532e9bd2012-01-25 12:04:17127 private:
Xiaohan Wang38e4ebb2022-01-19 06:57:43128#if BUILDFLAG(IS_WIN)
[email protected]532e9bd2012-01-25 12:04:17129 WaitableEvent shutdown_event_;
130 WaitableEvent file_operation_;
131#endif
[email protected]532e9bd2012-01-25 12:04:17132};
133
[email protected]0840cc72009-11-24 16:14:53134} // namespace base
135
136#endif // BASE_SYNC_SOCKET_H_