-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mds: manage Message lifetime with intrusive_ptr #22555
Conversation
Note: this doens't compile yet. Most of what's left to fix is to adjust the small amounts of code that tries to modify a dispatched message. e.g.:
|
I haven't read the code carefully. But I think there is a simple way: Let ms_dispatch() call message->put(). |
That indeed would be simpler however this patch is trying to eliminate the manual reference management which is so prone to leaks. |
1aa2c9e
to
a73fea1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great improvements to the messenger interfaces. would love to see these intrusive_ptr overloads replace the raw pointer ones eventually
src/msg/Dispatcher.h
Outdated
|
||
class Messenger; | ||
class Message; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just duplicate the existing MessageRef typedef here, so you can still use the forward declaration of Message? for that reason, i prefer MessageRef to the new nested Message::ref/const_ref
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved MessageRef to MessageRef.h
. What do you think now @cbodley ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that works! in the seastar messenger, i added a net/Fwd.h with forward declarations for all of the messenger types. so i could see this living in a more general header, but it's up to you
03e480d
to
5cc54ee
Compare
5cc54ee
to
2dfd4ac
Compare
2dfd4ac
to
923949d
Compare
4139610
to
1ee5420
Compare
Commit "msg: add factory method to correctly construct smart_ptr" add similar codes to all message types. why not make Message's operator new private and define a template factory function. Something like struct A {
private:
void * operator new(size_t size);
template <class M, class... Args>
friend std::shared_ptr<M> alloc_msg(Args&&... args);
public:
};
template <class M, class... Args>
std::shared_ptr<M> alloc_msg(Args&&... args) {
return std::make_shared<M>(std::forward<Args>(args)...);
}
struct B : public A {
};
int main(int argc, char *argv[])
{
// auto b1 = new B;
auto b2 = alloc_msg < B > ();
} |
#include <iostream>
#include <memory>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
#include <boost/smart_ptr/intrusive_ptr.hpp>
using namespace std;
template <class A>
class Creater {
public:
using ref = boost::intrusive_ptr<A>;
template<typename... Args>
static ref create(Args&&... args) {
return ref{new A{std::forward<Args>(args)...}};
}
};
class Message : public boost::intrusive_ref_counter<Message>
{
public:
virtual ~Message() = default;
};
class MOSDMap : public Message, public Creater<MOSDMap> {
public:
MOSDMap(int i) {
cout << "hello world" << endl;
}
~MOSDMap() {
cout << "goodbye, cruel world" << endl;
}
friend class Creater<MOSDMap>;
};
int main(int argc, char *argv[])
{
auto p = MOSDMap::create(1);
} i'd suggest use the CRTP pattern here. so we can have the |
656f2de
to
bdc8e4b
Compare
To improve cache locality. Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This codifies the giving of a reference to the Dispatcher and helps avoid memory leaks. Old-style dispatch is kept to allow older code to continue working. Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This avoids an allocation for each new message (amortized via deque). Additionally, use std::move to avoid atomic update to the Message ref. Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
For use to create Contexts only when needed. Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
dfe6552
to
97a73bb
Compare
This change turned out to be far more extensive than I hoped but the end result should prevent all Message-related memory leaks. I believe I fixed several incidentally. Fixes: http://tracker.ceph.com/issues/24306 Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This is to avoid easy leaks of the form: boost::intrusive_ptr(new M*(...)); where a ref is leaked because constructing the intrusive_ptr adds a ref. It is expected that eventually all constructors move to protected/private so that the message's factory is the only way to build a new message (safely). Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
Fixes: http://tracker.ceph.com/issues/24306 Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
This eliminates duplicate code definitions. Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
97a73bb
to
583e797
Compare
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
* refs/pull/22555/head: msg: define MFoo::create helper msg: add msgref cast method msg: cleanup factory/ref definition in messages mds: use message factory to avoid leaks msg: add factory method to correctly construct smart_ptr mds: remove dead MDS-MDS forwarding code mds: manage Message lifetime with intrusive_ptr common: add templated Context factory msg: add const version of get_payload msg: use queue of messages for dispatch msg: dispatch intrusive_ptr Messages msg: use deque for dispatcher pointers Reviewed-by: Zheng Yan <zyan@redhat.com>
This is a WIP.