diff --git a/src/XrdCl/XrdClFile.cc b/src/XrdCl/XrdClFile.cc index 1b73417a21b..9b1f6de5c11 100644 --- a/src/XrdCl/XrdClFile.cc +++ b/src/XrdCl/XrdClFile.cc @@ -58,7 +58,7 @@ namespace XrdCl // at this point we just give up the hope. //-------------------------------------------------------------------------- if ( DefaultEnv::GetLog() && IsOpen() ) {XRootDStatus status = Close();} - delete pStateHandler; + pStateHandler->Destroy(); delete pPlugIn; } diff --git a/src/XrdCl/XrdClFileStateHandler.cc b/src/XrdCl/XrdClFileStateHandler.cc index 86dc609a95c..aa4a841cda8 100644 --- a/src/XrdCl/XrdClFileStateHandler.cc +++ b/src/XrdCl/XrdClFileStateHandler.cc @@ -61,6 +61,11 @@ namespace { } + virtual ~OpenHandler() + { + pStateHandler->Destroy(); + } + //------------------------------------------------------------------------ // Handle the response //------------------------------------------------------------------------ @@ -121,6 +126,7 @@ namespace //------------------------------------------------------------------------ virtual ~CloseHandler() { + pStateHandler->Destroy(); delete pMessage; } @@ -175,6 +181,7 @@ namespace //------------------------------------------------------------------------ virtual ~StatefulHandler() { + pStateHandler->Destroy(); delete pMessage; delete pSendParams.chunkList; } @@ -243,7 +250,8 @@ namespace XrdCl pDoRecoverRead( true ), pDoRecoverWrite( true ), pFollowRedirects( true ), - pDoneInitOpen( false ) + pDoneInitOpen( false ), + pReferenceCounter(1) { pFileHandle = new uint8_t[4]; ResetMonitoringVars(); @@ -367,7 +375,7 @@ namespace XrdCl msg->Append( path.c_str(), path.length(), 24 ); XRootDTransport::SetDescription( msg ); - OpenHandler *openHandler = new OpenHandler( this, handler ); + OpenHandler *openHandler = new OpenHandler( Self(), handler ); MessageSendParams params; params.timeout = timeout; params.followRedirects = pFollowRedirects; MessageUtils::ProcessSendParams( params ); @@ -424,7 +432,7 @@ namespace XrdCl XRootDTransport::SetDescription( msg ); msg->SetSessionId( pSessionId ); - CloseHandler *closeHandler = new CloseHandler( this, handler, msg ); + CloseHandler *closeHandler = new CloseHandler( Self(), handler, msg ); MessageSendParams params; params.timeout = timeout; params.followRedirects = false; @@ -498,7 +506,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -541,7 +549,7 @@ namespace XrdCl params.chunkList = list; MessageUtils::ProcessSendParams( params ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -585,7 +593,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -619,7 +627,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -655,7 +663,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -728,7 +736,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -767,7 +775,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -802,7 +810,7 @@ namespace XrdCl MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); - StatefulHandler *stHandler = new StatefulHandler( this, handler, msg, params ); + StatefulHandler *stHandler = new StatefulHandler( Self(), handler, msg, params ); return SendOrQueue( *pDataServer, msg, stHandler, params ); } @@ -1461,7 +1469,7 @@ namespace XrdCl req->dlen = path.length(); msg->Append( path.c_str(), path.length(), 24 ); - OpenHandler *openHandler = new OpenHandler( this, 0 ); + OpenHandler *openHandler = new OpenHandler( Self(), 0 ); MessageSendParams params; params.timeout = timeout; MessageUtils::ProcessSendParams( params ); XRootDTransport::SetDescription( msg ); diff --git a/src/XrdCl/XrdClFileStateHandler.hh b/src/XrdCl/XrdClFileStateHandler.hh index b123190d89b..92baa0c0ea3 100644 --- a/src/XrdCl/XrdClFileStateHandler.hh +++ b/src/XrdCl/XrdClFileStateHandler.hh @@ -62,9 +62,25 @@ namespace XrdCl FileStateHandler(); //------------------------------------------------------------------------ - //! Destructor - //------------------------------------------------------------------------ - ~FileStateHandler(); + //! Destructor is private - use 'Destroy' in order to delete the object + //------------------------------------------------------------------------ + void Destroy() + { + XrdSysMutexHelper scopedLock( pMutex ); + --pReferenceCounter; + if( pReferenceCounter == 0) + delete this; + } + + //------------------------------------------------------------------------ + //! Increment reference counter + //------------------------------------------------------------------------ + FileStateHandler* Self() + { + XrdSysMutexHelper scopedLock( pMutex ); + ++pReferenceCounter; + return this; + } //------------------------------------------------------------------------ //! Open the file pointed to by the given URL @@ -305,6 +321,11 @@ namespace XrdCl void AfterForkChild(); private: + //------------------------------------------------------------------------ + //! Destructor + //------------------------------------------------------------------------ + ~FileStateHandler(); + //------------------------------------------------------------------------ // Helper for queuing messages //------------------------------------------------------------------------ @@ -403,7 +424,7 @@ namespace XrdCl //------------------------------------------------------------------------ void MonitorClose( const XRootDStatus *status ); - mutable XrdSysMutex pMutex; + mutable XrdSysRecMutex pMutex; FileStatus pFileState; XRootDStatus pStatus; StatInfo *pStatInfo; @@ -434,6 +455,11 @@ namespace XrdCl uint64_t pVCount; uint64_t pWCount; XRootDStatus pCloseReason; + + //------------------------------------------------------------------------ + // Reference counter + //------------------------------------------------------------------------ + size_t pReferenceCounter; }; }