Monero
zmq.h
Go to the documentation of this file.
1 // Copyright (c) 2019-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include <memory>
32 #include <string>
33 #include <system_error>
34 #include <zmq.h>
35 
36 #include "common/expect.h"
37 #include "span.h"
38 
40 #define MONERO_ZMQ_CHECK(...) \
41  do \
42  { \
43  if (( __VA_ARGS__ ) < 0) \
44  return {::net::zmq::get_error_code()}; \
45  } while (0)
46 
48 #define MONERO_LOG_ZMQ_ERROR(...) \
49  do \
50  { \
51  MERROR( __VA_ARGS__ << ": " << ::net::zmq::get_error_code().message()); \
52  } while (0)
53 
55 #define MONERO_ZMQ_THROW(msg) \
56  MONERO_THROW( ::net::zmq::get_error_code(), msg )
57 
58 namespace epee
59 {
60  class byte_slice;
61 }
62 
63 namespace net
64 {
65 namespace zmq
66 {
68  const std::error_category& error_category() noexcept;
69 
71  inline std::error_code make_error_code(int code) noexcept
72  {
73  return std::error_code{code, error_category()};
74  }
75 
77  inline std::error_code get_error_code() noexcept
78  {
79  return make_error_code(zmq_errno());
80  }
81 
83  class terminate
84  {
85  static void call(void* ptr) noexcept;
86  public:
87  void operator()(void* ptr) const noexcept
88  {
89  if (ptr)
90  call(ptr);
91  }
92  };
93 
95  struct close
96  {
97  void operator()(void* ptr) const noexcept
98  {
99  if (ptr)
100  zmq_close(ptr);
101  }
102  };
103 
105  using context = std::unique_ptr<void, terminate>;
106 
108  using socket = std::unique_ptr<void, close>;
109 
116  template<typename F, typename... T>
117  expect<void> retry_op(F op, T&&... args) noexcept(noexcept(op(args...)))
118  {
119  for (;;)
120  {
121  if (0 <= op(args...))
122  return success();
123 
124  const int error = zmq_errno();
125  if (error != EINTR)
126  return make_error_code(error);
127  }
128  }
129 
144  expect<std::string> receive(void* socket, int flags = 0);
145 
161  expect<void> send(epee::span<const std::uint8_t> payload, void* socket, int flags = 0) noexcept;
162 
180  expect<void> send(epee::byte_slice&& payload, void* socket, int flags = 0) noexcept;
181 } // zmq
182 } // net
std::error_category const & error_category() noexcept
Definition: error.cpp:92
const uint32_t T[512]
Definition: groestl_tables.h:36
std::error_code make_error_code(int code) noexcept
Definition: zmq.h:71
void operator()(void *ptr) const noexcept
Definition: zmq.h:87
expect< std::string > receive(void *const socket, const int flags)
Definition: zmq.cpp:163
#define F(w, k)
Definition: sha512-blocks.c:61
error
General net errors.
Definition: error.h:38
const std::error_category & error_category() noexcept
Definition: zmq.cpp:42
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition: zmq.h:108
Definition: enums.h:67
args
Definition: build_protob.py:10
static int flags
Definition: mdb_load.c:31
const portMappingElt code
Definition: portlistingparse.c:22
Calls zmq_close
Definition: zmq.h:95
Definition: net_utils_base.h:58
Definition: expect.h:71
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
Definition: zmq.h:105
static void call(void *ptr) noexcept
Definition: zmq.cpp:83
bool success
Definition: cold-transaction.cpp:57
void operator()(void *ptr) const noexcept
Definition: zmq.h:97
Calls zmq_term
Definition: zmq.h:83
TODO: (mj-xmr) This will be reduced in an another PR.
Definition: byte_slice.h:39
Definition: expect.h:345
expect< void > send(const epee::span< const std::uint8_t > payload, void *const socket, const int flags) noexcept
Definition: zmq.cpp:170
std::error_code get_error_code() noexcept
Definition: zmq.h:77
expect< void > retry_op(F op, T &&... args) noexcept(noexcept(op(args...)))
Definition: zmq.h:117
#define inline
Definition: inline_c.h:34