From: g0dil Date: Wed, 6 Feb 2008 09:51:41 +0000 (+0000) Subject: Socket: BUGFIX: Move incorrect v-function call out of FileBody destructor X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=31243b46fbd06bc6301acca8fbd8153829c61b0a;p=senf.git Socket: BUGFIX: Move incorrect v-function call out of FileBody destructor git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@670 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/FileHandle.cc b/Socket/FileHandle.cc index 2872469..4ce3835 100644 --- a/Socket/FileHandle.cc +++ b/Socket/FileHandle.cc @@ -38,6 +38,36 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::FileBody + +prefix_ void senf::FileBody::close() +{ + if (!valid()) + throwErrno(EBADF); + v_close(); + fd_ = -1; +} + +prefix_ void senf::FileBody::terminate() +{ + if (valid()) { + v_terminate(); + fd_ = -1; + } +} + +prefix_ void senf::FileBody::destroyClose() +{ + if (valid()) + try { + close(); + } + catch (...) { + terminate(); + } +} + prefix_ void senf::FileBody::v_close() { if (::close(fd_) != 0) diff --git a/Socket/FileHandle.cci b/Socket/FileHandle.cci index 9f82d08..79308ae 100644 --- a/Socket/FileHandle.cci +++ b/Socket/FileHandle.cci @@ -41,33 +41,6 @@ prefix_ senf::FileBody::FileBody(int fd) : fd_(fd) {} -prefix_ senf::FileBody::~FileBody() -{ - if (valid()) - try { - close(); - } - catch (...) { - terminate(); - } -} - -prefix_ void senf::FileBody::close() -{ - if (!valid()) - throwErrno(EBADF); - v_close(); - fd_ = -1; -} - -prefix_ void senf::FileBody::terminate() -{ - if (valid()) { - v_terminate(); - fd_ = -1; - } -} - prefix_ senf::FileHandle senf::FileBody::handle() { return FileHandle(ptr(this)); @@ -196,6 +169,12 @@ prefix_ senf::FileHandle::FileHandle() : body_(0) {} +prefix_ senf::FileHandle::~FileHandle() +{ + if (body_ && ! body().is_shared()) + body().destroyClose(); +} + prefix_ senf::FileHandle::FileHandle(std::auto_ptr body) : body_(body.release()) {} diff --git a/Socket/FileHandle.hh b/Socket/FileHandle.hh index 2ae609a..5b0e34d 100644 --- a/Socket/FileHandle.hh +++ b/Socket/FileHandle.hh @@ -123,6 +123,7 @@ namespace senf { ///@{ FileHandle(); + ~FileHandle(); // my default constructor // default copy constructor diff --git a/Socket/FileHandle.ih b/Socket/FileHandle.ih index cdc775d..e87e319 100644 --- a/Socket/FileHandle.ih +++ b/Socket/FileHandle.ih @@ -83,7 +83,10 @@ namespace senf { constructor not some arbitrary id even if you overload all the virtual members. If the file descriptor is -1 the resulting body/handle is not valid() */ - virtual ~FileBody(); + + // NO DESTRUCTOR HERE - destructors and virtual functions don't mix. What would be in the + // the destructor is in 'destroyClose()' which is called from FileHandle::~FileHandle() + // *before* the last handle dies. // no copy // no conversion constructors @@ -98,6 +101,7 @@ namespace senf { void close(); void terminate(); + void destroyClose(); bool readable() const; void waitReadable() const; diff --git a/Socket/SocketHandle.cc b/Socket/SocketHandle.cc index 14fd6b2..aa0cf61 100644 --- a/Socket/SocketHandle.cc +++ b/Socket/SocketHandle.cc @@ -36,6 +36,19 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// senf::SocketBody + +prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod) +{ + map["file.handle"] << fd(); + map["file.refcount"] << refcount(); + map["socket.server"] << isServer(); + map["socket.protocol"] << v_protocolName(); + map["socket.protocol.policy"] << prettyName(typeid(protocol().policy())); + protocol().state(map,lod); +} + prefix_ void senf::SocketBody::v_close() { protocol().close(); @@ -52,16 +65,6 @@ prefix_ bool senf::SocketBody::v_eof() return protocol().eof(); } -prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod) -{ - map["file.handle"] << fd(); - map["file.refcount"] << refcount(); - map["socket.server"] << isServer(); - map["socket.protocol"] << v_protocolName(); - map["socket.protocol.policy"] << prettyName(typeid(protocol().policy())); - protocol().state(map,lod); -} - /////////////////////////////////////////////////////////////////////////// // senf::detail::StateMapOrdering diff --git a/Socket/SocketHandle.test.cc b/Socket/SocketHandle.test.cc index e377f0b..709fb9f 100644 --- a/Socket/SocketHandle.test.cc +++ b/Socket/SocketHandle.test.cc @@ -45,7 +45,7 @@ namespace { MySocketHandle() : senf::SocketHandle( std::auto_ptr( - new senf::ProtocolSocketBody(false))) + new senf::ProtocolSocketBody(false, 0))) {} }; @@ -66,33 +66,38 @@ BOOST_AUTO_UNIT_TEST(socketHandle) >::policy OtherSocketPolicy; typedef senf::SocketHandle OtherSocketHandle; - MySocketHandle myh; - OtherSocketHandle osh (myh); - osh = myh; - - typedef senf::SocketHandle SomeSocketHandle; - SomeSocketHandle ssh = senf::static_socket_cast(osh); - - BOOST_CHECK_NO_THROW( senf::dynamic_socket_cast(osh) ); - - typedef senf::SocketHandle< senf::MakeSocketPolicy< - OtherSocketPolicy, - senf::NoAddressingPolicy - >::policy> SomeOtherSocketHandle; - - BOOST_CHECK_THROW( senf::dynamic_socket_cast(osh), - std::bad_cast ); - BOOST_CHECK_THROW( senf::dynamic_socket_cast( - senf::FileHandle(FDHandle())), - std::bad_cast ); - - BOOST_CHECK_EQUAL( myh.dumpState(), - "file.handle: -1\n" - "file.refcount: 3\n" - "handle: senf::SocketHandle >\n" - "socket.protocol: senf::test::SomeProtocol\n" - "socket.protocol.policy: senf::SocketPolicy\n" - "socket.server: false\n" ); + { + MySocketHandle myh; + OtherSocketHandle osh (myh); + osh = myh; + + typedef senf::SocketHandle SomeSocketHandle; + SomeSocketHandle ssh = senf::static_socket_cast(osh); + + BOOST_CHECK_NO_THROW( senf::dynamic_socket_cast(osh) ); + + typedef senf::SocketHandle< senf::MakeSocketPolicy< + OtherSocketPolicy, + senf::NoAddressingPolicy + >::policy> SomeOtherSocketHandle; + + BOOST_CHECK_THROW( senf::dynamic_socket_cast(osh), + std::bad_cast ); + BOOST_CHECK_THROW( senf::dynamic_socket_cast( + senf::FileHandle(FDHandle())), + std::bad_cast ); + + BOOST_CHECK_EQUAL( myh.dumpState(), + "file.handle: 0\n" + "file.refcount: 3\n" + "handle: senf::SocketHandle >\n" + "socket.protocol: senf::test::SomeProtocol\n" + "socket.protocol.policy: senf::SocketPolicy\n" + "socket.server: false\n" ); + } + + // Ensure, the destructor is called and calls the correct close() implementation + BOOST_CHECK_EQUAL( senf::test::SomeProtocol::closeCount(), 1u ); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/SocketProtocol.cc b/Socket/SocketProtocol.cc index e252603..ca28664 100644 --- a/Socket/SocketProtocol.cc +++ b/Socket/SocketProtocol.cc @@ -33,6 +33,7 @@ //#include "SocketProtocol.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// + prefix_ void senf::SocketProtocol::close() const { diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index db71a83..72ddad5 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -174,7 +174,8 @@ namespace senf { virtual void close() const; ///< Close socket /**< This override will automatically \c shutdown() the socket whenever it is closed. - \throws senf::SystemException */ + \throws senf::SystemException + \fixme Move into (at least) BSDSOcketProtocol */ virtual void terminate() const; ///< Forcibly close socket /**< This override will automatically \c shutdown() the @@ -182,7 +183,8 @@ namespace senf { disable SO_LINGER to ensure, that v_terminate will not block. Like the overriden method, this member will ignore failures and will never throw. It is therefore safe to be - called from a destructor. */ + called from a destructor. + \fixme Move into (at least) BSDSocketProtocol */ virtual void state(SocketStateMap & map, unsigned lod) const; ///< Return socket state information diff --git a/Socket/SocketProtocol.test.hh b/Socket/SocketProtocol.test.hh index 3ca682a..c5073f3 100644 --- a/Socket/SocketProtocol.test.hh +++ b/Socket/SocketProtocol.test.hh @@ -27,6 +27,7 @@ #include "SocketProtocol.hh" #include "SocketPolicy.test.hh" #include "ProtocolClientSocketHandle.hh" +#include "../Utils/Logger/SenfLog.hh" //#include "SocketProtocol.test.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -40,13 +41,24 @@ namespace test { public: ~SomeProtocol() {} - void init_client() const {} - void init_server() const {} + void init_client() const { fd(0); } + void init_server() const { fd(0); } unsigned available() const { return Policy::ReadPolicy::TEST_SIZE; } bool eof() const { return false; } + + virtual void close() const { + SENF_LOG(( "Closing socket ..." )); + closeCount(1); + } + + static unsigned closeCount(unsigned inc=0) { + static unsigned counter (0); + counter += inc; + return counter; + } }; }} diff --git a/debian/rules b/debian/rules index 911d1b8..b87c105 100755 --- a/debian/rules +++ b/debian/rules @@ -76,7 +76,7 @@ build-indep-stamp: configure-stamp scons all_docs scons linklint scons fixlinks - scons $(destdir)/usr/include $(destdir)/usr/share/doc $(SCONS_OPTIONS) \ + scons $(destdir)/usr/include $(destdir)/usr/share/doc \ PREFIX='$(destdir)/usr' \ DOCINSTALLDIR='$$PREFIX/share/doc/libsenf-doc/html' \ INCLUDEINSTALLDIR='$$PREFIX/include/senf' diff --git a/doclib/SConscript b/doclib/SConscript index 102709e..276ec2d 100644 --- a/doclib/SConscript +++ b/doclib/SConscript @@ -29,8 +29,9 @@ # 1. Scanning the Doxyfile's # # The doxygen builder scans all documentation source files which have -# the text 'doxyfile' in any case within them. It understands @INCLUDE -# directives and will find all the dependencies of the documentation: +# the text 'doxyfile' in any case in their name. It understands +# @INCLUDE directives and will find all the dependencies of the +# documentation: # # * All the source files as selected by INPUT, INPUT_PATTERN, # RECURSIVE and so on. @@ -94,14 +95,14 @@ # # * 'doclib/dot' calls the real dot binary. If the resulting image is # more than 800 pixels wide, dot is called again, this time using -# the oposite rang direction (top-bottom vs. left-right). Then the -# image with the smaller width is selected and returned. +# the oposite rank direction (top-bottom vs. left-right). The image +# with the smaller width is selected and returned. # # * after doxygen is finished, the list of referenced tag-files is # checked. For each tag file the directory is found, where the # documentation is generated (by scanning the Doxyfile which is # repsonsible for building the tag file). For every tag file, the -# correct 'insstalldox' command is generated +# correct 'installdox' command is generated. # # * The stamp files are created # @@ -118,9 +119,9 @@ # namespace. # # * All html files are processed by 'doclib/html-munge.xsl'. However, -# since the documentation generated by doxygen is completely broken -# we need to preprocess the html files with a simple 'sed' script -# and 'tidy' before 'xsltproc' even accepts the html code. +# since the documentation generated by doxygen is completely invalid +# html we need to preprocess the html files with a simple 'sed' +# script and 'tidy' before 'xsltproc' even accepts the html code. # # * We use the generated xml output of doxygen to generate an XML # fragment for the global cross reference. This fragment is