Use std::shared_ptr to do reference counting in Socket. Review: https://reviews.apache.org/r/27957
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/075859d9 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/075859d9 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/075859d9 Branch: refs/heads/master Commit: 075859d984aa0b23d8efb18cc9bf0e6a17f3e00f Parents: 9eda433 Author: Joris Van Remoortere <[email protected]> Authored: Sat Nov 15 16:45:35 2014 -0800 Committer: Benjamin Hindman <[email protected]> Committed: Sat Nov 15 17:38:21 2014 -0800 ---------------------------------------------------------------------- 3rdparty/libprocess/include/process/socket.hpp | 87 ++++++++++----------- 1 file changed, 42 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/075859d9/3rdparty/libprocess/include/process/socket.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/include/process/socket.hpp b/3rdparty/libprocess/include/process/socket.hpp index 6683881..9f4302e 100644 --- a/3rdparty/libprocess/include/process/socket.hpp +++ b/3rdparty/libprocess/include/process/socket.hpp @@ -4,6 +4,7 @@ #include <assert.h> #include <stout/abort.hpp> +#include <stout/memory.hpp> #include <stout/nothing.hpp> #include <stout/os.hpp> #include <stout/try.hpp> @@ -40,66 +41,62 @@ inline Try<int> socket(int family, int type, int protocol) { class Socket { public: - Socket() - : refs(new int(1)), s(-1) {} + class Impl + { + public: + Impl() : s(-1) {} - explicit Socket(int _s) - : refs(new int(1)), s(_s) {} + explicit Impl(int _s) : s(_s) {} - ~Socket() - { - cleanup(); - } + ~Impl() + { + if (s >= 0) { + Try<Nothing> close = os::close(s); + if (close.isError()) { + ABORT( + "Failed to close socket " + stringify(s) + ": " + close.error()); + } + } + } - Socket(const Socket& that) - { - copy(that); - } + int get() const + { + return s >= 0 ? s : create().get(); + } - Socket& operator = (const Socket& that) - { - if (this != &that) { - cleanup(); - copy(that); + private: + const Impl& create() const + { + CHECK(s < 0); + Try<int> fd = + process::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + if (fd.isError()) { + ABORT("Failed to create socket: " + fd.error()); + } + s = fd.get(); + return *this; } - return *this; - } + + // Mutable so that the socket can be lazily created. + mutable int s; + }; + + Socket() : impl(std::make_shared<Impl>()) {} + + explicit Socket(int s) : impl(std::make_shared<Impl>(s)) {} bool operator == (const Socket& that) const { - return s == that.s && refs == that.refs; + return impl == that.impl; } operator int () const { - return s; + return impl->get(); } private: - void copy(const Socket& that) - { - assert(that.refs > 0); - __sync_fetch_and_add(that.refs, 1); - refs = that.refs; - s = that.s; - } - - void cleanup() - { - assert(refs != NULL); - if (__sync_sub_and_fetch(refs, 1) == 0) { - delete refs; - if (s >= 0) { - Try<Nothing> close = os::close(s); - if (close.isError()) { - ABORT("Failed to close socket: " + close.error()); - } - } - } - } - - int* refs; - int s; + memory::shared_ptr<Impl> impl; }; } // namespace process {
