From 450be4a929a77ea426890012182cec61ae50c7ae Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 12 Dec 2011 00:38:01 +0000 Subject: [PATCH] =?UTF-8?q?=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88?= =?UTF-8?q?=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88=E2=96=88:=20fixed?= =?UTF-8?q?=20error=20with=20destructors=20when=20client=20closes=20connec?= =?UTF-8?q?tion=20without=20received=20all=20data=20[#CONV-2546].?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dbms/include/DB/IO/CompressedWriteBuffer.h | 13 +++++++- dbms/include/DB/IO/RemoteWriteBuffer.h | 31 +++++++++++++------ dbms/include/DB/IO/WriteBufferFromFile.h | 17 ++++++++-- .../DB/IO/WriteBufferFromFileDescriptor.h | 13 +++++++- dbms/include/DB/IO/WriteBufferFromOStream.h | 13 +++++++- 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/dbms/include/DB/IO/CompressedWriteBuffer.h b/dbms/include/DB/IO/CompressedWriteBuffer.h index 0a9565ad209..6f724a6b72c 100644 --- a/dbms/include/DB/IO/CompressedWriteBuffer.h +++ b/dbms/include/DB/IO/CompressedWriteBuffer.h @@ -67,7 +67,18 @@ public: ~CompressedWriteBuffer() { - nextImpl(); + bool uncaught_exception = std::uncaught_exception(); + + try + { + nextImpl(); + } + catch (...) + { + /// Если до этого уже было какое-то исключение, то второе исключение проигнорируем. + if (!uncaught_exception) + throw; + } } }; diff --git a/dbms/include/DB/IO/RemoteWriteBuffer.h b/dbms/include/DB/IO/RemoteWriteBuffer.h index ce15b33a799..339f8097cb6 100644 --- a/dbms/include/DB/IO/RemoteWriteBuffer.h +++ b/dbms/include/DB/IO/RemoteWriteBuffer.h @@ -89,19 +89,30 @@ public: virtual ~RemoteWriteBuffer() { - nextImpl(); + bool uncaught_exception = std::uncaught_exception(); - Poco::Net::HTTPResponse response; - std::istream & istr = session.receiveResponse(response); - Poco::Net::HTTPResponse::HTTPStatus status = response.getStatus(); - - if (status != Poco::Net::HTTPResponse::HTTP_OK) + try { - std::stringstream error_message; - error_message << "Received error from remote server " << uri_str << ". HTTP status code: " - << status << ", body: " << istr.rdbuf(); + nextImpl(); - throw Exception(error_message.str(), ErrorCodes::RECEIVED_ERROR_FROM_REMOTE_IO_SERVER); + Poco::Net::HTTPResponse response; + std::istream & istr = session.receiveResponse(response); + Poco::Net::HTTPResponse::HTTPStatus status = response.getStatus(); + + if (status != Poco::Net::HTTPResponse::HTTP_OK) + { + std::stringstream error_message; + error_message << "Received error from remote server " << uri_str << ". HTTP status code: " + << status << ", body: " << istr.rdbuf(); + + throw Exception(error_message.str(), ErrorCodes::RECEIVED_ERROR_FROM_REMOTE_IO_SERVER); + } + } + catch (...) + { + /// Если до этого уже было какое-то исключение, то второе исключение проигнорируем. + if (!uncaught_exception) + throw; } } }; diff --git a/dbms/include/DB/IO/WriteBufferFromFile.h b/dbms/include/DB/IO/WriteBufferFromFile.h index 2be923bf0fe..cc84260775c 100644 --- a/dbms/include/DB/IO/WriteBufferFromFile.h +++ b/dbms/include/DB/IO/WriteBufferFromFile.h @@ -28,9 +28,20 @@ public: virtual ~WriteBufferFromFile() { - next(); - if (0 != close(fd)) - throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE); + bool uncaught_exception = std::uncaught_exception(); + + try + { + next(); + if (0 != close(fd)) + throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE); + } + catch (...) + { + /// Если до этого уже было какое-то исключение, то второе исключение проигнорируем. + if (!uncaught_exception) + throw; + } } virtual std::string getFileName() diff --git a/dbms/include/DB/IO/WriteBufferFromFileDescriptor.h b/dbms/include/DB/IO/WriteBufferFromFileDescriptor.h index 7097bb4a0cc..e76f7e7de99 100644 --- a/dbms/include/DB/IO/WriteBufferFromFileDescriptor.h +++ b/dbms/include/DB/IO/WriteBufferFromFileDescriptor.h @@ -49,7 +49,18 @@ public: virtual ~WriteBufferFromFileDescriptor() { - nextImpl(); + bool uncaught_exception = std::uncaught_exception(); + + try + { + nextImpl(); + } + catch (...) + { + /// Если до этого уже было какое-то исключение, то второе исключение проигнорируем. + if (!uncaught_exception) + throw; + } } }; diff --git a/dbms/include/DB/IO/WriteBufferFromOStream.h b/dbms/include/DB/IO/WriteBufferFromOStream.h index a45c1cb97d8..671265d229f 100644 --- a/dbms/include/DB/IO/WriteBufferFromOStream.h +++ b/dbms/include/DB/IO/WriteBufferFromOStream.h @@ -35,7 +35,18 @@ public: ~WriteBufferFromOStream() { - nextImpl(); + bool uncaught_exception = std::uncaught_exception(); + + try + { + nextImpl(); + } + catch (...) + { + /// Если до этого уже было какое-то исключение, то второе исключение проигнорируем. + if (!uncaught_exception) + throw; + } } };