From 4f42e5c54f2513e4ea021ac9494d9397dfeec58a Mon Sep 17 00:00:00 2001 From: "Charles E. Rolke" Date: Wed, 21 Dec 2011 17:55:59 +0000 Subject: QPID-3193 Major update provides locks and checks for disposed objects. * White space police: tabs, trailing white, reformat source per Visual Studio ^k ^f. * Changed native object pointer names to nativeObjPtr for all classes. * Reviewed at https://reviews.apache.org/r/3239 * No macros - all code expanded in-line. * msclr::lock scoped locks use per-object private lock and not 'this'. * References to native functions of disposed (.NET Dispose, C++ delete) objects throws ObjectDisposedException. * Each object gets an IsDisposed property for diagnostic purposes. * Unused file Duration.cpp is deleted. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1221824 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/bindings/qpid/dotnet/src/Address.cpp | 213 +++++---- cpp/bindings/qpid/dotnet/src/Address.h | 102 +++- cpp/bindings/qpid/dotnet/src/Connection.cpp | 280 ++++++----- cpp/bindings/qpid/dotnet/src/Connection.h | 57 ++- cpp/bindings/qpid/dotnet/src/Duration.cpp | 107 ----- cpp/bindings/qpid/dotnet/src/Duration.h | 16 +- cpp/bindings/qpid/dotnet/src/FailoverUpdates.cpp | 41 +- cpp/bindings/qpid/dotnet/src/FailoverUpdates.h | 25 +- cpp/bindings/qpid/dotnet/src/Message.cpp | 555 ++++++++++++---------- cpp/bindings/qpid/dotnet/src/Message.h | 227 ++++++--- cpp/bindings/qpid/dotnet/src/QpidException.h | 8 +- cpp/bindings/qpid/dotnet/src/QpidMarshal.h | 10 +- cpp/bindings/qpid/dotnet/src/QpidTypeCheck.h | 14 +- cpp/bindings/qpid/dotnet/src/ReadMe.txt | 10 +- cpp/bindings/qpid/dotnet/src/Receiver.cpp | 201 ++++---- cpp/bindings/qpid/dotnet/src/Receiver.h | 74 ++- cpp/bindings/qpid/dotnet/src/Sender.cpp | 140 +++--- cpp/bindings/qpid/dotnet/src/Sender.h | 81 +++- cpp/bindings/qpid/dotnet/src/Session.cpp | 574 +++++++++++++---------- cpp/bindings/qpid/dotnet/src/Session.h | 72 ++- cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp | 66 +-- cpp/bindings/qpid/dotnet/src/TypeTranslator.h | 12 +- cpp/bindings/qpid/dotnet/src/resource1.h | 2 +- 23 files changed, 1677 insertions(+), 1210 deletions(-) delete mode 100644 cpp/bindings/qpid/dotnet/src/Duration.cpp (limited to 'cpp') diff --git a/cpp/bindings/qpid/dotnet/src/Address.cpp b/cpp/bindings/qpid/dotnet/src/Address.cpp index 79a8021d9a..67484df1c4 100644 --- a/cpp/bindings/qpid/dotnet/src/Address.cpp +++ b/cpp/bindings/qpid/dotnet/src/Address.cpp @@ -40,25 +40,34 @@ namespace Messaging { /// Address is a managed wrapper for a qpid::messaging::Address /// + // Disallow access if object has been destroyed. + void Address::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // Create empty Address::Address() { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address(QpidMarshal::ToNative("")); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address(QpidMarshal::ToNative("")); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Create string address @@ -66,79 +75,82 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address(QpidMarshal::ToNative(address)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address(QpidMarshal::ToNative(address)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Create with options - Address::Address(System::String ^ name, - System::String ^ subject, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options) + Address::Address(System::String ^ name, + System::String ^ subject, + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options) { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address(); + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address(); Name = name; Subject = subject; Options = options; Type = ""; - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Create with options and type - Address::Address(System::String ^ name, - System::String ^ subject, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options, - System::String ^ type) + Address::Address(System::String ^ name, + System::String ^ subject, + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options, + System::String ^ type) { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address(); + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address(); Name = name; Subject = subject; Options = options; Type = type; - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor look-alike (C#) @@ -146,21 +158,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address( - *(const_cast
(address)->NativeAddress)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address( + *(const_cast
(address)->NativeAddress)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) @@ -168,21 +181,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address( - *(const_cast
(address).NativeAddress)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address( + *(const_cast
(address).NativeAddress)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // unmanaged clone @@ -190,20 +204,21 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - addressp = new ::qpid::messaging::Address(addrp); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Address(addrp); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Destructor @@ -216,12 +231,15 @@ namespace Messaging { // Finalizer Address::!Address() { - msclr::lock lk(this); - - if (NULL != addressp) + if (NULL != nativeObjPtr) { - delete addressp; - addressp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } @@ -233,20 +251,23 @@ namespace Messaging { System::String ^ result = nullptr; System::Exception ^ newException = nullptr; - try - { - result = gcnew System::String(addressp->str().c_str()); - } - catch (const ::qpid::types::Exception & error) - { + try + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + result = gcnew System::String(nativeObjPtr->str().c_str()); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return result; } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/Address.h b/cpp/bindings/qpid/dotnet/src/Address.h index 8bbc207d4e..108a265923 100644 --- a/cpp/bindings/qpid/dotnet/src/Address.h +++ b/cpp/bindings/qpid/dotnet/src/Address.h @@ -44,23 +44,29 @@ namespace Messaging { { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::Address * addressp; + ::qpid::messaging::Address * nativeObjPtr; + + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); public: Address(); - + Address(System::String ^ address); Address(System::String ^ name, - System::String ^ subject, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options); - + System::String ^ subject, + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options); + Address(System::String ^ name, - System::String ^ subject, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options, - System::String ^ type); + System::String ^ subject, + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options, + System::String ^ type); // copy constructor Address(const Address ^ address); @@ -69,29 +75,51 @@ namespace Messaging { // unmanaged clone Address(const ::qpid::messaging::Address & addrp); + // System destructor/finalizer entry points ~Address(); !Address(); // assignment operator Address % operator=(const Address % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != addressp) - delete addressp; - addressp = new ::qpid::messaging::Address( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Address( *(const_cast
(rhs).NativeAddress) ); } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + + // + // NativeAddress + // property ::qpid::messaging::Address * NativeAddress { - ::qpid::messaging::Address * get () { return addressp; } + ::qpid::messaging::Address * get () + { + return nativeObjPtr; + } } // @@ -101,12 +129,18 @@ namespace Messaging { { System::String ^ get () { - return gcnew System::String(addressp->getName().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getName().c_str()); } void set (System::String ^ name) { - addressp->::qpid::messaging::Address::setName(QpidMarshal::ToNative(name)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->::qpid::messaging::Address::setName(QpidMarshal::ToNative(name)); } } @@ -118,12 +152,18 @@ namespace Messaging { { System::String ^ get () { - return gcnew System::String(addressp->getSubject().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getSubject().c_str()); } void set (System::String ^ subject) { - addressp->setSubject(QpidMarshal::ToNative(subject)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setSubject(QpidMarshal::ToNative(subject)); } } @@ -137,23 +177,29 @@ namespace Messaging { System::Collections::Generic::Dictionary< System::String ^, System::Object ^> ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::types::Variant::Map map; System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ newMap = + System::String ^, System::Object ^> ^ newMap = gcnew System::Collections::Generic::Dictionary< - System::String ^, System::Object ^>; - map = addressp->getOptions(); + System::String ^, System::Object ^>; + map = nativeObjPtr->getOptions(); TypeTranslator::NativeToManaged(map, newMap); return newMap; } void set (System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options) + System::String ^, System::Object ^> ^ options) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::types::Variant::Map map; TypeTranslator::ManagedToNative(options, map); - addressp->setOptions(map); + nativeObjPtr->setOptions(map); } } @@ -165,13 +211,19 @@ namespace Messaging { { System::String ^ get () { - return gcnew System::String(addressp->getType().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getType().c_str()); } void set (System::String ^ type) { - addressp->setType(QpidMarshal::ToNative(type)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setType(QpidMarshal::ToNative(type)); } } diff --git a/cpp/bindings/qpid/dotnet/src/Connection.cpp b/cpp/bindings/qpid/dotnet/src/Connection.cpp index 12c0e29f74..011c720bdc 100644 --- a/cpp/bindings/qpid/dotnet/src/Connection.cpp +++ b/cpp/bindings/qpid/dotnet/src/Connection.cpp @@ -42,53 +42,63 @@ namespace Messaging { /// Connection is a managed wrapper for a qpid::messaging::Connection /// + // Disallow access if object has been destroyed. + void Connection::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // constructors Connection::Connection(System::String ^ url) { System::Exception ^ newException = nullptr; - try - { - connectionp = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } Connection::Connection(System::String ^ url, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options) + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options) { System::Exception ^ newException = nullptr; - try - { - connectionp = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url)); + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url)); for each (System::Collections::Generic::KeyValuePair kvp in options) { SetOption(kvp.Key, kvp.Value); } - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -96,21 +106,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - connectionp = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url), - QpidMarshal::ToNative(options)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Connection(QpidMarshal::ToNative(url), + QpidMarshal::ToNative(options)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -119,21 +130,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - connectionp = new ::qpid::messaging::Connection( - *(const_cast(connection)->NativeConnection)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Connection( + *(const_cast(connection)->NativeConnection)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) @@ -141,21 +153,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - connectionp = new ::qpid::messaging::Connection( - *(const_cast(connection).NativeConnection)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Connection( + *(const_cast(connection).NativeConnection)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -169,12 +182,15 @@ namespace Messaging { // Finalizer Connection::!Connection() { - msclr::lock lk(this); - - if (NULL != connectionp) + if (NULL != nativeObjPtr) { - delete connectionp; - connectionp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } @@ -183,63 +199,72 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { + try + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::types::Variant entryValue; TypeTranslator::ManagedToNativeObject(value, entryValue); std::string entryName = QpidMarshal::ToNative(name); - connectionp->::qpid::messaging::Connection::setOption(entryName, entryValue); - } - catch (const ::qpid::types::Exception & error) - { + nativeObjPtr->::qpid::messaging::Connection::setOption(entryName, entryValue); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Connection::Open() { System::Exception ^ newException = nullptr; - try - { - connectionp->open(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->open(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Connection::Close() { System::Exception ^ newException = nullptr; - try - { - connectionp->close(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->close(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // @@ -258,14 +283,17 @@ namespace Messaging { try { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + // create native session - ::qpid::messaging::Session sessionp = - connectionp->createTransactionalSession(QpidMarshal::ToNative(name)); + ::qpid::messaging::Session sessionp = + nativeObjPtr->createTransactionalSession(QpidMarshal::ToNative(name)); // create managed session newSession = gcnew Session(sessionp, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -276,9 +304,9 @@ namespace Messaging { if (newException != nullptr) { if (newSession != nullptr) - { - delete newSession; - } + { + delete newSession; + } } } @@ -287,7 +315,7 @@ namespace Messaging { throw newException; } - return newSession; + return newSession; } @@ -307,14 +335,17 @@ namespace Messaging { try { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + // create native session - ::qpid::messaging::Session sessionp = - connectionp->createSession(QpidMarshal::ToNative(name)); + ::qpid::messaging::Session sessionp = + nativeObjPtr->createSession(QpidMarshal::ToNative(name)); // create managed session newSession = gcnew Session(sessionp, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -324,17 +355,17 @@ namespace Messaging { // Clean up and throw on caught exceptions if (newException != nullptr) { - if (newSession != nullptr) - { - delete newSession; - } + if (newSession != nullptr) + { + delete newSession; + } } } - if (nullptr != newException) - { - throw newException; - } + if (nullptr != newException) + { + throw newException; + } return newSession; } @@ -344,17 +375,20 @@ namespace Messaging { { System::Exception ^ newException = nullptr; Session ^ newSession = nullptr; - + try { const std::string n = QpidMarshal::ToNative(name); - ::qpid::messaging::Session sess = - connectionp->::qpid::messaging::Connection::getSession(n); - + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + ::qpid::messaging::Session sess = + nativeObjPtr->::qpid::messaging::Connection::getSession(n); + newSession = gcnew Session(sess, this); } - catch (const ::qpid::types::Exception & error) + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -364,17 +398,17 @@ namespace Messaging { // Clean up and throw on caught exceptions if (newException != nullptr) { - if (newSession != nullptr) - { - delete newSession; - } + if (newSession != nullptr) + { + delete newSession; + } } } - if (nullptr != newException) - { - throw newException; - } + if (nullptr != newException) + { + throw newException; + } return newSession; } diff --git a/cpp/bindings/qpid/dotnet/src/Connection.h b/cpp/bindings/qpid/dotnet/src/Connection.h index 0788f5d225..27381d8d5e 100644 --- a/cpp/bindings/qpid/dotnet/src/Connection.h +++ b/cpp/bindings/qpid/dotnet/src/Connection.h @@ -43,14 +43,20 @@ namespace Messaging { { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::Connection * connectionp; + ::qpid::messaging::Connection * nativeObjPtr; + + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); public: Connection(System::String ^ url); - Connection(System::String ^ url, - System::Collections::Generic::Dictionary< - System::String ^, System::Object ^> ^ options); + Connection(System::String ^ url, + System::Collections::Generic::Dictionary< + System::String ^, System::Object ^> ^ options); Connection(System::String ^ url, System::String ^ options); @@ -58,8 +64,8 @@ namespace Messaging { Connection(const Connection ^ connection); Connection(const Connection % connection); - // unmanaged clone - // not defined + // unmanaged clone + // not defined ~Connection(); !Connection(); @@ -67,23 +73,44 @@ namespace Messaging { // assignment operator Connection % operator=(const Connection % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != connectionp) - delete connectionp; - connectionp = new ::qpid::messaging::Connection( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Connection( *(const_cast(rhs).NativeConnection) ); } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + + // + // NativeConnection + // property ::qpid::messaging::Connection * NativeConnection { - ::qpid::messaging::Connection * get () { return connectionp; } + ::qpid::messaging::Connection * get () + { + return nativeObjPtr; + } } void SetOption(System::String ^ name, System::Object ^ value); @@ -95,7 +122,10 @@ namespace Messaging { { System::Boolean get () { - return connectionp->isOpen(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->isOpen(); } } @@ -113,7 +143,10 @@ namespace Messaging { { System::String ^ get () { - return gcnew System::String(connectionp->getAuthenticatedUsername().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getAuthenticatedUsername().c_str()); } } }; diff --git a/cpp/bindings/qpid/dotnet/src/Duration.cpp b/cpp/bindings/qpid/dotnet/src/Duration.cpp deleted file mode 100644 index 7daf803be8..0000000000 --- a/cpp/bindings/qpid/dotnet/src/Duration.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -* 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 -#include -#include -#include -#include - -#include "qpid/messaging/Duration.h" - -#include "Duration.h" - -namespace org { -namespace apache { -namespace qpid { -namespace messaging { - - /// - /// Duration is a time interval in milliseconds. - /// It is a managed wrapper for a ::qpid::messaging::Duration - /// - - // Public constructor - Duration::Duration(System::UInt64 milliseconds) : - durationp(new ::qpid::messaging::Duration(milliseconds)) - { - } - - // Private experimental constructor - Duration::Duration(const ::qpid::messaging::Duration * d) : - durationp(d) - { - } - - - // Destructor - Duration::~Duration() - { - Cleanup(); - } - - - // Finalizer - Duration::!Duration() - { - Cleanup(); - } - - - // Returns the value from kept object - System::UInt64 Duration::getMilliseconds() - { - return durationp->getMilliseconds(); - } - - - // Destroys kept object - // TODO: add lock - void Duration::Cleanup() - { - if (NULL != durationp) - { - delete durationp; - durationp = NULL; - } - } - - // Return value(s) for constant durations - // NOTE: These return the duration mS and not a Duration - // object like the C++ code gets. - System::UInt64 Duration::FOREVER() - { - return ::qpid::messaging::Duration::FOREVER.getMilliseconds(); - } - - System::UInt64 Duration::IMMEDIATE() - { - return ::qpid::messaging::Duration::IMMEDIATE.getMilliseconds(); - } - - System::UInt64 Duration::SECOND() - { - return ::qpid::messaging::Duration::SECOND.getMilliseconds(); - } - - System::UInt64 Duration::MINUTE() - { - return ::qpid::messaging::Duration::MINUTE.getMilliseconds(); - } -}}}} diff --git a/cpp/bindings/qpid/dotnet/src/Duration.h b/cpp/bindings/qpid/dotnet/src/Duration.h index d4239fae88..c77f5fc868 100644 --- a/cpp/bindings/qpid/dotnet/src/Duration.h +++ b/cpp/bindings/qpid/dotnet/src/Duration.h @@ -43,14 +43,12 @@ namespace Messaging { public: Duration(const Duration % rhs) : - milliseconds(rhs.milliseconds) - { - } + milliseconds(rhs.milliseconds) {} - explicit Duration(System::UInt64 mS) : + explicit Duration(System::UInt64 mS) : milliseconds(mS) {} - - Duration() : + + Duration() : milliseconds(System::UInt64::MaxValue) {} property System::UInt64 Milliseconds @@ -91,12 +89,12 @@ namespace Messaging { { return a->Milliseconds != b->Milliseconds; } -}; + }; public ref class DurationConstants sealed { - private: - DurationConstants::DurationConstants() {} + private: + DurationConstants::DurationConstants() {} public: static Duration ^ FORVER; diff --git a/cpp/bindings/qpid/dotnet/src/FailoverUpdates.cpp b/cpp/bindings/qpid/dotnet/src/FailoverUpdates.cpp index d34474f2c4..19b55db3f8 100644 --- a/cpp/bindings/qpid/dotnet/src/FailoverUpdates.cpp +++ b/cpp/bindings/qpid/dotnet/src/FailoverUpdates.cpp @@ -38,26 +38,34 @@ namespace Messaging { /// FailoverUpdates is a managed wrapper for a qpid::messaging::FailoverUpdates /// + // Disallow access if object has been destroyed. + void FailoverUpdates::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + // constructors FailoverUpdates::FailoverUpdates(Connection ^ connection) { System::Exception ^ newException = nullptr; - try - { - failoverupdatesp = new ::qpid::messaging::FailoverUpdates(*(connection->NativeConnection)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::FailoverUpdates(*(connection->NativeConnection)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -71,12 +79,15 @@ namespace Messaging { // Finalizer FailoverUpdates::!FailoverUpdates() { - msclr::lock lk(this); - - if (NULL != failoverupdatesp) + if (NULL != nativeObjPtr) { - delete failoverupdatesp; - failoverupdatesp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h b/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h index d82e276fc8..1ad5c4b42b 100644 --- a/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h +++ b/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h @@ -40,7 +40,13 @@ namespace Messaging { { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::FailoverUpdates * failoverupdatesp; + ::qpid::messaging::FailoverUpdates * nativeObjPtr; + + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); public: FailoverUpdates(Connection ^ connection); @@ -48,16 +54,27 @@ namespace Messaging { ~FailoverUpdates(); !FailoverUpdates(); + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + private: - // unmanaged clone - // not defined + // unmanaged clone + // not defined // copy constructor FailoverUpdates(const FailoverUpdates ^ failoverUpdates) {} FailoverUpdates(const FailoverUpdates % failoverUpdates) {} // assignment operator - FailoverUpdates % operator=(const FailoverUpdates % rhs) + FailoverUpdates % operator=(const FailoverUpdates % rhs) { return *this; } diff --git a/cpp/bindings/qpid/dotnet/src/Message.cpp b/cpp/bindings/qpid/dotnet/src/Message.cpp index e5dbf845b3..27cf4e7dba 100644 --- a/cpp/bindings/qpid/dotnet/src/Message.cpp +++ b/cpp/bindings/qpid/dotnet/src/Message.cpp @@ -46,25 +46,34 @@ namespace Messaging { /// Message is a managed wrapper for a ::qpid::messaging::Message /// + // Disallow access if object has been destroyed. + void Message::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // Create empty message Message::Message() { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message(QpidMarshal::ToNative("")); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message(QpidMarshal::ToNative("")); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Create from string @@ -72,20 +81,21 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message(QpidMarshal::ToNative(theStr)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message(QpidMarshal::ToNative(theStr)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Create from object @@ -93,9 +103,10 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message(QpidMarshal::ToNative("")); + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message(QpidMarshal::ToNative("")); if (QpidTypeCheck::ObjectIsMap(theValue)) { @@ -108,10 +119,10 @@ namespace Messaging { TypeTranslator::ManagedToNative((QpidMap ^)theValue, newMap); // Set message content type - messagep->setContentType("ampq/map"); + nativeObjPtr->setContentType("ampq/map"); // Insert the map into the message - ::qpid::messaging::encode(newMap, *messagep, QpidMarshal::ToNative("amqp/map")); + ::qpid::messaging::encode(newMap, *nativeObjPtr, QpidMarshal::ToNative("amqp/map")); } else if (QpidTypeCheck::ObjectIsList(theValue)) { @@ -124,99 +135,103 @@ namespace Messaging { TypeTranslator::ManagedToNative((QpidList ^)theValue, newList); // Set message content type - messagep->setContentType("ampq/list"); + nativeObjPtr->setContentType("ampq/list"); // Insert the list into the message - ::qpid::messaging::encode(newList, *messagep, QpidMarshal::ToNative("amqp/list")); + ::qpid::messaging::encode(newList, *nativeObjPtr, QpidMarshal::ToNative("amqp/list")); } else { // Create a binary string message - messagep->setContent(QpidMarshal::ToNative(theValue->ToString())); + nativeObjPtr->setContent(QpidMarshal::ToNative(theValue->ToString())); } - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } - // Create from bytes - Message::Message(array ^ bytes) - { + // Create from bytes + Message::Message(array ^ bytes) + { System::Exception ^ newException = nullptr; - try - { - pin_ptr pBytes = &bytes[0]; - messagep = new ::qpid::messaging::Message((char *)pBytes, bytes->Length); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + pin_ptr pBytes = &bytes[0]; + nativeObjPtr = new ::qpid::messaging::Message((char *)pBytes, bytes->Length); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } - } + if (newException != nullptr) + { + throw newException; + } + } // Create from byte array slice - Message::Message(array ^ bytes, int offset, int size) - { + Message::Message(array ^ bytes, int offset, int size) + { if ((offset + size) > bytes->Length) - throw gcnew QpidException("Message::Message Create from byte array slice: buffer length exceeded"); + throw gcnew QpidException("Message::Message Create from byte array slice: buffer length exceeded"); System::Exception ^ newException = nullptr; - try - { - pin_ptr pBytes = &bytes[offset]; - messagep = new ::qpid::messaging::Message((char *)pBytes, size); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + pin_ptr pBytes = &bytes[offset]; + nativeObjPtr = new ::qpid::messaging::Message((char *)pBytes, size); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } - } + if (newException != nullptr) + { + throw newException; + } + } - // unmanaged clone + // unmanaged clone Message::Message(const ::qpid::messaging::Message & msgp) { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message(msgp); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message(msgp); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Destructor + // Called by .NET Dispose() or C++ delete. Message::~Message() { this->!Message(); @@ -224,14 +239,18 @@ namespace Messaging { // Finalizer + // Called by Destructor or by System::GC Message::!Message() { - msclr::lock lk(this); - - if (NULL != messagep) + if (NULL != nativeObjPtr) { - delete messagep; - messagep = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } @@ -240,21 +259,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message( - *(const_cast(message)->NativeMessage)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message( + *(const_cast(message)->NativeMessage)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) @@ -262,135 +282,151 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - messagep = new ::qpid::messaging::Message( - *(const_cast(message).NativeMessage)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Message( + *(const_cast(message).NativeMessage)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Property void Message::SetProperty(System::String ^ name, System::Object ^ value) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { + try + { ::qpid::types::Variant entryValue; TypeTranslator::ManagedToNativeObject(value, entryValue); - messagep->getProperties()[QpidMarshal::ToNative(name)] = entryValue; - } - catch (const ::qpid::types::Exception & error) - { + nativeObjPtr->getProperties()[QpidMarshal::ToNative(name)] = entryValue; + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } - // Content - void Message::SetContent(System::String ^ content) + // Content + void Message::SetContent(System::String ^ content) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - messagep->setContent(QpidMarshal::ToNative(content)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->setContent(QpidMarshal::ToNative(content)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Message::SetContent(cli::array ^ bytes) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - pin_ptr pBytes = &bytes[0]; - messagep->setContent((char *)pBytes, bytes->Length); - } - catch (const ::qpid::types::Exception & error) - { + try + { + pin_ptr pBytes = &bytes[0]; + nativeObjPtr->setContent((char *)pBytes, bytes->Length); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Message::SetContent(cli::array ^ bytes, int offset, int size) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if ((offset + size) > bytes->Length) - throw gcnew QpidException("Message::SetContent from byte array slice: buffer length exceeded"); + throw gcnew QpidException("Message::SetContent from byte array slice: buffer length exceeded"); System::Exception ^ newException = nullptr; - try - { - pin_ptr pBytes = &bytes[offset]; - messagep->setContent((char *)pBytes, size); - } - catch (const ::qpid::types::Exception & error) - { + try + { + pin_ptr pBytes = &bytes[offset]; + nativeObjPtr->setContent((char *)pBytes, size); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } System::String ^ Message::GetContent() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::String ^ result = nullptr; System::Exception ^ newException = nullptr; - try - { - result = gcnew String(messagep->getContent().c_str()); - } - catch (const ::qpid::types::Exception & error) - { + try + { + result = gcnew String(nativeObjPtr->getContent().c_str()); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return result; } @@ -400,30 +436,33 @@ namespace Messaging { // User wants to extract a Dictionary from the message // void Message::GetContent(System::Collections::Generic::Dictionary< - System::String^, - System::Object^> ^ dict) + System::String^, + System::Object^> ^ dict) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { + try + { // Extract the message map from the message ::qpid::types::Variant::Map map; - - ::qpid::messaging::decode(*messagep, map, QpidMarshal::ToNative("amqp/map")); + + ::qpid::messaging::decode(*nativeObjPtr, map, QpidMarshal::ToNative("amqp/map")); TypeTranslator::NativeToManaged(map, dict); - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -431,121 +470,127 @@ namespace Messaging { // User wants to extract a list from the message // void Message::GetContent(System::Collections::ObjectModel::Collection< - System::Object^> ^ list) + System::Object^> ^ list) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { + try + { // allocate a native messaging::List ::qpid::types::Variant::List nativeList; - + // Extract the list from the message in native format - ::qpid::messaging::decode(*messagep, nativeList, QpidMarshal::ToNative("amqp/list")); + ::qpid::messaging::decode(*nativeObjPtr, nativeList, QpidMarshal::ToNative("amqp/list")); // translate native list into user's managed list TypeTranslator::NativeToManaged(nativeList, list); - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // // Return message content to raw byte array. - // On entry message size must not be zero and - // caller's byte array must be equal to message size. + // On entry, message size must not be zero and + // caller's byte array size must be equal to message size. // void Message::GetContent(array ^ arr) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - System::UInt32 size = messagep->getContentSize(); - + try + { + System::UInt32 size = (System::UInt32) nativeObjPtr->getContentSize(); + if (0 == size) throw gcnew QpidException("Message::GetRaw - message size is zero"); if (arr->Length != size) throw gcnew QpidException("Message::GetRaw - receive buffer is wrong size"); - const char * pMsgSrc = messagep->getContentPtr(); - pin_ptr pArr = &arr[0]; - memcpy(pArr, pMsgSrc, size); - } - catch (const ::qpid::types::Exception & error) - { + const char * pMsgSrc = nativeObjPtr->getContentPtr(); + pin_ptr pArr = &arr[0]; + memcpy(pArr, pMsgSrc, size); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } - System::String ^ Message::MapAsString(System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^ dict) + System::String ^ Message::MapAsString(System::Collections::Generic::Dictionary< + System::String^, System::Object^> ^ dict) { - System::Text::StringBuilder ^ sb = gcnew System::Text::StringBuilder("{"); + System::Text::StringBuilder ^ sb = gcnew System::Text::StringBuilder("{"); System::Exception ^ newException = nullptr; - try - { - System::String ^ leading = ""; + try + { + System::String ^ leading = ""; - for each (System::Collections::Generic::KeyValuePair - kvp in dict) + for each (System::Collections::Generic::KeyValuePair + kvp in dict) { sb->Append(leading); leading = ", "; - if (QpidTypeCheck::ObjectIsMap(kvp.Value)) + if (QpidTypeCheck::ObjectIsMap(kvp.Value)) { - sb->AppendFormat( - "{0}={1}", - kvp.Key, - MapAsString((System::Collections::Generic::Dictionary ^)kvp.Value)); + sb->AppendFormat( + "{0}={1}", + kvp.Key, + MapAsString((System::Collections::Generic::Dictionary ^)kvp.Value)); } - else if (QpidTypeCheck::ObjectIsList(kvp.Value)) + else if (QpidTypeCheck::ObjectIsList(kvp.Value)) { sb->AppendFormat( - "{0}={1}", - kvp.Key, - ListAsString((System::Collections::ObjectModel::Collection< - System::Object^> ^)kvp.Value)); + "{0}={1}", + kvp.Key, + ListAsString((System::Collections::ObjectModel::Collection< + System::Object^> ^)kvp.Value)); } else if (nullptr == kvp.Value) { sb->AppendFormat( - "{0}=", - kvp.Key); + "{0}=", + kvp.Key); } else sb->AppendFormat("{0}={1}", kvp.Key, kvp.Value); } - sb->Append("}"); - } - catch (const ::qpid::types::Exception & error) - { + sb->Append("}"); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } System::String ^ result = gcnew System::String(sb->ToString()); return result; @@ -555,29 +600,29 @@ namespace Messaging { /// A function to display a ampq/list message packaged as a List. /// /// The AMQP list - System::String ^ Message::ListAsString(System::Collections::ObjectModel::Collection ^ list) + System::String ^ Message::ListAsString(System::Collections::ObjectModel::Collection ^ list) { System::Text::StringBuilder ^ sb = gcnew System::Text::StringBuilder("["); System::Exception ^ newException = nullptr; - try - { - System::String ^ leading = ""; + try + { + System::String ^ leading = ""; - for each (System::Object ^ obj in list) + for each (System::Object ^ obj in list) { sb->Append(leading); leading = ", "; - if (QpidTypeCheck::ObjectIsMap(obj)) + if (QpidTypeCheck::ObjectIsMap(obj)) { sb->Append(MapAsString((System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^)obj)); + System::String^, System::Object^> ^)obj)); } - else if (QpidTypeCheck::ObjectIsList(obj)) + else if (QpidTypeCheck::ObjectIsList(obj)) { sb->Append(ListAsString((System::Collections::ObjectModel::Collection< - System::Object^> ^)obj)); + System::Object^> ^)obj)); } else if (nullptr == obj) { @@ -587,31 +632,31 @@ namespace Messaging { sb->Append(obj->ToString()); } sb->Append("]"); - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } - System::String ^ result = gcnew System::String(sb->ToString()); + System::String ^ result = gcnew System::String(sb->ToString()); return result; } - System::String ^ Message::AsString(System::Object ^ obj) - { - if (QpidTypeCheck::ObjectIsMap(obj)) - return MapAsString((System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^)obj); - else if (QpidTypeCheck::ObjectIsList(obj)) - return ListAsString((System::Collections::ObjectModel::Collection< - System::Object^> ^)obj); - else - return obj->ToString(); - } + System::String ^ Message::AsString(System::Object ^ obj) + { + if (QpidTypeCheck::ObjectIsMap(obj)) + return MapAsString((System::Collections::Generic::Dictionary< + System::String^, System::Object^> ^)obj); + else if (QpidTypeCheck::ObjectIsList(obj)) + return ListAsString((System::Collections::ObjectModel::Collection< + System::Object^> ^)obj); + else + return obj->ToString(); + } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/Message.h b/cpp/bindings/qpid/dotnet/src/Message.h index ac7f285fe5..a0d77b056b 100644 --- a/cpp/bindings/qpid/dotnet/src/Message.h +++ b/cpp/bindings/qpid/dotnet/src/Message.h @@ -48,7 +48,13 @@ namespace Messaging { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::Message * messagep; + ::qpid::messaging::Message * nativeObjPtr; + + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); public: // Create empty message @@ -61,11 +67,12 @@ namespace Messaging { Message(System::Object ^ theValue); // Create from byte array - Message(array ^ bytes); + Message(array ^ bytes); // Create from byte array slice - Message(array ^ bytes, int offset, int size); + Message(array ^ bytes, int offset, int size); + // System destructor/finalizer entry points ~Message(); !Message(); @@ -73,48 +80,72 @@ namespace Messaging { Message(const Message ^ message); Message(const Message % message); - // unmanaged clone + // unmanaged clone Message(const ::qpid::messaging::Message & msgp); // assignment operator Message % operator=(const Message % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != messagep) - delete messagep; - messagep = new ::qpid::messaging::Message( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Message( *(const_cast(rhs).NativeMessage) ); } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + // // NativeMessage // property ::qpid::messaging::Message * NativeMessage { - ::qpid::messaging::Message * get () { return messagep; } + ::qpid::messaging::Message * get () + { + return nativeObjPtr; + } } // // ReplyTo // - property Address ^ ReplyTo + property Address ^ ReplyTo { void set (Address ^ address) { - messagep->setReplyTo(*(address->NativeAddress)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setReplyTo(*(address->NativeAddress)); } - Address ^ get () + Address ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + const ::qpid::messaging::Address & addrp = - messagep->::qpid::messaging::Message::getReplyTo(); + nativeObjPtr->::qpid::messaging::Message::getReplyTo(); return gcnew Address(addrp); } @@ -127,13 +158,18 @@ namespace Messaging { { void set (System::String ^ subject) { - messagep->setSubject(QpidMarshal::ToNative(subject)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setSubject(QpidMarshal::ToNative(subject)); } - - + System::String ^ get () { - return gcnew String(messagep->getSubject().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew String(nativeObjPtr->getSubject().c_str()); } } @@ -145,15 +181,21 @@ namespace Messaging { { void set (System::String ^ ct) { - messagep->setContentType(QpidMarshal::ToNative(ct)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setContentType(QpidMarshal::ToNative(ct)); } - - System::String ^ get () + + System::String ^ get () { - return gcnew String(messagep->::qpid::messaging::Message::getContentType().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew String(nativeObjPtr->::qpid::messaging::Message::getContentType().c_str()); } } - + // // MessageId @@ -162,16 +204,22 @@ namespace Messaging { { void set (System::String ^ messageId) { - messagep->setMessageId(QpidMarshal::ToNative(messageId)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setMessageId(QpidMarshal::ToNative(messageId)); } System::String ^ get () { - return gcnew String(messagep->getMessageId().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew String(nativeObjPtr->getMessageId().c_str()); } } - + // // UserId // @@ -179,16 +227,22 @@ namespace Messaging { { void set (System::String ^ uId) { - messagep->setUserId(QpidMarshal::ToNative(uId)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setUserId(QpidMarshal::ToNative(uId)); } - + System::String ^ get () { - return gcnew String(messagep->getUserId().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew String(nativeObjPtr->getUserId().c_str()); } } - + // // CorrelationId // @@ -196,12 +250,18 @@ namespace Messaging { { void set (System::String ^ correlationId) { - messagep->setCorrelationId(QpidMarshal::ToNative(correlationId)); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setCorrelationId(QpidMarshal::ToNative(correlationId)); } - + System::String ^ get () { - return gcnew String(messagep->getCorrelationId().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew String(nativeObjPtr->getCorrelationId().c_str()); } } @@ -213,14 +273,20 @@ namespace Messaging { { void set (unsigned char priority) { - messagep->setPriority(priority); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setPriority(priority); } - + unsigned char get () { - return messagep->getPriority(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getPriority(); } - } + } // @@ -230,14 +296,20 @@ namespace Messaging { { void set (Duration ^ ttl) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::messaging::Duration dur(ttl->Milliseconds); - messagep->setTtl(dur); + nativeObjPtr->setTtl(dur); } - + Duration ^ get () { - Duration ^ dur = gcnew Duration(messagep->getTtl().getMilliseconds()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + Duration ^ dur = gcnew Duration(nativeObjPtr->getTtl().getMilliseconds()); return dur; } @@ -250,12 +322,18 @@ namespace Messaging { { void set (bool durable) { - messagep->setDurable(durable); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setDurable(durable); } - + bool get () { - return messagep->getDurable(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getDurable(); } } @@ -266,12 +344,18 @@ namespace Messaging { { bool get () { - return messagep->getRedelivered(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getRedelivered(); } void set (bool redelivered) { - messagep->setRedelivered(redelivered); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setRedelivered(redelivered); } } @@ -284,19 +368,22 @@ namespace Messaging { // Properties // property System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^ Properties + System::String^, System::Object^> ^ Properties { System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^ get () + System::String^, System::Object^> ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::types::Variant::Map map; - map = messagep->getProperties(); + map = nativeObjPtr->getProperties(); System::Collections::Generic::Dictionary< System::String^, System::Object^> ^ dict = gcnew System::Collections::Generic::Dictionary< - System::String^, System::Object^> ; + System::String^, System::Object^> ; TypeTranslator::NativeToManaged(map, dict); @@ -305,15 +392,18 @@ namespace Messaging { } - void set (System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^ properties) - { - for each (System::Collections::Generic::KeyValuePair - kvp in properties) + void set (System::Collections::Generic::Dictionary< + System::String^, System::Object^> ^ properties) + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + for each (System::Collections::Generic::KeyValuePair + kvp in properties) { - SetProperty(kvp.Key, kvp.Value); - } - } + SetProperty(kvp.Key, kvp.Value); + } + } } @@ -330,12 +420,12 @@ namespace Messaging { // get content as dictionary void GetContent(System::Collections::Generic::Dictionary< - System::String^, - System::Object^> ^ dict); + System::String^, + System::Object^> ^ dict); // get content as map void GetContent(System::Collections::ObjectModel::Collection< - System::Object^> ^); + System::Object^> ^); // get content as bytes void GetContent(cli::array ^ arr); @@ -347,20 +437,23 @@ namespace Messaging { { System::UInt64 get () { - return messagep->getContentSize(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getContentSize(); } } - // A message has been returned to managed code through GetContent(). - // Display the content of that System::Object as a string. - System::String ^ AsString(System::Object ^ obj); + // A message has been returned to managed code through GetContent(). + // Display the content of that System::Object as a string. + System::String ^ AsString(System::Object ^ obj); + + System::String ^ MapAsString(System::Collections::Generic::Dictionary< + System::String^, System::Object^> ^ dict); - System::String ^ MapAsString(System::Collections::Generic::Dictionary< - System::String^, System::Object^> ^ dict); - - System::String ^ ListAsString(System::Collections::ObjectModel::Collection< - System::Object^> ^ list); + System::String ^ ListAsString(System::Collections::ObjectModel::Collection< + System::Object^> ^ list); //TODO: EncodingException diff --git a/cpp/bindings/qpid/dotnet/src/QpidException.h b/cpp/bindings/qpid/dotnet/src/QpidException.h index c63f245f74..dc042ed939 100644 --- a/cpp/bindings/qpid/dotnet/src/QpidException.h +++ b/cpp/bindings/qpid/dotnet/src/QpidException.h @@ -31,11 +31,11 @@ public ref class QpidException : System::Exception { public: - QpidException() - : System::Exception() {} + QpidException() + : System::Exception() {} - QpidException(String^ estring) - : System::Exception(estring) {} + QpidException(String^ estring) + : System::Exception(estring) {} }; diff --git a/cpp/bindings/qpid/dotnet/src/QpidMarshal.h b/cpp/bindings/qpid/dotnet/src/QpidMarshal.h index a8266ba5da..60f40afe04 100644 --- a/cpp/bindings/qpid/dotnet/src/QpidMarshal.h +++ b/cpp/bindings/qpid/dotnet/src/QpidMarshal.h @@ -34,24 +34,24 @@ namespace Messaging { private ref class QpidMarshal { private: - QpidMarshal::QpidMarshal() {} + QpidMarshal::QpidMarshal() {} public: /// /// Convert managed String into native UTF8-encoded string - /// TODO: figure out some encoding other that UTF-8 + /// TODO: figure out some encoding other than UTF-8 /// - static std::string ToNative (System::String^ managed) + static std::string ToNative (System::String^ managed) { - if (managed->Length == 0) + if (managed->Length == 0) { return std::string(); } array^ mbytes = Encoding::UTF8->GetBytes(managed); - if (mbytes->Length == 0) + if (mbytes->Length == 0) { return std::string(); } diff --git a/cpp/bindings/qpid/dotnet/src/QpidTypeCheck.h b/cpp/bindings/qpid/dotnet/src/QpidTypeCheck.h index d0f410b912..a3fdaf99c2 100644 --- a/cpp/bindings/qpid/dotnet/src/QpidTypeCheck.h +++ b/cpp/bindings/qpid/dotnet/src/QpidTypeCheck.h @@ -39,18 +39,18 @@ namespace Messaging { /// typedef System::Collections::Generic::Dictionary< - System::String^, - System::Object^> + System::String^, + System::Object^> QpidMap; typedef System::Collections::ObjectModel::Collection< - System::Object^> + System::Object^> QpidList; private ref class QpidTypeCheckConstants sealed { - private: - QpidTypeCheckConstants::QpidTypeCheckConstants() {} + private: + QpidTypeCheckConstants::QpidTypeCheckConstants() {} public: static System::Type const ^ const mapTypeP = System::Type::GetType( @@ -62,8 +62,8 @@ namespace Messaging { public ref class QpidTypeCheck sealed { - private: - QpidTypeCheck::QpidTypeCheck() {} + private: + QpidTypeCheck::QpidTypeCheck() {} public: diff --git a/cpp/bindings/qpid/dotnet/src/ReadMe.txt b/cpp/bindings/qpid/dotnet/src/ReadMe.txt index a17f04325e..f7287af573 100644 --- a/cpp/bindings/qpid/dotnet/src/ReadMe.txt +++ b/cpp/bindings/qpid/dotnet/src/ReadMe.txt @@ -2,14 +2,14 @@ DYNAMIC LINK LIBRARY : Org.Apache.Qpid.Messaging Project Overview ======================================================================== -AppWizard has created this Org.Apache.Qpid.Messaging DLL for you. +AppWizard has created this Org.Apache.Qpid.Messaging DLL for you. This file contains a summary of what you will find in each of the files that make up your Org.Apache.Qpid.Messaging application. Org.Apache.Qpid.Messaging.vcproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and information about the platforms, configurations, and project features selected with the Application Wizard. @@ -21,9 +21,9 @@ Sender.[cpp h] Session.[cpp h] Managed code Interop layer modules to provide access to functions exported by qpidcommon.dll. - + AssemblyInfo.cpp - Contains custom attributes for modifying assembly metadata. + Contains custom attributes for modifying assembly metadata. ///////////////////////////////////////////////////////////////////////////// Other notes: diff --git a/cpp/bindings/qpid/dotnet/src/Receiver.cpp b/cpp/bindings/qpid/dotnet/src/Receiver.cpp index 8aa77effbd..4f96c23511 100644 --- a/cpp/bindings/qpid/dotnet/src/Receiver.cpp +++ b/cpp/bindings/qpid/dotnet/src/Receiver.cpp @@ -43,27 +43,36 @@ namespace Messaging { /// Receiver is a managed wrapper for a ::qpid::messaging::Receiver /// + // Disallow access if object has been destroyed. + void Receiver::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // unmanaged clone Receiver::Receiver(const ::qpid::messaging::Receiver & r, - Org::Apache::Qpid::Messaging::Session ^ sessRef) : - parentSession(sessRef) + Org::Apache::Qpid::Messaging::Session ^ sessRef) : + parentSession(sessRef) { System::Exception ^ newException = nullptr; - try - { - receiverp = new ::qpid::messaging::Receiver (r); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Receiver (r); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // unmanaged clone @@ -79,60 +88,65 @@ namespace Messaging { // Finalizer Receiver::!Receiver() { - msclr::lock lk(this); - - if (NULL != receiverp) + if (NULL != nativeObjPtr) { - delete receiverp; - receiverp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } // Copy constructor look-alike (C#) Receiver::Receiver(const Receiver ^ receiver) : - parentSession(receiver->parentSession) + parentSession(receiver->parentSession) { System::Exception ^ newException = nullptr; - try - { - receiverp = new ::qpid::messaging::Receiver( - *(const_cast(receiver)->NativeReceiver)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Receiver( + *(const_cast(receiver)->NativeReceiver)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) Receiver::Receiver(const Receiver % receiver) : - parentSession(receiver.parentSession) + parentSession(receiver.parentSession) { System::Exception ^ newException = nullptr; - try - { - receiverp = new ::qpid::messaging::Receiver( - *(const_cast(receiver).NativeReceiver)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Receiver( + *(const_cast(receiver).NativeReceiver)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -143,36 +157,39 @@ namespace Messaging { { return Get(mmsgp, DurationConstants::FORVER); } - + bool Receiver::Get(Message ^% mmsgp, Duration ^ durationp) { System::Exception ^ newException = nullptr; - try - { + try + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::messaging::Duration dur((*durationp).Milliseconds); - + ::qpid::messaging::Message tmpMsg; - - bool result = receiverp->Receiver::get(tmpMsg, dur); - + + bool result = nativeObjPtr->Receiver::get(tmpMsg, dur); + if (result) { mmsgp = gcnew Message(tmpMsg); } - + return result; } - catch (const ::qpid::types::Exception & error) - { + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return false; } @@ -193,17 +210,20 @@ namespace Messaging { try { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + // translate the duration ::qpid::messaging::Duration dur((*durationp).Milliseconds); // get the message - ::qpid::messaging::Message msg = - receiverp->::qpid::messaging::Receiver::get(dur); + ::qpid::messaging::Message msg = + nativeObjPtr->::qpid::messaging::Receiver::get(dur); // create new managed message with received message embedded in it newMessage = gcnew Message(msg); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -212,16 +232,16 @@ namespace Messaging { { if (newException != nullptr) { - if (newMessage != nullptr) - { - delete newMessage; - } + if (newMessage != nullptr) + { + delete newMessage; + } } } if (newException != nullptr) { - throw newException; - } + throw newException; + } return newMessage; } @@ -233,39 +253,42 @@ namespace Messaging { { return Fetch(mmsgp, DurationConstants::FORVER); } - + bool Receiver::Fetch(Message ^% mmsgp, Duration ^ durationp) { System::Exception ^ newException = nullptr; try { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + ::qpid::messaging::Duration dur((*durationp).Milliseconds); - + ::qpid::messaging::Message tmpMsg; - - bool result = receiverp->Receiver::fetch(tmpMsg, dur); - + + bool result = nativeObjPtr->Receiver::fetch(tmpMsg, dur); + if (result) { mmsgp = gcnew Message(tmpMsg); } - + return result; - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } if (newException != nullptr) { - throw newException; - } + throw newException; + } return false; } - + // // message = Fetch() @@ -283,17 +306,20 @@ namespace Messaging { try { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + // translate the duration ::qpid::messaging::Duration dur((*durationp).Milliseconds); // get the message ::qpid::messaging::Message msg = - receiverp->::qpid::messaging::Receiver::fetch(dur); + nativeObjPtr->::qpid::messaging::Receiver::fetch(dur); // create new managed message with received message embedded in it newMessage = gcnew Message(msg); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -302,22 +328,25 @@ namespace Messaging { { if (newException != nullptr) { - if (newMessage != nullptr) - { - delete newMessage; - } + if (newMessage != nullptr) + { + delete newMessage; + } } } if (newException != nullptr) { - throw newException; - } + throw newException; + } return newMessage; } void Receiver::Close() { - receiverp->close(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->close(); } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/Receiver.h b/cpp/bindings/qpid/dotnet/src/Receiver.h index 8ddcc9ac01..77b361851e 100644 --- a/cpp/bindings/qpid/dotnet/src/Receiver.h +++ b/cpp/bindings/qpid/dotnet/src/Receiver.h @@ -41,7 +41,7 @@ namespace Qpid { namespace Messaging { /// - /// Mreceiver is a managed wrapper for a ::qpid::messaging::Receiver + /// Receiver is a managed wrapper for a ::qpid::messaging::Receiver /// ref class Session; @@ -55,7 +55,13 @@ namespace Messaging { Session ^ parentSession; // The kept object in the Messaging C++ DLL - ::qpid::messaging::Receiver * receiverp; + ::qpid::messaging::Receiver * nativeObjPtr; + + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); public: @@ -76,24 +82,45 @@ namespace Messaging { // assignment operator Receiver % operator=(const Receiver % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != receiverp) - delete receiverp; - receiverp = new ::qpid::messaging::Receiver( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Receiver( *(const_cast(rhs).NativeReceiver)); parentSession = rhs.parentSession; } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + + // + // NativeReceiver + // property ::qpid::messaging::Receiver * NativeReceiver { - ::qpid::messaging::Receiver * get () { return receiverp; } + ::qpid::messaging::Receiver * get () + { + return nativeObjPtr; + } } // Get(message) @@ -119,12 +146,18 @@ namespace Messaging { { void set (System::UInt32 capacity) { - receiverp->setCapacity(capacity); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setCapacity(capacity); } System::UInt32 get () { - return receiverp->getCapacity(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getCapacity(); } } @@ -135,7 +168,10 @@ namespace Messaging { { System::UInt32 get () { - return receiverp->getAvailable(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getAvailable(); } } @@ -146,12 +182,15 @@ namespace Messaging { { System::UInt32 get () { - return receiverp->getUnsettled(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getUnsettled(); } } void Close(); - + // // IsClosed // @@ -159,7 +198,10 @@ namespace Messaging { { System::Boolean get () { - return receiverp->isClosed(); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->isClosed(); } } @@ -170,7 +212,10 @@ namespace Messaging { { System::String ^ get () { - return gcnew System::String(receiverp->getName().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getName().c_str()); } } @@ -181,6 +226,9 @@ namespace Messaging { { Org::Apache::Qpid::Messaging::Session ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + return parentSession; } } diff --git a/cpp/bindings/qpid/dotnet/src/Sender.cpp b/cpp/bindings/qpid/dotnet/src/Sender.cpp index 3225f1a6e1..102e6c20b3 100644 --- a/cpp/bindings/qpid/dotnet/src/Sender.cpp +++ b/cpp/bindings/qpid/dotnet/src/Sender.cpp @@ -37,30 +37,39 @@ namespace Qpid { namespace Messaging { /// - /// Sender a managed wrapper for a ::qpid::messaging::Sender + /// Sender a managed wrapper for a ::qpid::messaging::Sender /// + // Disallow access if object has been destroyed. + void Sender::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // unmanaged clone Sender::Sender(const ::qpid::messaging::Sender & s, - Org::Apache::Qpid::Messaging::Session ^ sessRef) : - parentSession(sessRef) + Org::Apache::Qpid::Messaging::Session ^ sessRef) : + parentSession(sessRef) { System::Exception ^ newException = nullptr; - try - { - senderp = new ::qpid::messaging::Sender (s); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Sender (s); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -74,12 +83,15 @@ namespace Messaging { // Finalizer Sender::!Sender() { - msclr::lock lk(this); - - if (NULL != senderp) + if (NULL != nativeObjPtr) { - delete senderp; - senderp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } @@ -90,21 +102,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - senderp = new ::qpid::messaging::Sender( - *(const_cast(sender)->NativeSender)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Sender( + *(const_cast(sender)->NativeSender)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) @@ -113,21 +126,22 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - senderp = new ::qpid::messaging::Sender( - *(const_cast(sender).NativeSender)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Sender( + *(const_cast(sender).NativeSender)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -141,42 +155,48 @@ namespace Messaging { void Sender::Send(Message ^ mmsgp, bool sync) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - senderp->::qpid::messaging::Sender::send(*((*mmsgp).NativeMessage), sync); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->::qpid::messaging::Sender::send(*((*mmsgp).NativeMessage), sync); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Sender::Close() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - senderp->close(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->close(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/Sender.h b/cpp/bindings/qpid/dotnet/src/Sender.h index 4054e87316..0d477b795f 100644 --- a/cpp/bindings/qpid/dotnet/src/Sender.h +++ b/cpp/bindings/qpid/dotnet/src/Sender.h @@ -40,7 +40,7 @@ namespace Qpid { namespace Messaging { /// - /// Sender is a managed wrapper for a ::qpid::messaging::Sender + /// Sender is a managed wrapper for a ::qpid::messaging::Sender /// ref class Session; @@ -50,16 +50,22 @@ namespace Messaging { { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::Sender * senderp; + ::qpid::messaging::Sender * nativeObjPtr; // The session that created this Sender Session ^ parentSession; + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); + public: // unmanaged clone Sender(const ::qpid::messaging::Sender & s, Session ^ sessRef); - + // copy constructor Sender(const Sender ^ sender); Sender(const Sender % sender); @@ -70,24 +76,45 @@ namespace Messaging { // assignment operator Sender % operator=(const Sender % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != senderp) - delete senderp; - senderp = new ::qpid::messaging::Sender( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Sender( *(const_cast(rhs).NativeSender)); parentSession = rhs.parentSession; } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + + // + // NativeSender + // property ::qpid::messaging::Sender * NativeSender { - ::qpid::messaging::Sender * get () { return senderp; } + ::qpid::messaging::Sender * get () + { + return nativeObjPtr; + } } @@ -99,25 +126,52 @@ namespace Messaging { property System::UInt32 Capacity { - System::UInt32 get () { return senderp->getCapacity(); } - void set (System::UInt32 capacity) { senderp->setCapacity(capacity); } + System::UInt32 get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getCapacity(); + } + void set (System::UInt32 capacity) + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + nativeObjPtr->setCapacity(capacity); + } } property System::UInt32 Unsettled { - System::UInt32 get () { return senderp->getUnsettled(); } + System::UInt32 get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getUnsettled(); + } } property System::UInt32 Available { - System::UInt32 get () { return senderp->getAvailable(); } + System::UInt32 get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getAvailable(); + } } property System::String ^ Name { System::String ^ get () { - return gcnew System::String(senderp->getName().c_str()); + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return gcnew System::String(nativeObjPtr->getName().c_str()); } } @@ -128,6 +182,9 @@ namespace Messaging { { Org::Apache::Qpid::Messaging::Session ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + return parentSession; } } diff --git a/cpp/bindings/qpid/dotnet/src/Session.cpp b/cpp/bindings/qpid/dotnet/src/Session.cpp index 0e918769a3..929dddf80c 100644 --- a/cpp/bindings/qpid/dotnet/src/Session.cpp +++ b/cpp/bindings/qpid/dotnet/src/Session.cpp @@ -45,27 +45,36 @@ namespace Messaging { /// Session is a managed wrapper for a ::qpid::messaging::Session /// + // Disallow access if object has been destroyed. + void Session::ThrowIfDisposed() + { + if (IsDisposed) + throw gcnew ObjectDisposedException (GetType()->FullName); + } + + // unmanaged clone - Session::Session(const ::qpid::messaging::Session & session, - Org::Apache::Qpid::Messaging::Connection ^ connRef) : - parentConnectionp(connRef) + Session::Session(const ::qpid::messaging::Session & session, + Org::Apache::Qpid::Messaging::Connection ^ connRef) : + parentConnectionp(connRef) { System::Exception ^ newException = nullptr; - try - { - sessionp = new ::qpid::messaging::Session (session); - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Session (session); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } @@ -79,12 +88,15 @@ namespace Messaging { // Finalizer Session::!Session() { - msclr::lock lk(this); - - if (NULL != sessionp) + if (NULL != nativeObjPtr) { - delete sessionp; - sessionp = NULL; + privateLock = gcnew System::Object(); + + if (NULL != nativeObjPtr) + { + delete nativeObjPtr; + nativeObjPtr = NULL; + } } } @@ -95,22 +107,23 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - sessionp = new ::qpid::messaging::Session( - *(const_cast(session)->NativeSession)); - - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Session( + *(const_cast(session)->NativeSession)); + + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // Copy constructor implicitly dereferenced (C++) @@ -119,83 +132,93 @@ namespace Messaging { { System::Exception ^ newException = nullptr; - try - { - sessionp = new ::qpid::messaging::Session( - *(const_cast(session).NativeSession)); - - } - catch (const ::qpid::types::Exception & error) - { + try + { + privateLock = gcnew System::Object(); + nativeObjPtr = new ::qpid::messaging::Session( + *(const_cast(session).NativeSession)); + + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Close() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->close(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->close(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Commit() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->commit(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->commit(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Rollback() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->rollback(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->rollback(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Acknowledge() @@ -205,22 +228,25 @@ namespace Messaging { void Session::Acknowledge(bool sync) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->acknowledge(sync); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->acknowledge(sync); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Acknowledge(Message ^ message) @@ -230,22 +256,25 @@ namespace Messaging { void Session::Acknowledge(Message ^ message, bool sync) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->acknowledge(*(message->NativeMessage), sync); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->acknowledge(*(message->NativeMessage), sync); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::AcknowledgeUpTo(Message ^ message) @@ -255,62 +284,71 @@ namespace Messaging { void Session::AcknowledgeUpTo(Message ^ message, bool sync) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->acknowledgeUpTo(*(message->NativeMessage), sync); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->acknowledgeUpTo(*(message->NativeMessage), sync); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Reject(Message ^ message) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->::qpid::messaging::Session::reject(*(message->NativeMessage)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->::qpid::messaging::Session::reject(*(message->NativeMessage)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Release(Message ^ message) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->::qpid::messaging::Session::release(*(message->NativeMessage)); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->::qpid::messaging::Session::release(*(message->NativeMessage)); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } void Session::Sync() @@ -320,22 +358,25 @@ namespace Messaging { void Session::Sync(bool block) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->sync(block); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->sync(block); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } // next(receiver) @@ -346,18 +387,21 @@ namespace Messaging { bool Session::NextReceiver(Receiver ^ rcvr, Duration ^ timeout) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - // create a duration object + try + { + // create a duration object ::qpid::messaging::Duration dur(timeout->Milliseconds); - // wait for the next received message - return sessionp->nextReceiver(*(rcvr->NativeReceiver), dur); - } - catch (const ::qpid::types::Exception & error) - { + // wait for the next received message + return nativeObjPtr->nextReceiver(*(rcvr->NativeReceiver), dur); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); if ("No message to fetch" == errmsg){ return false; @@ -365,10 +409,10 @@ namespace Messaging { newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return true; } @@ -381,19 +425,22 @@ namespace Messaging { Receiver ^ Session::NextReceiver(Duration ^ timeout) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; try { ::qpid::messaging::Duration dur(timeout->Milliseconds); - ::qpid::messaging::Receiver receiver = sessionp->::qpid::messaging::Session::nextReceiver(dur); + ::qpid::messaging::Receiver receiver = nativeObjPtr->::qpid::messaging::Session::nextReceiver(dur); Receiver ^ newRcvr = gcnew Receiver(receiver, this); return newRcvr; - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); if ("No message to fetch" == errmsg) @@ -403,30 +450,33 @@ namespace Messaging { newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } - return nullptr; + return nullptr; } Sender ^ Session::CreateSender (System::String ^ address) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Sender ^ newSender = nullptr; try { // create the sender - ::qpid::messaging::Sender sender = - sessionp->::qpid::messaging::Session::createSender(QpidMarshal::ToNative(address)); + ::qpid::messaging::Sender sender = + nativeObjPtr->::qpid::messaging::Session::createSender(QpidMarshal::ToNative(address)); // create a managed sender newSender = gcnew Sender(sender, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -435,16 +485,16 @@ namespace Messaging { { if (newException != nullptr) { - if (newSender != nullptr) - { - delete newSender; - } + if (newSender != nullptr) + { + delete newSender; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newSender; } @@ -452,19 +502,22 @@ namespace Messaging { Sender ^ Session::CreateSender (Address ^ address) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Sender ^ newSender = nullptr; try { // allocate a native sender - ::qpid::messaging::Sender sender = - sessionp->::qpid::messaging::Session::createSender(*(address->NativeAddress)); + ::qpid::messaging::Sender sender = + nativeObjPtr->::qpid::messaging::Session::createSender(*(address->NativeAddress)); // create a managed sender newSender = gcnew Sender(sender, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); @@ -473,92 +526,98 @@ namespace Messaging { { if (newException != nullptr) { - if (newSender != nullptr) - { - delete newSender; - } + if (newSender != nullptr) + { + delete newSender; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newSender; } - Receiver ^ Session::CreateReceiver(System::String ^ address) + Receiver ^ Session::CreateReceiver(System::String ^ address) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Receiver ^ newReceiver = nullptr; - try - { + try + { // create the receiver - ::qpid::messaging::Receiver receiver = - sessionp->createReceiver(QpidMarshal::ToNative(address)); + ::qpid::messaging::Receiver receiver = + nativeObjPtr->createReceiver(QpidMarshal::ToNative(address)); // create a managed receiver newReceiver = gcnew Receiver(receiver, this); - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - finally - { + finally + { if (newException != nullptr) - { - if (newReceiver != nullptr) - { - delete newReceiver; - } + { + if (newReceiver != nullptr) + { + delete newReceiver; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newReceiver; } - Receiver ^ Session::CreateReceiver(Address ^ address) + Receiver ^ Session::CreateReceiver(Address ^ address) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Receiver ^ newReceiver = nullptr; - try - { + try + { // create the receiver ::qpid::messaging::Receiver receiver = - sessionp->createReceiver(*(address->NativeAddress)); + nativeObjPtr->createReceiver(*(address->NativeAddress)); // create a managed receiver newReceiver = gcnew Receiver(receiver, this); - } - catch (const ::qpid::types::Exception & error) - { + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - finally - { + finally + { if (newException != nullptr) - { - if (newReceiver != nullptr) - { - delete newReceiver; - } + { + if (newReceiver != nullptr) + { + delete newReceiver; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newReceiver; } @@ -566,35 +625,38 @@ namespace Messaging { Sender ^ Session::GetSender(System::String ^ name) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Sender ^ newSender = nullptr; try { - ::qpid::messaging::Sender senderp = - sessionp->::qpid::messaging::Session::getSender(QpidMarshal::ToNative(name)); + ::qpid::messaging::Sender senderp = + nativeObjPtr->::qpid::messaging::Session::getSender(QpidMarshal::ToNative(name)); newSender = gcnew Sender(senderp, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - finally - { + finally + { if (newException != nullptr) - { - if (newSender != nullptr) - { - delete newSender; - } + { + if (newSender != nullptr) + { + delete newSender; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newSender; } @@ -603,35 +665,38 @@ namespace Messaging { Receiver ^ Session::GetReceiver(System::String ^ name) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; Receiver ^ newReceiver = nullptr; try { - ::qpid::messaging::Receiver receiver = - sessionp->::qpid::messaging::Session::getReceiver(QpidMarshal::ToNative(name)); + ::qpid::messaging::Receiver receiver = + nativeObjPtr->::qpid::messaging::Session::getReceiver(QpidMarshal::ToNative(name)); newReceiver = gcnew Receiver(receiver, this); - } - catch (const ::qpid::types::Exception & error) + } + catch (const ::qpid::types::Exception & error) { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - finally - { + finally + { if (newException != nullptr) - { - if (newReceiver != nullptr) - { - delete newReceiver; - } + { + if (newReceiver != nullptr) + { + delete newReceiver; + } } } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } return newReceiver; } @@ -640,21 +705,24 @@ namespace Messaging { void Session::CheckError() { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + System::Exception ^ newException = nullptr; - try - { - sessionp->checkError(); - } - catch (const ::qpid::types::Exception & error) - { + try + { + nativeObjPtr->checkError(); + } + catch (const ::qpid::types::Exception & error) + { String ^ errmsg = gcnew String(error.what()); newException = gcnew QpidException(errmsg); } - if (newException != nullptr) - { - throw newException; - } + if (newException != nullptr) + { + throw newException; + } } }}}} diff --git a/cpp/bindings/qpid/dotnet/src/Session.h b/cpp/bindings/qpid/dotnet/src/Session.h index 4b98a37f18..42e9475c6c 100644 --- a/cpp/bindings/qpid/dotnet/src/Session.h +++ b/cpp/bindings/qpid/dotnet/src/Session.h @@ -45,7 +45,7 @@ namespace Messaging { /// Session is a managed wrapper for a ::qpid::messaging::Session /// - ref class Address; + ref class Address; ref class Connection; ref class Duration; ref class Receiver; @@ -56,15 +56,21 @@ namespace Messaging { { private: // The kept object in the Messaging C++ DLL - ::qpid::messaging::Session * sessionp; + ::qpid::messaging::Session * nativeObjPtr; // The connection that created this session Connection ^ parentConnectionp; + // per-instance lock object + System::Object ^ privateLock; + + // Disallow use after object is destroyed + void ThrowIfDisposed(); + public: // unmanaged clone - Session(const ::qpid::messaging::Session & sessionp, + Session(const ::qpid::messaging::Session & nativeObjPtr, Connection ^ connRef); // copy constructor @@ -77,24 +83,45 @@ namespace Messaging { // assignment operator Session % operator=(const Session % rhs) { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + if (this == %rhs) { // Self assignment, do nothing } else { - if (NULL != sessionp) - delete sessionp; - sessionp = new ::qpid::messaging::Session( + if (NULL != nativeObjPtr) + delete nativeObjPtr; + nativeObjPtr = new ::qpid::messaging::Session( *(const_cast(rhs).NativeSession) ); parentConnectionp = rhs.parentConnectionp; } return *this; } + // + // IsDisposed + // + property bool IsDisposed + { + bool get() + { + return NULL == nativeObjPtr; + } + } + + + // + // NativeSession + // property ::qpid::messaging::Session * NativeSession { - ::qpid::messaging::Session * get () { return sessionp; } + ::qpid::messaging::Session * get () + { + return nativeObjPtr; + } } void Close(); @@ -113,12 +140,24 @@ namespace Messaging { property System::UInt32 Receivable { - System::UInt32 get () { return sessionp->getReceivable(); } + System::UInt32 get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getReceivable(); + } } property System::UInt32 UnsettledAcks { - System::UInt32 get () { return sessionp->getUnsettledAcks(); } + System::UInt32 get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->getUnsettledAcks(); + } } // next(receiver) @@ -131,10 +170,10 @@ namespace Messaging { Sender ^ CreateSender(System::String ^ address); - Sender ^ CreateSender(Address ^ address); + Sender ^ CreateSender(Address ^ address); Receiver ^ CreateReceiver(System::String ^ address); - Receiver ^ CreateReceiver(Address ^ address); + Receiver ^ CreateReceiver(Address ^ address); Sender ^ GetSender(System::String ^ name); Receiver ^ GetReceiver(System::String ^ name); @@ -143,6 +182,9 @@ namespace Messaging { { Org::Apache::Qpid::Messaging::Connection ^ get () { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + return parentConnectionp; } } @@ -150,7 +192,13 @@ namespace Messaging { property System::Boolean HasError { - System::Boolean get () { return sessionp->hasError(); } + System::Boolean get () + { + msclr::lock lk(privateLock); + ThrowIfDisposed(); + + return nativeObjPtr->hasError(); + } } void CheckError(); diff --git a/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp b/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp index b515095323..9ee0ff41f8 100644 --- a/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp +++ b/cpp/bindings/qpid/dotnet/src/TypeTranslator.cpp @@ -43,11 +43,11 @@ namespace Messaging { // Add its elements to the qpid map. // void TypeTranslator::ManagedToNative(QpidMap ^ theDictionary, - ::qpid::types::Variant::Map & qpidMap) + ::qpid::types::Variant::Map & qpidMap) { // iterate the items, converting each to a variant and adding to the map for each (System::Collections::Generic::KeyValuePair - kvp in theDictionary) + kvp in theDictionary) { if (QpidTypeCheck::ObjectIsMap(kvp.Value)) { @@ -108,7 +108,7 @@ namespace Messaging { // Add its elements to the qpid list. // void TypeTranslator::ManagedToNative(QpidList ^ theList, - ::qpid::types::Variant::List & qpidList) + ::qpid::types::Variant::List & qpidList) { // iterate the items, converting each to a variant and adding to the map for each (System::Object ^ listObj in theList) @@ -162,7 +162,7 @@ namespace Messaging { // Returns a variant representing simple native type object. // Not to be called for Map/List objects. // - void TypeTranslator::ManagedToNativeObject(System::Object ^ managedValue, + void TypeTranslator::ManagedToNativeObject(System::Object ^ managedValue, ::qpid::types::Variant & qpidVariant) { System::Type ^ typeP = (*managedValue).GetType(); @@ -171,7 +171,7 @@ namespace Messaging { switch (typeCode) { case System::TypeCode::Boolean : - qpidVariant = System::Convert::ToBoolean(managedValue, System::Globalization::CultureInfo::InvariantCulture); + qpidVariant = System::Convert::ToBoolean(managedValue, System::Globalization::CultureInfo::InvariantCulture); break; case System::TypeCode::Byte : @@ -258,9 +258,9 @@ namespace Messaging { // extract the qpid elements and put them into the dictionary. // void TypeTranslator::NativeToManaged(::qpid::types::Variant::Map & qpidMap, - QpidMap ^ dict) + QpidMap ^ dict) { - // For each object in the message map, + // For each object in the message map, // create a .NET object and add it to the dictionary. for (::qpid::types::Variant::Map::const_iterator i = qpidMap.begin(); i != qpidMap.end(); ++i) { // Get the name @@ -278,47 +278,47 @@ namespace Messaging { case ::qpid::types::VAR_BOOL: dict[elementName] = variant.asBool(); break; - + case ::qpid::types::VAR_UINT8: dict[elementName] = variant.asUint8(); break; - + case ::qpid::types::VAR_UINT16: dict[elementName] = variant.asUint16(); break; - + case ::qpid::types::VAR_UINT32: dict[elementName] = variant.asUint32(); break; - + case ::qpid::types::VAR_UINT64: dict[elementName] = variant.asUint64(); break; - + case ::qpid::types::VAR_INT8: dict[elementName] = variant.asInt8(); break; - + case ::qpid::types::VAR_INT16: dict[elementName] = variant.asInt16(); break; - + case ::qpid::types::VAR_INT32: dict[elementName] = variant.asInt32(); break; - + case ::qpid::types::VAR_INT64: dict[elementName] = variant.asInt64(); break; - + case ::qpid::types::VAR_FLOAT: dict[elementName] = variant.asFloat(); break; - + case ::qpid::types::VAR_DOUBLE: dict[elementName] = variant.asDouble(); break; - + case ::qpid::types::VAR_STRING: { System::String ^ elementValue = gcnew System::String(variant.asString().c_str()); @@ -344,7 +344,7 @@ namespace Messaging { dict[elementName] = newList; break; } - + case ::qpid::types::VAR_UUID: { System::String ^ elementValue = gcnew System::String(variant.asUuid().str().c_str()); @@ -359,9 +359,9 @@ namespace Messaging { void TypeTranslator::NativeToManaged(::qpid::types::Variant::List & qpidList, QpidList ^ managedList) { - // For each object in the qpidList + // For each object in the qpidList // create a .NET object and add it to the managed List. - for (::qpid::types::Variant::List::const_iterator i = qpidList.begin(); i != qpidList.end(); ++i) + for (::qpid::types::Variant::List::const_iterator i = qpidList.begin(); i != qpidList.end(); ++i) { ::qpid::types::Variant variant = *i; ::qpid::types::VariantType vType = variant.getType(); @@ -375,47 +375,47 @@ namespace Messaging { case ::qpid::types::VAR_BOOL: (*managedList).Add(variant.asBool()); break; - + case ::qpid::types::VAR_UINT8: (*managedList).Add(variant.asUint8()); break; - + case ::qpid::types::VAR_UINT16: (*managedList).Add(variant.asUint16()); break; - + case ::qpid::types::VAR_UINT32: (*managedList).Add(variant.asUint32()); break; - + case ::qpid::types::VAR_UINT64: (*managedList).Add(variant.asUint64()); break; - + case ::qpid::types::VAR_INT8: (*managedList).Add(variant.asInt8()); break; - + case ::qpid::types::VAR_INT16: (*managedList).Add(variant.asInt16()); break; - + case ::qpid::types::VAR_INT32: (*managedList).Add(variant.asInt32()); break; - + case ::qpid::types::VAR_INT64: (*managedList).Add(variant.asInt64()); break; - + case ::qpid::types::VAR_FLOAT: (*managedList).Add(variant.asFloat()); break; - + case ::qpid::types::VAR_DOUBLE: (*managedList).Add(variant.asDouble()); break; - + case ::qpid::types::VAR_STRING: { System::String ^ elementValue = gcnew System::String(variant.asString().c_str()); @@ -441,7 +441,7 @@ namespace Messaging { (*managedList).Add(newList); break; } - + case ::qpid::types::VAR_UUID: { System::String ^ elementValue = gcnew System::String(variant.asUuid().str().c_str()); diff --git a/cpp/bindings/qpid/dotnet/src/TypeTranslator.h b/cpp/bindings/qpid/dotnet/src/TypeTranslator.h index df12689cf8..add30a862c 100644 --- a/cpp/bindings/qpid/dotnet/src/TypeTranslator.h +++ b/cpp/bindings/qpid/dotnet/src/TypeTranslator.h @@ -39,19 +39,19 @@ namespace Messaging { /// public ref class TypeTranslator sealed { - private: - TypeTranslator::TypeTranslator() {} + private: + TypeTranslator::TypeTranslator() {} public: // The given object is a managed Dictionary. // Add its elements to the qpid map. static void ManagedToNative(QpidMap ^ theDictionary, - ::qpid::types::Variant::Map & qpidMap); + ::qpid::types::Variant::Map & qpidMap); // The given object is a managed List. // Add its elements to the qpid list. static void ManagedToNative(QpidList ^ theList, - ::qpid::types::Variant::List & qpidList); + ::qpid::types::Variant::List & qpidList); // The given object is a simple managed type (not a Dictionary or List) // Returns a variant representing simple native type object. @@ -61,11 +61,11 @@ namespace Messaging { // The given object is a qpid map. // Add its elements to the managed Dictionary. static void NativeToManaged(::qpid::types::Variant::Map & qpidMap, - QpidMap ^ dict); + QpidMap ^ dict); // The given object is a qpid list. // Add its elements to the managed List. static void NativeToManaged(::qpid::types::Variant::List & qpidList, - QpidList ^ managedList); + QpidList ^ managedList); }; }}}} diff --git a/cpp/bindings/qpid/dotnet/src/resource1.h b/cpp/bindings/qpid/dotnet/src/resource1.h index 98830aba70..12cc93450b 100644 --- a/cpp/bindings/qpid/dotnet/src/resource1.h +++ b/cpp/bindings/qpid/dotnet/src/resource1.h @@ -23,7 +23,7 @@ // Used by org.apache.qpid.messaging.rc // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 -- cgit v1.2.1