notifiers
list after its callback function returned false
(which is likely not relevant in practice but still a bug).
notifiers
list after its callback function returned false
(which is likely not relevant in practice but still a bug).
Concept ACK.
From a quick view LGTM.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
What do you think about wrapping the code with zmq
namespace and removing ZMQ/zmq
prefix from class/function names?
Basically when the location of the file is a/b/c.cpp
then we have:
0namespace a {
1namespace b {
2class C {}
3}
4}
@kostyantyn: At least for now, there seems to be not much namespace usage at all in the Bitcoin code - so I’m not sure if we should change that lightly. Also, note that zmq
is the namespace that is also used by ZMQ’s own C++ language bindings; they are currently not used, but I proposed to change that (#13957).
Also, note that C++ namespaces are different from Java’s, so that some people advise against nesting (e.g. exact correspondence to the directory structure as you suggest).
4@@ -5,12 +5,13 @@
5 #ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
6 #define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
7
8-#include <zmq/zmqconfig.h>
9+#include <memory>
10
<string>
. There are still CI errors, though, which I don’t understand so far. Has anyone an insight of where they come from? I’ll try to resolve them now.
19
20+#include <zmq.h>
21+
22+#include <cstdarg>
23+#include <cstddef>
24+
I would suggest adding the following code for Windows.
0#if defined(WIN32) && defined(SendMessage)
1#undef SendMessage
2#endif
Windows headers have defined SendMessage
as SendMessageA
or SendMessageW
Or you could rename the method name SendMessage
.
3@@ -4,79 +4,69 @@
4
5 #include <zmq/zmqnotificationinterface.h>
6 #include <zmq/zmqpublishnotifier.h>
7+#include <zmq/zmqutil.h>
8+
9+#include <zmq.h>
Why is a guard dropped?
0#ifdef ENABLE_ZMQ
1#include <zmq.h>
2#endif
init.cpp
) around zmqnotificationinterface
itself.
std::unique_ptr
).
114@@ -136,45 +115,44 @@ void CZMQNotificationInterface::Shutdown()
115 }
116 }
117
118-void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
119+namespace
f18bc54cab43ef1de8502b8f84b5585ae68af4bc
According to developer notes put {
here.
129- i++;
130- }
131- else
132- {
133+template <typename Function>
134+void TryForEachAndRemoveFailed(std::list<std::unique_ptr<CZMQAbstractNotifier>>& notifiers, const Function& func)
f18bc54cab43ef1de8502b8f84b5585ae68af4bc
Could make this refactor in a separate commit?
22@@ -21,9 +23,9 @@ class CZMQAbstractNotifier
23 virtual ~CZMQAbstractNotifier();
24
25 template <typename T>
26- static CZMQAbstractNotifier* Create()
27+ static std::unique_ptr<CZMQAbstractNotifier> Create()
28 {
29- return new T();
30+ return std::unique_ptr<CZMQAbstractNotifier>(new T());
d10f274a6e0291e752e25b2bd99c0472d22a420f
MakeUnique
?
Thanks for the review! I’ve addressed your comments in follow-up commits (I do not want to force-push right now and perhaps mess up your ongoing review). I will add them as fixups to the proper commits later when you are done with the review.
I can then also split out the creation of TryForEachAndRemoveFailed
into a separate commit if you prefer that.
72+ notificationInterface.reset();
73 }
74 }
75
76- return notificationInterface;
77+ return notificationInterface.release();
69f92ffce9f0d11d9389610e702b99d9038f3fed
If this code is touched to make it easier to read and maintain, may I suggest a simpler approach:
0 if (!notifiers.empty()) {
1 auto notificationInterface = std::unique_ptr<CZMQNotificationInterface>(new CZMQNotificationInterface());
2 notificationInterface->notifiers = std::move(notifiers);
3
4 if (notificationInterface->Initialize()) {
5 return notificationInterface.release();
6 }
7 }
8
9 return nullptr;
?
auto notificationInterface = ...
line slightly into what I consider even clearer; but let me know if you prefer your suggestion).
18 #include <rpc/server.h>
19
20+#include <zmq.h>
21+
22+#include <cstdarg>
23+#include <cstddef>
0#include <cstdarg>
1#include <cstddef>
2#include <map>
3#include <string>
4#include <utility>
1@@ -2,14 +2,25 @@
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5+#if defined(HAVE_CONFIG_H)
6+#include <config/bitcoin-config.h>
7+#endif
bitcoin-config.h
is used here?
0@@ -0,0 +1,10 @@
1+// Copyright (c) 2014-2018 The Bitcoin Core developers
2+// Distributed under the MIT software license, see the accompanying
3+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+#ifndef BITCOIN_ZMQ_ZMQUTIL_H
6+#define BITCOIN_ZMQ_ZMQUTIL_H
7+
8+void zmqError(const char *str);
49e2cb78563df27ff0a5d2ad985e074ee98afcce nanonit:
0void zmqError(const char* str);
6+
7+#include <logging.h>
8+
9+#include <zmq.h>
10+
11+void zmqError(const char *str)
49e2cb78563df27ff0a5d2ad985e074ee98afcce nanonit:
0void zmqError(const char* str)
TryForEachAndRemoveFailed
refactor into its own commit.
auto
?
This is a pure refactoring of zmqnotificationinterface to make the
code easier to read and maintain. It replaces explicit iterators
with C++11 for-each loops where appropriate and uses std::unique_ptr
to make memory ownership more explicit.
This factors out the common logic to run over all ZMQ notifiers, call a
function on them, and remove them from the list if the function fails is
extracted to a helper method.
Note that this also fixes a potential memory leak: When a notifier was
removed previously after its callback returned false, it would just be
removed from the list without destructing the object. This is now done
correctly by std::unique_ptr behind the scenes.
Instead of returning a raw pointer from CZMQNotifierFactory and
implicitly requiring the caller to know that it has to take ownership,
return a std::unique_ptr to make this explicit.
This also changes the typedef for CZMQNotifierFactory to use the new
C++11 using syntax, which makes it (a little) less cryptic.
zmqconfig.h is currently not really needed anywhere, except that
it declares zmqError (which is then defined in
zmqnotificationinterface.cpp). Note in particular that there is
no need to conditionally include zmq.h only if ZMQ is enabled, because
the place in the core code where the ZMQ library itself is included
(init.cpp) is conditional already on that.
This commit removes zmqconfig.h and replaces it by a much simpler
zmqutil.h library for zmqError. The definition of the function is
moved to the matching (newly created) zmqutil.cpp.
ACK 166ddcbef82ba2b6734e8f09584fb73e4f9f98a4.
Mind making the latest commit 166ddcbef82ba2b6734e8f09584fb73e4f9f98a4 a sripted-diff with the following script:
0sed -i 's/SendMessage/SendZmqMessage/g' src/zmq/zmqpublishnotifier.*
?
Windows headers define SendMessage as a macro, which leads to problems
with the method name "SendMessage". To circumvent this, we rename the
method to "SendZmqMessage".
-BEGIN VERIFY SCRIPT-
sed -i 's/SendMessage/SendZmqMessage/g' src/zmq/zmqpublishnotifier.*
-END VERIFY SCRIPT-
utACK 6fe2ef2acb00b1df7f6a0c0dea1a81a1924be0e1
I restarted one travis job that appeared to be a spurious timeout.