diff options
author | Vincent Richard <[email protected]> | 2016-08-25 16:36:05 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2016-08-25 16:36:05 +0000 |
commit | 4e28af3a21dd6bcd9fcffa21da053541e1afdf3a (patch) | |
tree | 5b0dcf2c1a824e5041d43c134babedb37237b834 | |
parent | Issue #138: fixed MSG_NOSIGNAL on Mac OS. (diff) | |
download | vmime-4e28af3a21dd6bcd9fcffa21da053541e1afdf3a.tar.gz vmime-4e28af3a21dd6bcd9fcffa21da053541e1afdf3a.zip |
Fixed issue #139: thread-safe exception handling.
-rw-r--r-- | src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp | 59 | ||||
-rw-r--r-- | src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp | 3 |
2 files changed, 23 insertions, 39 deletions
diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 85082749..16dabb66 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp @@ -71,11 +71,7 @@ TLSSocket_GnuTLS::TLSSocket_GnuTLS(shared_ptr <TLSSession_GnuTLS> session, share TLSSocket_GnuTLS::~TLSSocket_GnuTLS() { - if (m_ex) - { - delete m_ex; - m_ex = NULL; - } + resetException(); try { @@ -194,12 +190,13 @@ size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count) { m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); + resetException(); + const ssize_t ret = gnutls_record_recv (*m_session->m_gnutlsSession, buffer, static_cast <size_t>(count)); - if (m_ex) - internalThrow(); + throwException(); if (ret < 0) { @@ -226,12 +223,13 @@ void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count) for (size_t size = count ; size > 0 ; ) { + resetException(); + ssize_t ret = gnutls_record_send (*m_session->m_gnutlsSession, buffer, static_cast <size_t>(size)); - if (m_ex) - internalThrow(); + throwException(); if (ret < 0) { @@ -260,12 +258,13 @@ size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t c { m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); + resetException(); + ssize_t ret = gnutls_record_send (*m_session->m_gnutlsSession, buffer, static_cast <size_t>(count)); - if (m_ex) - internalThrow(); + throwException(); if (ret < 0) { @@ -307,10 +306,11 @@ void TLSSocket_GnuTLS::handshake() { while (true) { + resetException(); + const int ret = gnutls_handshake(*m_session->m_gnutlsSession); - if (m_ex) - internalThrow(); + throwException(); if (ret < 0) { @@ -498,38 +498,21 @@ shared_ptr <security::cert::certificateChain> TLSSocket_GnuTLS::getPeerCertifica // gnutls_record_recv() calls TLSSocket::gnutlsPullFunc, and exceptions // thrown by the socket can not be caught. -#ifndef VMIME_BUILDING_DOC - -class TLSSocket_DeleteExWrapper : public object +void TLSSocket_GnuTLS::throwException() { -public: - - TLSSocket_DeleteExWrapper(exception* ex) : m_ex(ex) { } - ~TLSSocket_DeleteExWrapper() { delete m_ex; } - -private: - - exception* m_ex; -}; - -#endif // VMIME_BUILDING_DOC + if (m_ex) + { + throw *m_ex; + } +} -void TLSSocket_GnuTLS::internalThrow() +void TLSSocket_GnuTLS::resetException() { - static std::vector <shared_ptr <TLSSocket_DeleteExWrapper> > exToDelete; - if (m_ex) { - // Reset the current exception pointer to prevent the same - // exception from being thrown again later - exception* ex = m_ex; + delete m_ex; m_ex = NULL; - - // To avoid memory leaks - exToDelete.push_back(make_shared <TLSSocket_DeleteExWrapper>(ex)); - - throw *ex; } } diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp index 502d08dc..931cb993 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp @@ -88,7 +88,8 @@ public: private: - void internalThrow(); + void resetException(); + void throwException(); #ifdef LIBGNUTLS_VERSION static ssize_t gnutlsPushFunc(gnutls_transport_ptr_t trspt, const void* data, size_t len); |