diff --git a/apps/memcached/memcache.cc b/apps/memcached/memcache.cc index 097f3ee61a..e998cd4832 100644 --- a/apps/memcached/memcache.cc +++ b/apps/memcached/memcache.cc @@ -63,13 +63,13 @@ public: }; class subdevice { - foreign_ptr> _dev; + foreign_ptr> _dev; uint64_t _offset; uint64_t _end; std::queue _free_blocks; semaphore _par = { 1000 }; public: - subdevice(foreign_ptr> dev, uint64_t offset, uint64_t length) + subdevice(foreign_ptr> dev, uint64_t offset, uint64_t length) : _dev(std::move(dev)) , _offset(offset) , _end(offset + length) @@ -417,7 +417,7 @@ private: item_lru_list _lru; cache_stats _stats; public: - void do_setup(foreign_ptr> dev, uint64_t offset, uint64_t length) {} + void do_setup(foreign_ptr> dev, uint64_t offset, uint64_t length) {} void do_erase(item_type& item_ref) { _lru.erase(_lru.iterator_to(item_ref)); @@ -462,7 +462,7 @@ public: return subdev_ref; } - void do_setup(foreign_ptr> dev, uint64_t offset, uint64_t length) { + void do_setup(foreign_ptr> dev, uint64_t offset, uint64_t length) { _subdev = std::make_unique(std::move(dev), offset, length); } @@ -593,7 +593,7 @@ future<> flashcache_cache_base::load_item_data(boost::intrusive_ptr i assert(item->get_state() == item_state::DISK); flashcache::subdevice& subdev = this->get_subdevice(); - auto sem = make_shared({ 0 }); + auto sem = make_lw_shared({ 0 }); auto& item_data = item->data(); auto item_size = item->size(); auto blocks_to_load = item->used_blocks_size(); @@ -659,7 +659,7 @@ future<> flashcache_cache_base::store_item_data(boost::intrusive_ptr assert(item->get_state() == item_state::TO_MEM_DISK); flashcache::subdevice& subdev = this->get_subdevice(); - auto sem = make_shared({ 0 }); + auto sem = make_lw_shared({ 0 }); auto& item_data = item->data(); auto item_size = item->size(); auto blocks_to_store = (item_size + (flashcache::block_size - 1)) / flashcache::block_size; @@ -878,7 +878,7 @@ public: _flush_timer.set_callback([this] { flush_all(); }); } - future<> setup(foreign_ptr> dev, uint64_t offset, uint64_t length) { + future<> setup(foreign_ptr> dev, uint64_t offset, uint64_t length) { this->do_setup(std::move(dev), offset, length); return make_ready_future<>(); } @@ -1058,7 +1058,7 @@ public: return decr(key, delta); } - std::pair>> print_hash_stats() { + std::pair>> print_hash_stats() { static constexpr unsigned bits = sizeof(size_t) * 8; size_t histo[bits + 1] {}; size_t max_size = 0; @@ -1096,7 +1096,7 @@ public: } ss << histo[i] << "\n"; } - return {engine.cpu_id(), make_foreign(make_shared(ss.str()))}; + return {engine.cpu_id(), make_foreign(make_lw_shared(ss.str()))}; } future<> stop() { return make_ready_future<>(); } @@ -1195,7 +1195,7 @@ public: } future<> print_hash_stats(output_stream& out) { - return _peers.map_reduce([&out] (std::pair>> data) mutable { + return _peers.map_reduce([&out] (std::pair>> data) mutable { return out.write("=== CPU " + std::to_string(data.first) + " ===\r\n") .then([&out, str = std::move(data.second)] { return out.write(*str); @@ -1667,7 +1667,7 @@ public: auto request_id = hdr._request_id; auto in = as_input_stream(std::move(p)); - auto conn = make_shared(dgram.get_src(), request_id, std::move(in), + auto conn = make_lw_shared(dgram.get_src(), request_id, std::move(in), _max_datagram_size - sizeof(header), _cache, _system_stats); if (hdr._n != 1 || hdr._sequence_number != 0) { @@ -1693,7 +1693,7 @@ public: template class tcp_server { private: - shared_ptr _listener; + lw_shared_ptr _listener; sharded_cache& _cache; distributed& _system_stats; uint16_t _port; @@ -1732,7 +1732,7 @@ public: _listener = engine.listen(make_ipv4_address({_port}), lo); keep_doing([this] { return _listener->accept().then([this] (connected_socket fd, socket_address addr) mutable { - auto conn = make_shared(std::move(fd), addr, _cache, _system_stats); + auto conn = make_lw_shared(std::move(fd), addr, _cache, _system_stats); do_until([conn] { return conn->_in.eof(); }, [this, conn] { return conn->_proto.handle(conn->_in, conn->_out).then([conn] { return conn->_out.flush(); @@ -1818,7 +1818,7 @@ int start_instance(int ac, char** av) { if (WithFlashCache) { auto device_path = config["device"].as(); return engine.open_file_dma(device_path).then([&] (file f) { - auto dev = make_shared({std::move(f)}); + auto dev = make_lw_shared({std::move(f)}); return dev->f().stat().then([&, dev] (struct stat st) mutable { assert(S_ISBLK(st.st_mode)); return dev->f().size().then([&, dev] (size_t device_size) mutable { diff --git a/core/future-util.hh b/core/future-util.hh index 7ec8065d2b..8c208b1adb 100644 --- a/core/future-util.hh +++ b/core/future-util.hh @@ -156,7 +156,7 @@ template struct reducer_with_get_traits { using result_type = decltype(std::declval().get()); using future_type = future; - static future_type maybe_call_get(future<> f, shared_ptr r) { + static future_type maybe_call_get(future<> f, lw_shared_ptr r) { return f.then([r = std::move(r)] () mutable { return make_ready_future(std::move(*r).get()); }); @@ -166,7 +166,7 @@ struct reducer_with_get_traits { template struct reducer_traits { using future_type = future<>; - static future_type maybe_call_get(future<> f, shared_ptr r) { + static future_type maybe_call_get(future<> f, lw_shared_ptr r) { return f.then([r = std::move(r)] {}); } }; @@ -188,7 +188,7 @@ auto map_reduce(Iterator begin, Iterator end, Mapper&& mapper, Reducer&& r) -> typename reducer_traits::future_type { - auto r_ptr = make_shared(std::forward(r)); + auto r_ptr = make_lw_shared(std::forward(r)); future<> ret = make_ready_future<>(); while (begin != end) { ret = mapper(*begin++).then([ret = std::move(ret), r_ptr] (auto value) mutable { diff --git a/core/memory.cc b/core/memory.cc index 8d3071d5c6..2ca58dbc23 100644 --- a/core/memory.cc +++ b/core/memory.cc @@ -742,7 +742,7 @@ void configure(std::vector m, if (hugetlbfs_path) { // std::function is copyable, but file_desc is not, so we must use // a shared_ptr to allow sys_alloc to be copied around - auto fdp = make_shared(file_desc::temporary(*hugetlbfs_path)); + auto fdp = make_lw_shared(file_desc::temporary(*hugetlbfs_path)); sys_alloc = [fdp] (optional where, size_t how_much) { return allocate_hugetlbfs_memory(*fdp, where, how_much); }; diff --git a/core/scollectd.cc b/core/scollectd.cc index b4f00dc69d..7c4744c370 100644 --- a/core/scollectd.cc +++ b/core/scollectd.cc @@ -286,7 +286,7 @@ private: typedef value_list_map::iterator iterator; typedef std::tuple context; - auto ctxt = make_shared(); + auto ctxt = make_lw_shared(); // note we're doing this unsynced since we assume // all registrations to this instance will be done on the diff --git a/core/shared_ptr.hh b/core/shared_ptr.hh index d397314675..82e398a104 100644 --- a/core/shared_ptr.hh +++ b/core/shared_ptr.hh @@ -8,20 +8,57 @@ #include #include +// This header defines two shared pointer facilities, lw_shared_ptr<> and +// shared_ptr<>, both modeled after std::shared_ptr<>. +// +// Unlike std::shared_ptr<>, neither of these implementations are thread +// safe, and two pointers sharing the same object must not be used in +// different threads. +// +// lw_shared_ptr<> is the more lightweight variant, with a lw_shared_ptr<> +// occupying just one machine word, and adding just one word to the shared +// object. However, it does not support polymorphism. +// +// shared_ptr<> is more expensive, with a pointer occupying two machine +// words, and with two words of overhead in the shared object. In return, +// it does support polymorphism. +// +// Both variants support shared_from_this() via enable_shared_from_this<> +// and lw_enable_shared_from_this<>(). +// + +template +class lw_shared_ptr; + template class shared_ptr; +template +class enable_lw_shared_from_this; + template class enable_shared_from_this; +template +lw_shared_ptr make_lw_shared(A&&... a); + +template +lw_shared_ptr make_lw_shared(T&& a); + +template +lw_shared_ptr make_lw_shared(T& a); + template shared_ptr make_shared(A&&... a); -template -shared_ptr make_shared(T&& a); +template +shared_ptr static_pointer_cast(const shared_ptr& p); -template -shared_ptr make_shared(T& a); +template +shared_ptr dynamic_pointer_cast(const shared_ptr& p); + +template +shared_ptr const_pointer_cast(const shared_ptr& p); // We want to support two use cases for shared_ptr: // @@ -43,18 +80,18 @@ shared_ptr make_shared(T& a); // CRTP from this to enable shared_from_this: template -class enable_shared_from_this { +class enable_lw_shared_from_this { long _count = 0; using ctor = T; T* to_value() { return static_cast(this); } T* to_internal_object() { return static_cast(this); } protected: - enable_shared_from_this& operator=(const enable_shared_from_this&) { return *this; } - enable_shared_from_this& operator=(enable_shared_from_this&&) { return *this; } + enable_lw_shared_from_this& operator=(const enable_lw_shared_from_this&) { return *this; } + enable_lw_shared_from_this& operator=(enable_lw_shared_from_this&&) { return *this; } public: - shared_ptr shared_from_this(); + lw_shared_ptr shared_from_this(); template - friend class shared_ptr; + friend class lw_shared_ptr; }; template @@ -71,64 +108,64 @@ struct shared_ptr_no_esft { template shared_ptr_no_esft(A&&... a) : _value(std::forward(a)...) {} template - friend class shared_ptr; + friend class lw_shared_ptr; }; template using shared_ptr_impl = std::conditional_t< - std::is_base_of, T>::value, - enable_shared_from_this, + std::is_base_of, T>::value, + enable_lw_shared_from_this, shared_ptr_no_esft >; template -class shared_ptr { +class lw_shared_ptr { mutable shared_ptr_impl* _p = nullptr; private: - shared_ptr(shared_ptr_impl* p) : _p(p) { + lw_shared_ptr(shared_ptr_impl* p) : _p(p) { if (_p) { ++_p->_count; } } template - static shared_ptr make(A&&... a) { - return shared_ptr(new typename shared_ptr_impl::ctor(std::forward(a)...)); + static lw_shared_ptr make(A&&... a) { + return lw_shared_ptr(new typename shared_ptr_impl::ctor(std::forward(a)...)); } public: using element_type = T; - shared_ptr() = default; - shared_ptr(const shared_ptr& x) : _p(x._p) { + lw_shared_ptr() = default; + lw_shared_ptr(const lw_shared_ptr& x) : _p(x._p) { if (_p) { ++_p->_count; } } - shared_ptr(shared_ptr&& x) : _p(x._p) { + lw_shared_ptr(lw_shared_ptr&& x) : _p(x._p) { x._p = nullptr; } - ~shared_ptr() { + ~lw_shared_ptr() { if (_p && !--_p->_count) { delete _p->to_internal_object(); } } - shared_ptr& operator=(const shared_ptr& x) { + lw_shared_ptr& operator=(const lw_shared_ptr& x) { if (_p != x._p) { - this->~shared_ptr(); - new (this) shared_ptr(x); + this->~lw_shared_ptr(); + new (this) lw_shared_ptr(x); } return *this; } - shared_ptr& operator=(shared_ptr&& x) { + lw_shared_ptr& operator=(lw_shared_ptr&& x) { if (_p != x._p) { - this->~shared_ptr(); - new (this) shared_ptr(std::move(x)); + this->~lw_shared_ptr(); + new (this) lw_shared_ptr(std::move(x)); } return *this; } - shared_ptr& operator=(T&& x) { - this->~shared_ptr(); - new (this) shared_ptr(make_shared(std::move(x))); + lw_shared_ptr& operator=(T&& x) { + this->~lw_shared_ptr(); + new (this) lw_shared_ptr(make_lw_shared(std::move(x))); return *this; } @@ -144,8 +181,8 @@ public: } } - operator shared_ptr() const { - return shared_ptr(_p); + operator lw_shared_ptr() const { + return lw_shared_ptr(_p); } explicit operator bool() const { @@ -157,34 +194,235 @@ public: } template - friend shared_ptr make_shared(A&&...); + friend lw_shared_ptr make_lw_shared(A&&...); template - friend shared_ptr make_shared(U&&); + friend lw_shared_ptr make_lw_shared(U&&); template - friend shared_ptr make_shared(U&); + friend lw_shared_ptr make_lw_shared(U&); template - friend class enable_shared_from_this; + friend class enable_lw_shared_from_this; }; template inline -shared_ptr make_shared(A&&... a) { - return shared_ptr::make(std::forward(a)...); +lw_shared_ptr make_lw_shared(A&&... a) { + return lw_shared_ptr::make(std::forward(a)...); } template inline -shared_ptr make_shared(T&& a) { - return shared_ptr::make(std::move(a)); +lw_shared_ptr make_lw_shared(T&& a) { + return lw_shared_ptr::make(std::move(a)); } template inline -shared_ptr make_shared(T& a) { - return shared_ptr::make(a); +lw_shared_ptr make_lw_shared(T& a) { + return lw_shared_ptr::make(a); +} + +template +inline +lw_shared_ptr +enable_lw_shared_from_this::shared_from_this() { + return lw_shared_ptr(this); +} + +// Polymorphic shared pointer class + +struct shared_ptr_count_base { + // destructor is responsible for fully-typed deletion + virtual ~shared_ptr_count_base() {} + long count = 0; +}; + +template +struct shared_ptr_count_for : shared_ptr_count_base { + T data; + template + shared_ptr_count_for(A&&... a) : data(std::forward(a)...) {} +}; + +template +class enable_shared_from_this : private shared_ptr_count_base { +public: + shared_ptr shared_from_this(); + + template + friend class shared_ptr; +}; + +template +class shared_ptr { + mutable shared_ptr_count_base* _b = nullptr; + mutable T* _p = nullptr; +private: + explicit shared_ptr(shared_ptr_count_for* b) : _b(b), _p(&b->data) { + ++_b->count; + } + shared_ptr(shared_ptr_count_for* b, T* p) : _b(b), _p(p) { + // test _p, not _b, since dynamic_pointer_cast<>() can zero p but not b + if (_p) { + ++_b->count; + } + } + explicit shared_ptr(enable_shared_from_this* p) : _b(p), _p(static_cast(p)) { + if (_b) { + ++_b->count; + } + } +public: + shared_ptr() = default; + shared_ptr(const shared_ptr& x) + : _b(x._b) + , _p(x._p) { + if (_b) { + ++_b->count; + } + } + shared_ptr(shared_ptr&& x) + : _b(x._b) + , _p(x._p) { + x._b = nullptr; + x._p = nullptr; + } + template ::value>> + shared_ptr(const shared_ptr& x) + : _b(x._b) + , _p(x._p) { + if (_b) { + ++_b->count; + } + } + template ::value>> + shared_ptr(shared_ptr&& x) + : _b(x._b) + , _p(x._p) { + x._b = nullptr; + x._p = nullptr; + } + ~shared_ptr() { + if (_b && !--_b->count) { + delete _b; + } + } + shared_ptr& operator=(const shared_ptr& x) { + if (this != &x) { + this->~shared_ptr(); + new (this) shared_ptr(x); + } + return *this; + } + shared_ptr& operator=(shared_ptr&& x) { + if (this != &x) { + this->~shared_ptr(); + new (this) shared_ptr(std::move(x)); + } + return *this; + } + template ::value>> + shared_ptr& operator=(const shared_ptr& x) { + if (this != &x) { + this->~shared_ptr(); + new (this) shared_ptr(x); + } + return *this; + } + template ::value>> + shared_ptr& operator=(shared_ptr&& x) { + if (this != &x) { + this->~shared_ptr(); + new (this) shared_ptr(std::move(x)); + } + return *this; + } + explicit operator bool() const { + return _p; + } + T& operator*() const{ + return *_p; + } + T* operator->() const { + return _p; + } + T* get() const { + return _p; + } + + template + struct make_helper; + + template + friend shared_ptr make_shared(A&&... a); + + template + friend shared_ptr static_pointer_cast(const shared_ptr& p); + + template + friend shared_ptr dynamic_pointer_cast(const shared_ptr& p); + + template + friend shared_ptr const_pointer_cast(const shared_ptr& p); + + template + static shared_ptr make(A&&... a); + + template + friend class enable_shared_from_this; + + template + friend struct shared_ptr_make_helper; +}; + +template +struct shared_ptr_make_helper; + +template +struct shared_ptr_make_helper { + template + static shared_ptr make(A&&... a) { + return shared_ptr(new shared_ptr_count_for(std::forward(a)...)); + } +}; + +template +struct shared_ptr_make_helper { + template + static shared_ptr make(A&&... a) { + return shared_ptr(new T(std::forward(a)...)); + } +}; + +template +inline +shared_ptr +make_shared(A&&... a) { + using helper = shared_ptr_make_helper, T>::value>; + return helper::make(std::forward(a)...); +} + +template +inline +shared_ptr +static_pointer_cast(const shared_ptr& p) { + return shared_ptr(p->_b, static_cast(p._p)); +} + +template +inline +shared_ptr +dynamic_pointer_cast(const shared_ptr& p) { + return shared_ptr(p->_b, dynamic_cast(p._p)); +} + +template +inline +shared_ptr +const_pointer_cast(const shared_ptr& p) { + return shared_ptr(p->_b, const_cast(p._p)); } template diff --git a/net/ip.cc b/net/ip.cc index 5dafa286cc..fbbc932b3c 100644 --- a/net/ip.cc +++ b/net/ip.cc @@ -247,7 +247,7 @@ future<> ipv4::send(ipv4_address to, ip_protocol_num proto_num, packet p) { uint16_t remaining; uint16_t offset; }; - auto si = make_shared({std::move(p), remaining, offset}); + auto si = make_lw_shared({std::move(p), remaining, offset}); auto stop = [si] { return si->remaining == 0; }; auto send_frag = [this, send_pkt, si] () mutable { auto& remaining = si->remaining; diff --git a/net/native-stack.cc b/net/native-stack.cc index 0e1b1faa97..7aa80e0826 100644 --- a/net/native-stack.cc +++ b/net/native-stack.cc @@ -184,7 +184,7 @@ native_network_stack::listen(socket_address sa, listen_options opts) { using namespace std::chrono_literals; future<> native_network_stack::run_dhcp(bool is_renew, const dhcp::lease& res) { - shared_ptr d = make_shared(_inet); + lw_shared_ptr d = make_lw_shared(_inet); // Hijack the ip-stack. for (unsigned i = 0; i < smp::count; i++) { diff --git a/net/tcp.hh b/net/tcp.hh index 9d03e61d93..aa1656fc73 100644 --- a/net/tcp.hh +++ b/net/tcp.hh @@ -148,7 +148,7 @@ public: private: class tcb; - class tcb : public enable_shared_from_this { + class tcb : public enable_lw_shared_from_this { using clock_type = lowres_clock; // Instead of tracking state through an enum, track individual // bits of the state. This reduces duplication in state handling. @@ -298,13 +298,13 @@ private: friend class connection; }; inet_type& _inet; - std::unordered_map, connid_hash> _tcbs; + std::unordered_map, connid_hash> _tcbs; std::unordered_map _listening; public: class connection { - shared_ptr _tcb; + lw_shared_ptr _tcb; public: - explicit connection(shared_ptr tcbp) : _tcb(std::move(tcbp)) { _tcb->_conn = this; } + explicit connection(lw_shared_ptr tcbp) : _tcb(std::move(tcbp)) { _tcb->_conn = this; } connection(const connection&) = delete; connection(connection&& x) noexcept : _tcb(std::move(x._tcb)) { _tcb->_conn = this; @@ -406,14 +406,14 @@ void tcp::received(packet p, ipaddr from, ipaddr to) { auto h = ntoh(*th); auto id = connid{to, from, h.dst_port, h.src_port}; auto tcbi = _tcbs.find(id); - shared_ptr tcbp; + lw_shared_ptr tcbp; if (tcbi == _tcbs.end()) { if (h.f_syn && !h.f_ack) { auto listener = _listening.find(id.local_port); if (listener == _listening.end() || listener->second->_q.full()) { return respond_with_reset(&h, id.local_ip, id.foreign_ip); } - tcbp = make_shared(*this, id); + tcbp = make_lw_shared(*this, id); listener->second->_q.push(connection(tcbp)); _tcbs.insert({id, tcbp}); } diff --git a/net/udp.cc b/net/udp.cc index 719c10501b..f95109d4bf 100644 --- a/net/udp.cc +++ b/net/udp.cc @@ -46,9 +46,9 @@ private: udp_v4& _proto; udp_v4::registration _reg; bool _closed; - shared_ptr _state; + lw_shared_ptr _state; public: - native_channel(udp_v4 &proto, udp_v4::registration reg, shared_ptr state) + native_channel(udp_v4 &proto, udp_v4::registration reg, lw_shared_ptr state) : _proto(proto) , _reg(reg) , _closed(false) @@ -168,7 +168,7 @@ udp_v4::make_channel(ipv4_addr addr) { _next_anonymous_port = next_port(_next_anonymous_port); } - auto chan_state = make_shared(_queue_size); + auto chan_state = make_lw_shared(_queue_size); _channels[bind_port] = chan_state; return udp_channel(std::make_unique(*this, registration(*this, bind_port), chan_state)); } diff --git a/net/udp.hh b/net/udp.hh index 43064942eb..f25a214553 100644 --- a/net/udp.hh +++ b/net/udp.hh @@ -49,7 +49,7 @@ public: private: static const uint16_t min_anonymous_port = 32768; ipv4 &_inet; - std::unordered_map> _channels; + std::unordered_map> _channels; int _queue_size = default_queue_size; uint16_t _next_anonymous_port = min_anonymous_port; private: diff --git a/tests/memcached/test_ascii_parser.cc b/tests/memcached/test_ascii_parser.cc index 5b28038c25..622ae616c7 100644 --- a/tests/memcached/test_ascii_parser.cc +++ b/tests/memcached/test_ascii_parser.cc @@ -33,11 +33,11 @@ static auto make_input_stream(packet&& p) { } static auto parse(packet&& p) { - auto is = make_shared(make_input_stream(std::move(p))); - auto parser = make_shared(); + auto is = make_lw_shared>(make_input_stream(std::move(p))); + auto parser = make_lw_shared(); parser->init(); return is->consume(*parser).then([is, parser] { - return make_ready_future>(parser); + return make_ready_future>(parser); }); } @@ -259,7 +259,7 @@ SEASTAR_TEST_CASE(test_catches_errors_in_get) { SEASTAR_TEST_CASE(test_parser_returns_eof_state_when_no_command_follows) { return for_each_fragment_size([] (auto make_packet) { auto p = make_shared(); - auto is = make_shared(make_input_stream(make_packet({"get key\r\n"}))); + auto is = make_shared>(make_input_stream(make_packet({"get key\r\n"}))); p->init(); return is->consume(*p).then([p] { BOOST_REQUIRE(p->_state == parser_type::state::cmd_get); @@ -275,7 +275,7 @@ SEASTAR_TEST_CASE(test_parser_returns_eof_state_when_no_command_follows) { SEASTAR_TEST_CASE(test_incomplete_command_is_an_error) { return for_each_fragment_size([] (auto make_packet) { auto p = make_shared(); - auto is = make_shared(make_input_stream(make_packet({"get"}))); + auto is = make_shared>(make_input_stream(make_packet({"get"}))); p->init(); return is->consume(*p).then([p] { BOOST_REQUIRE(p->_state == parser_type::state::error); @@ -291,7 +291,7 @@ SEASTAR_TEST_CASE(test_incomplete_command_is_an_error) { SEASTAR_TEST_CASE(test_multiple_requests_in_one_stream) { return for_each_fragment_size([] (auto make_packet) { auto p = make_shared(); - auto is = make_shared(make_input_stream(make_packet({"set key1 1 1 5\r\ndata1\r\nset key2 2 2 6\r\ndata2+\r\n"}))); + auto is = make_shared>(make_input_stream(make_packet({"set key1 1 1 5\r\ndata1\r\nset key2 2 2 6\r\ndata2+\r\n"}))); p->init(); return is->consume(*p).then([p] { BOOST_REQUIRE(p->_state == parser_type::state::cmd_set); diff --git a/tests/output_stream_test.cc b/tests/output_stream_test.cc index d59bc1013d..cc68b279e0 100644 --- a/tests/output_stream_test.cc +++ b/tests/output_stream_test.cc @@ -37,8 +37,8 @@ struct stream_maker { return std::move(*this); } - shared_ptr> operator()(data_sink sink) { - return make_shared>(std::move(sink), _size, _trim); + lw_shared_ptr> operator()(data_sink sink) { + return make_lw_shared>(std::move(sink), _size, _trim); } }; @@ -47,8 +47,8 @@ future<> assert_split(StreamConstructor stream_maker, std::initializer_list w std::vector expected_split) { static int i = 0; BOOST_TEST_MESSAGE("checking split: " << i++); - auto sh_write_calls = make_shared(std::move(write_calls)); - auto sh_expected_splits = make_shared(std::move(expected_split)); + auto sh_write_calls = make_lw_shared>(std::move(write_calls)); + auto sh_expected_splits = make_lw_shared>(std::move(expected_split)); auto v = make_shared>(); auto out = stream_maker(data_sink(std::make_unique(*v))); diff --git a/tests/udp_zero_copy.cc b/tests/udp_zero_copy.cc index 66222cfac1..4e12443853 100644 --- a/tests/udp_zero_copy.cc +++ b/tests/udp_zero_copy.cc @@ -85,7 +85,7 @@ public: keep_doing([this] { return _chan.receive().then([this] (udp_datagram dgram) { auto chunk = next_chunk(); - shared_ptr item; + lw_shared_ptr item; if (_copy) { _packets.clear(); _out->write(chunk, _chunk_size);