summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2011-03-15 01:49:37 +0000
committerAlan Conway <aconway@apache.org>2011-03-15 01:49:37 +0000
commita537010f4dc49fbcb05820eefa132c879f96b7ba (patch)
treef2d58ff36aa968d461b284d2b74a534cfaf077eb /cpp
parent5f3fc9ce1861acb0ccb912f9a2326c82f0ad760c (diff)
downloadqpid-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.am9
-rw-r--r--cpp/src/qpid/BufferRef.h70
-rw-r--r--cpp/src/qpid/RefCountedBuffer.cpp22
-rw-r--r--cpp/src/qpid/RefCountedBuffer.h61
-rw-r--r--cpp/src/qpid/cluster/Event.cpp5
-rw-r--r--cpp/src/qpid/cluster/Event.h12
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;
};