diff options
author | Alan Conway <aconway@apache.org> | 2011-03-15 01:49:37 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2011-03-15 01:49:37 +0000 |
commit | a537010f4dc49fbcb05820eefa132c879f96b7ba (patch) | |
tree | f2d58ff36aa968d461b284d2b74a534cfaf077eb /cpp | |
parent | 5f3fc9ce1861acb0ccb912f9a2326c82f0ad760c (diff) | |
download | qpid-python-a537010f4dc49fbcb05820eefa132c879f96b7ba.tar.gz |
NO-JIRA: Refactor RefCountedBuffer to be simpler and more flexible.
RefCountedBuffer::pointer is replaced by a separate class BufferRef.
BufferRef is independent of RefCountedBuffer, it can be used to manage other
reference-counted buffer classes e.g. to implement buffer pools.
BufferRef also provides beginning and end of the buffer, not just beginning.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1081631 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Makefile.am | 9 | ||||
-rw-r--r-- | cpp/src/qpid/BufferRef.h | 70 | ||||
-rw-r--r-- | cpp/src/qpid/RefCountedBuffer.cpp | 22 | ||||
-rw-r--r-- | cpp/src/qpid/RefCountedBuffer.h | 61 | ||||
-rw-r--r-- | cpp/src/qpid/cluster/Event.cpp | 5 | ||||
-rw-r--r-- | cpp/src/qpid/cluster/Event.h | 12 |
6 files changed, 98 insertions, 81 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am index dfb2547613..0820a7a29a 100644 --- a/cpp/src/Makefile.am +++ b/cpp/src/Makefile.am @@ -176,7 +176,7 @@ nobase_include_HEADERS += \ ../include/qpid/sys/posix/Time.h \ ../include/qpid/sys/posix/check.h -if HAVE_EPOLL +if HAVE_EPOLL poller = qpid/sys/epoll/EpollPoller.cpp endif @@ -195,7 +195,7 @@ libqpidcommon_la_SOURCES += $(poller) $(systeminfo) posix_broker_src = \ qpid/broker/posix/BrokerDefaults.cpp -lib_LTLIBRARIES = libqpidtypes.la libqpidcommon.la libqpidbroker.la libqpidclient.la libqpidmessaging.la +lib_LTLIBRARIES = libqpidtypes.la libqpidcommon.la libqpidbroker.la libqpidclient.la libqpidmessaging.la # Definitions for client and daemon plugins PLUGINLDFLAGS=-no-undefined -module -avoid-version @@ -203,7 +203,7 @@ confdir=$(sysconfdir)/qpid dmoduledir=$(libdir)/qpid/daemon cmoduledir=$(libdir)/qpid/client dmodule_LTLIBRARIES = -cmodule_LTLIBRARIES = +cmodule_LTLIBRARIES = include cluster.mk include acl.mk @@ -341,6 +341,7 @@ libqpidcommon_la_SOURCES += \ qpid/RefCounted.h \ qpid/RefCountedBuffer.cpp \ qpid/RefCountedBuffer.h \ + qpid/BufferRef.h \ qpid/Sasl.h \ qpid/SaslFactory.cpp \ qpid/SaslFactory.h \ @@ -892,6 +893,6 @@ dist-hook: $(BUILT_SOURCES) install-data-local: $(mkinstalldirs) $(DESTDIR)/$(localstatedir)/lib/qpidd -# Support for pkg-config +# Support for pkg-config pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = qpid.pc diff --git a/cpp/src/qpid/BufferRef.h b/cpp/src/qpid/BufferRef.h new file mode 100644 index 0000000000..bfe1f9ebaa --- /dev/null +++ b/cpp/src/qpid/BufferRef.h @@ -0,0 +1,70 @@ +#ifndef QPID_BUFFERREF_H +#define QPID_BUFFERREF_H + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/RefCounted.h" +#include <boost/intrusive_ptr.hpp> + +namespace qpid { + +/** Template for mutable or const buffer references */ +template <class T> class BufferRefT { + public: + BufferRefT() : begin_(0), end_(0) {} + + BufferRefT(boost::intrusive_ptr<RefCounted> c, T* begin, T* end) : + counter(c), begin_(begin), end_(end) {} + + template <class U> BufferRefT(const BufferRefT<U>& other) : + counter(other.counter), begin_(other.begin_), end_(other.end_) {} + + T* begin() const { return begin_; } + T* end() const { return end_; } + + /** Return a sub-buffer of the current buffer */ + BufferRefT sub_buffer(T* begin, T* end) { + assert(begin_ <= begin && begin <= end_); + assert(begin_ <= end && end <= end_); + assert(begin <= end); + return BufferRefT(counter, begin, end); + } + + private: + boost::intrusive_ptr<RefCounted> counter; + T* begin_; + T* end_; +}; + +/** + * Reference to a mutable ref-counted buffer. + */ +typedef BufferRefT<char> BufferRef; + +/** + * Reference to a const ref-counted buffer. + */ +typedef BufferRefT<const char> ConstBufferRef; + +} // namespace qpid + +#endif /*!QPID_BUFFERREF_H*/ diff --git a/cpp/src/qpid/RefCountedBuffer.cpp b/cpp/src/qpid/RefCountedBuffer.cpp index 9b8f1ebd5e..40d620f7ad 100644 --- a/cpp/src/qpid/RefCountedBuffer.cpp +++ b/cpp/src/qpid/RefCountedBuffer.cpp @@ -24,30 +24,20 @@ namespace qpid { -RefCountedBuffer::RefCountedBuffer() : count(0) {} - -void RefCountedBuffer::destroy() const { +void RefCountedBuffer::released() const { this->~RefCountedBuffer(); ::delete[] reinterpret_cast<const char*>(this); } -char* RefCountedBuffer::addr() const { - return const_cast<char*>(reinterpret_cast<const char*>(this)+sizeof(RefCountedBuffer)); -} - -RefCountedBuffer::pointer RefCountedBuffer::create(size_t n) { +BufferRef RefCountedBuffer::create(size_t n) { char* store=::new char[n+sizeof(RefCountedBuffer)]; new(store) RefCountedBuffer; - return pointer(reinterpret_cast<RefCountedBuffer*>(store)); + char* start = store+sizeof(RefCountedBuffer); + return BufferRef( + boost::intrusive_ptr<RefCounted>(reinterpret_cast<RefCountedBuffer*>(store)), + start, start+n); } -RefCountedBuffer::pointer::pointer() {} -RefCountedBuffer::pointer::pointer(RefCountedBuffer* x) : p(x) {} -RefCountedBuffer::pointer::pointer(const pointer& x) : p(x.p) {} -RefCountedBuffer::pointer::~pointer() {} -RefCountedBuffer::pointer& RefCountedBuffer::pointer::operator=(const RefCountedBuffer::pointer& x) { p = x.p; return *this; } - -char* RefCountedBuffer::pointer::cp() const { return p ? p->get() : 0; } } // namespace qpid diff --git a/cpp/src/qpid/RefCountedBuffer.h b/cpp/src/qpid/RefCountedBuffer.h index 75a23862be..f0ea86130b 100644 --- a/cpp/src/qpid/RefCountedBuffer.h +++ b/cpp/src/qpid/RefCountedBuffer.h @@ -22,68 +22,23 @@ * */ -#include <boost/utility.hpp> -#include <boost/detail/atomic_count.hpp> -#include <boost/intrusive_ptr.hpp> +#include <qpid/RefCounted.h> +#include <qpid/BufferRef.h> namespace qpid { /** - * Reference-counted byte buffer. - * No alignment guarantees. + * Reference-counted byte buffer. No alignment guarantees. */ -class RefCountedBuffer : boost::noncopyable { - mutable boost::detail::atomic_count count; - RefCountedBuffer(); - void destroy() const; - char* addr() const; - -public: - /** Smart char pointer to a reference counted buffer */ - class pointer { - boost::intrusive_ptr<RefCountedBuffer> p; - char* cp() const; - pointer(RefCountedBuffer* x); - friend class RefCountedBuffer; - - public: - pointer(); - pointer(const pointer&); - ~pointer(); - pointer& operator=(const pointer&); - - char* get() { return cp(); } - operator char*() { return cp(); } - char& operator*() { return *cp(); } - char& operator[](size_t i) { return cp()[i]; } - - const char* get() const { return cp(); } - operator const char*() const { return cp(); } - const char& operator*() const { return *cp(); } - const char& operator[](size_t i) const { return cp()[i]; } - }; - +class RefCountedBuffer : public RefCounted { + public: /** Create a reference counted buffer of size n */ - static pointer create(size_t n); - - /** Get a pointer to the start of the buffer. */ - char* get() { return addr(); } - const char* get() const { return addr(); } - char& operator[](size_t i) { return get()[i]; } - const char& operator[](size_t i) const { return get()[i]; } + static BufferRef create(size_t n); - void addRef() const { ++count; } - void release() const { if (--count==0) destroy(); } - long refCount() { return count; } + protected: + void released() const; }; } // namespace qpid -// intrusive_ptr support. -namespace boost { -inline void intrusive_ptr_add_ref(const qpid::RefCountedBuffer* p) { p->addRef(); } -inline void intrusive_ptr_release(const qpid::RefCountedBuffer* p) { p->release(); } -} - - #endif /*!QPID_REFCOUNTEDBUFFER_H*/ diff --git a/cpp/src/qpid/cluster/Event.cpp b/cpp/src/qpid/cluster/Event.cpp index cd775ce2f1..da2bc89d8c 100644 --- a/cpp/src/qpid/cluster/Event.cpp +++ b/cpp/src/qpid/cluster/Event.cpp @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -23,6 +23,7 @@ #include "qpid/cluster/Cpg.h" #include "qpid/framing/Buffer.h" #include "qpid/framing/AMQFrame.h" +#include "qpid/RefCountedBuffer.h" #include "qpid/assert.h" #include <ostream> #include <iterator> diff --git a/cpp/src/qpid/cluster/Event.h b/cpp/src/qpid/cluster/Event.h index c2dca073d1..13283edff7 100644 --- a/cpp/src/qpid/cluster/Event.h +++ b/cpp/src/qpid/cluster/Event.h @@ -23,7 +23,7 @@ */ #include "qpid/cluster/types.h" -#include "qpid/RefCountedBuffer.h" +#include "qpid/BufferRef.h" #include "qpid/framing/AMQFrame.h" #include <sys/uio.h> // For iovec #include <iosfwd> @@ -88,12 +88,12 @@ class Event : public EventHeader { static Event control(const framing::AMQFrame&, const ConnectionId&); // Data excluding header. - char* getData() { return store + HEADER_SIZE; } - const char* getData() const { return store + HEADER_SIZE; } + char* getData() { return store.begin() + HEADER_SIZE; } + const char* getData() const { return store.begin() + HEADER_SIZE; } // Store including header - char* getStore() { return store; } - const char* getStore() const { return store; } + char* getStore() { return store.begin(); } + const char* getStore() const { return store.begin(); } const framing::AMQFrame& getFrame() const; @@ -104,7 +104,7 @@ class Event : public EventHeader { private: void encodeHeader() const; - RefCountedBuffer::pointer store; + BufferRef store; mutable framing::AMQFrame frame; }; |