----------------------------------------------------------- This is an automatically generated e-mail. To reply, visit: https://reviews.apache.org/r/37217/#review95090 -----------------------------------------------------------
I want to clarify my thoughts for discussion, I'm working on putting this into code. DESIGN PRINCIPLES: 1. C++ is not python. In C++ it is normal to provide "raw" alloc/free style pairs, esp. when wrapping C. Automation of memory management in C++ is done by a "smart pointer" layer (e.g. shared_ptr, unique_ptr) that is *separate* from the underlying raw access. 2. Proton refcounting should be considered an internal implementation detail of proton, NOT a feature that we use in the C++ binding. If need to refcount in the binding we should maintain our own refcounts to references *from the binding*, not rely on pn refcounts. 3. I suggest something like this: for pn_foo we have a. foo : public wrapper<pn_foo> {} behaves like a plain pn_foo* but has convenience C++ member functions and "free()" member calling appropriate pn_foo_free() b. unique<foo> : behaves like foo but calls foo.free() in dtor c. shared<foo> : behaves like foo but maintains a refcount (like shared_ptr) and calls foo.free() on last ref. 4. Objects belonging to the binding itself that are not wrapper<pn_foo> should have normal new/delete semantics, and be manageable by std::shared_ptr, std::unique_ptr etc. Some justification for 2: Consider this from the public proton API doc for pn_link_target: * The pointer returned by this operation is valid until the link * object is freed. Note the text specificaly says the pointer valid *until the link is freed*. It does *not* say you can incref the pointer to keep it around longer. It so happens that right now that actually works but IMO that is an implementation detail we should not rely on. In a future, simpler implementation of proton as a more C-like library that is not so heavily influenced by python it might NOT work. The python bindings rely on proton refcounts because they were specifically designed to support python, I don't think languages like C++ or Go should rely on them (and IMO this detail of python and ruby-like languages should not have been pushed into the C library, but should have been dealt with in those bindings) Go and C++ which have their own interface with C should treat proton as a simple C library. I suspect that simple 3a + 3b will cover most cases, I'm not sure we even need 3c but it isn't that hard to do. ASIDE: We could do some really freaky C++ magic and make wrapper<pn_foo> look exactly like a real C++ object with a real pointer (imaginary C++ objects occupying the same memory location as the pn_foo_*, casting their `this` pointers with overloaded op delete and all that fun stuff) but I think that would be, um, silly. - Alan Conway On Aug. 7, 2015, 1:46 p.m., Cliff Jansen wrote: > > ----------------------------------------------------------- > This is an automatically generated e-mail. To reply, visit: > https://reviews.apache.org/r/37217/ > ----------------------------------------------------------- > > (Updated Aug. 7, 2015, 1:46 p.m.) > > > Review request for qpid, Alan Conway and Andrew Stitcher. > > > Bugs: PROTON-865 > https://issues.apache.org/jira/browse/PROTON-865 > > > Repository: qpid-proton-git > > > Description > ------- > > This is a mini refactor of a single class to see if the chosen direction for > generally removing handle<foo> is sane. > > > I chose the connection class to try based on medium complexity and > interaction with other moving parts (not visible to the user, the > connector/override and life cycle issues). > > The connection is now non copyable. > > If the connection "self-created" (i.e. an inbound connection from a listener, > arriving via a reactor event, or implicit connection from > container.create_receiver), it is not "owned", and its life ends when the > pn_connection_t dies (dies for good, i.e. when it releases its attachment > records). > > If the user creates the connection explicitly, it is "owned" and destructs as > normal. It is unclear if the Python behavior should be preserved, where the > connection lives on un-owned, or destruction means "all gone" with tear down > of the transport and connector. I chose the latter as perhaps least surprise > for the user. > > The Proton C++ code can use either model internally to taste. > > Perhaps the connection object should have a pin/unpin or incref/decref > ability so that the user can hang onto it past the event delivery. As a > hack, they can always do pn_incref(connection.pn_connection()) and decref it > when done. > > It is not clear to me that the counted class will ever be used separately > from the context<foo> class, so they might get rolled together in the future. > The memory management is accomplished by a special proton metaclass that is > refcounted, but neither allocates nor frees memory. > > connection::getZZZcontainer() is an unintended artifact of the refactor. I'm > not sure why gcc is fussing over the original signature, but I don't wish to > target its resolution in this review. > > > Diffs > ----- > > examples/cpp/helloworld.cpp 34e5076 > examples/cpp/server.cpp 78b78d3 > proton-c/bindings/cpp/CMakeLists.txt d1b1ebc > proton-c/bindings/cpp/include/proton/connection.hpp af3c585 > proton-c/bindings/cpp/include/proton/container.hpp a0ca59a > proton-c/bindings/cpp/include/proton/context.hpp PRE-CREATION > proton-c/bindings/cpp/include/proton/counted.hpp PRE-CREATION > proton-c/bindings/cpp/src/blocking_connection.cpp c0c1477 > proton-c/bindings/cpp/src/blocking_connection_impl.hpp 11ff4fd > proton-c/bindings/cpp/src/blocking_connection_impl.cpp 0e78541 > proton-c/bindings/cpp/src/connection.cpp 2b335a4 > proton-c/bindings/cpp/src/connection_impl.hpp 6450ef5 > proton-c/bindings/cpp/src/connection_impl.cpp e2f4608 > proton-c/bindings/cpp/src/connector.hpp ad373a9 > proton-c/bindings/cpp/src/connector.cpp 559a7fd > proton-c/bindings/cpp/src/container.cpp a424c0b > proton-c/bindings/cpp/src/container_impl.hpp 1ce27ee > proton-c/bindings/cpp/src/container_impl.cpp e328251 > proton-c/bindings/cpp/src/context.cpp PRE-CREATION > proton-c/bindings/cpp/src/contexts.cpp 98c502b > proton-c/bindings/cpp/src/counted.cpp PRE-CREATION > proton-c/bindings/cpp/src/link.cpp 2cef0a2 > proton-c/bindings/cpp/src/proton_event.cpp 46b43ee > proton-c/bindings/cpp/src/session.cpp 5742f13 > > Diff: https://reviews.apache.org/r/37217/diff/ > > > Testing > ------- > > passes ctest on rhel7 > > > Thanks, > > Cliff Jansen > >