Date: Thursday, January 11, 2007 @ 19:37:07
Author: marc
Path: /cvsroot/carob/carob
Modified: include/Connection.hpp (1.80 -> 1.81) src/Connection.cpp (1.102
-> 1.103) src/DriverSocket.cpp (1.23 -> 1.24) src/JavaSocket.cpp
(1.67 -> 1.68)
Fix for CAROB-101. Do not hide CodecException but rethrow it as an
UnexpectedException (should be a ProtocolException). In Connection.cpp
retry/reconnect loop, catch ProtocolException and UnexpectedException
and abort thanks to new method corruptedConnectionClose().
Implemented portable_close(socket) in JavaSocket.cpp and use it
immediately on CodecException
------------------------+
include/Connection.hpp | 5 +++++
src/Connection.cpp | 35 ++++++++++++++++++++++++++++++++++-
src/DriverSocket.cpp | 25 +++++++++++++++++++++----
src/JavaSocket.cpp | 45 ++++++++++++++++++++++++++++++++++-----------
4 files changed, 94 insertions(+), 16 deletions(-)
Index: carob/include/Connection.hpp
diff -u carob/include/Connection.hpp:1.80 carob/include/Connection.hpp:1.81
--- carob/include/Connection.hpp:1.80 Thu Jan 11 17:42:36 2007
+++ carob/include/Connection.hpp Thu Jan 11 19:37:07 2007
@@ -735,6 +735,11 @@
*/
void reconnectOrDie() throw (ConnectionException,
DriverException, UnexpectedException);
+
+
+
+ void corruptedConnectionClose(const CarobException& reason);
+
/**
* Forbids Connection creation that would lead to unexpected state.
* A connection is either created, ie. connected to a controller or destroyed
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.102 carob/src/Connection.cpp:1.103
--- carob/src/Connection.cpp:1.102 Thu Jan 11 17:42:35 2007
+++ carob/src/Connection.cpp Thu Jan 11 19:37:07 2007
@@ -33,6 +33,8 @@
#include "CarobException.hpp"
#include <string>
+#include <sstream>
+
#ifdef __MINGW32__
#define sleep _sleep
@@ -63,11 +65,19 @@
#define FO_CATCH_NTIMES\
break; /* no exception means success: get out of the retry for loop */\
}\
- catch (SocketIOException sioe)\
+ catch (const SocketIOException& sioe)\
{\
::sleep(static_cast<int>(foCnt*0.5)); /* sleep incrementally */\
reconnectOrDie();\
}\
+ catch (const ProtocolException& pe)\
+ {\
+ corruptedConnectionClose(pe); throw; /* TODO: type rethrown? */ \
+ }\
+ catch (const UnexpectedException& ue) /* because of CAROB-101 */ \
+ {\
+ corruptedConnectionClose(ue); throw; \
+ }\
}
Connection::Connection(ConnectionParameters& prms)
@@ -266,6 +276,29 @@
}
}
+void Connection::corruptedConnectionClose(const CarobException& reason)
+{
+ const std::wstring fctName(L"Connection::corruptedConnectionClose(const
CarobException&)");
+
+ std::wostringstream buffer;
+ buffer << reason;
+ logError(fctName, buffer.str());
+
+ // Brutally close network socket FIRST
+ try {
+ driverSocketPtr->closeSocket();
+ } catch (const SocketIOException& sioe) {
+ std::wostringstream buffer;
+ buffer << L"failed to force ->closeSocket(), probably already closed? " <<
sioe.description();
+ logError(fctName, buffer.str());
+ }
+
+ // Then call the regular close(). It will try to send the close
+ // command, and fail. We will survive anyway.
+ close();
+}
+
+
bool Connection::close()
{
const wstring fctName(L"Connection::close");
Index: carob/src/DriverSocket.cpp
diff -u carob/src/DriverSocket.cpp:1.23 carob/src/DriverSocket.cpp:1.24
--- carob/src/DriverSocket.cpp:1.23 Mon Dec 18 17:55:31 2006
+++ carob/src/DriverSocket.cpp Thu Jan 11 19:37:07 2007
@@ -44,12 +44,14 @@
}
catch (CodecException ce)
{
- std::wostringstream buffer;
- buffer<<L"Invalid input string '"<<s<<L"' to send. Exception was:"<<ce;
+ // not so bad fix for CAROB-101
if (isErrorEnabled())
{
+ std::wostringstream buffer;
+ buffer<<L"CodecException while UTF8 encoding string to send:'"<< s <<
L"'. " << ce.description();;
logError(L"DriverSocket::operator<<(wstring)", buffer.str());
}
+ throw UnexpectedException(ce.description(), ce.getSQLState(), &ce);
}
return *this;
}
@@ -80,8 +82,23 @@
std::wstring chunk;
while (static_cast<int>(sizeRead)<strSize)
{
- // FIXME: catch CodecException here. See CAROB-101
- sizeRead += readJavaUTF(chunk);
+ try
+ {
+ sizeRead += readJavaUTF(chunk);
+ }
+ catch (CodecException ce)
+ {
+ // not so bad fix for CAROB-101
+ if (isErrorEnabled())
+ {
+ std::wostringstream buffer;
+ // Here GNU libstdc++ 4.0.2 ostream.tcc will just widen the bytes
to wchar_t
+ // Not sure this is portable
+ buffer<<L"CodecException while UTF8-decoding byte sequence
received'"<< chunk << L"'. " << ce.description();
+ logError(L"DriverSocket::operator<<(wstring)", buffer.str());
+ }
+ throw UnexpectedException(ce.description(), ce.getSQLState(), &ce);
+ }
s += chunk;
}
}
Index: carob/src/JavaSocket.cpp
diff -u carob/src/JavaSocket.cpp:1.67 carob/src/JavaSocket.cpp:1.68
--- carob/src/JavaSocket.cpp:1.67 Fri Jan 5 15:58:37 2007
+++ carob/src/JavaSocket.cpp Thu Jan 11 19:37:07 2007
@@ -16,7 +16,7 @@
* limitations under the License.
*
* Initial developer(s): Gilles Rayrat
- * Contributor(s): Zsolt Simon
+ * Contributor(s): Zsolt Simon, Marc Herbert
*/
#include "JavaSocket.hpp"
@@ -66,7 +66,7 @@
}
catch (SocketIOException e)
{
- if (isInfoEnabled())
+ if (isWarnEnabled())
logInfo(fctName, L"Socket closure failed. Exception is: " +
e.description());
}
}
@@ -184,16 +184,23 @@
return false;
}
+namespace {
+inline int portable_close(int socket_fd)
+{
+#ifdef __MINGW32__
+ return closesocket(socket_fd);
+#else
+ return close(socket_fd);
+#endif
+}
+}
+
bool JavaSocket::closeSocket() throw (SocketIOException, UnexpectedException)
{
const wstring fctName(L"closeSocket");
if (isValid())
{
-#ifdef __MINGW32__
- if (closesocket(socket_fd) != 0)
-#else
- if (close(socket_fd) != 0)
-#endif
+ if (portable_close(this->socket_fd) != 0)
{
wstring msg(L"Could not close socket. Error is ");
#ifdef __MINGW32__
@@ -220,7 +227,17 @@
{
const wstring fctName(L"JavaSocket::writeJavaUTF");
- std::string utf8str(toUTF8(str));
+ std::string utf8str;
+
+ try
+ {
+ utf8str = toUTF8(str);
+ }
+ catch (const CodecException&)
+ { // Don't leave connection in such a rotten state, see CAROB-101
+ portable_close(this->socket_fd);
+ throw;
+ }
int32_t netlen = htonl(utf8str.length());
@@ -248,10 +265,16 @@
receiveFromSocket(fctName, L"UTF string", utfStr, lenRec, 0);
const std::string received(reinterpret_cast<char*>(utfStr), lenRec);
- try {
+ try
+ {
s = fromUTF8(received);
- } catch (CodecException) {
- delete[] utfStr; throw;
+ }
+ catch (const CodecException&)
+ {
+ delete[] utfStr;
+ // Don't leave connection in such a rotten state, see CAROB-101
+ portable_close(this->socket_fd);
+ throw;
}
sizeRead = (size_t)lenRec;
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits