From 8fea5c8c2705097b92a2e010b435ff9a6df83f8a Mon Sep 17 00:00:00 2001 From: Michal Simon Date: Tue, 9 May 2017 17:15:18 +0200 Subject: [PATCH] [XrdCl] Fix: xcp hangs if there are no valid sources. --- src/XrdCl/XrdClXCpCtx.cc | 20 ++++++++++++-------- src/XrdCl/XrdClXCpCtx.hh | 20 +++++++++++++++++++- src/XrdCl/XrdClXCpSrc.cc | 8 ++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/XrdCl/XrdClXCpCtx.cc b/src/XrdCl/XrdClXCpCtx.cc index e40061c2463..a44c0afdce6 100644 --- a/src/XrdCl/XrdClXCpCtx.cc +++ b/src/XrdCl/XrdClXCpCtx.cc @@ -148,15 +148,8 @@ XRootDStatus XCpCtx::GetChunk( XrdCl::ChunkInfo &ci ) return XRootDStatus( stOK, suDone ); } - // check if there are any active sources - size_t nbRunning = 0; - std::list::iterator itr; - for( itr = pSources.begin() ; itr != pSources.end() ; ++ itr) - if( (*itr)->IsRunning() ) - ++nbRunning; - // if we don't have active sources it means we failed - if( nbRunning == 0 ) + if( GetRunning() == 0 ) { XrdSysCondVarHelper lck( pDoneCV ); pDone = true; @@ -191,5 +184,16 @@ bool XCpCtx::AllDone() return pDone; } +size_t XCpCtx::GetRunning() +{ + // count active sources + size_t nbRunning = 0; + std::list::iterator itr; + for( itr = pSources.begin() ; itr != pSources.end() ; ++ itr) + if( (*itr)->IsRunning() ) + ++nbRunning; + return nbRunning; +} + } /* namespace XrdCl */ diff --git a/src/XrdCl/XrdClXCpCtx.hh b/src/XrdCl/XrdClXCpCtx.hh index 6179f60e086..7c875b0ddea 100644 --- a/src/XrdCl/XrdClXCpCtx.hh +++ b/src/XrdCl/XrdClXCpCtx.hh @@ -126,7 +126,7 @@ class XCpCtx int64_t GetSize() { XrdSysCondVarHelper lck( pFileSizeCV ); - while( pFileSize < 0 ) pFileSizeCV.Wait(); + while( pFileSize < 0 && GetRunning() > 0 ) pFileSizeCV.Wait(); return pFileSize; } @@ -186,8 +186,26 @@ class XCpCtx */ bool AllDone(); + /** + * Notify those who are waiting for initialization. + * In particular the GetSize() caller will be waiting + * on the result of initialization. + */ + void NotifyInitExpectant() + { + pFileSizeCV.Broadcast(); + } + + private: + /** + * Returns the number of active sources + * + * @return : number of active sources + */ + size_t GetRunning(); + /** * Destructor (private). * diff --git a/src/XrdCl/XrdClXCpSrc.cc b/src/XrdCl/XrdClXCpSrc.cc index be8f5e6c892..ad53981a9de 100644 --- a/src/XrdCl/XrdClXCpSrc.cc +++ b/src/XrdCl/XrdClXCpSrc.cc @@ -131,6 +131,14 @@ void XCpSrc::StartDownloading() if( !st.IsOK() ) { pRunning = false; + // notify those who wait for the file + // size, they wont get it from this + // source + pCtx->NotifyInitExpectant(); + // put a null chunk so we are sure + // the main thread doesn't get stuck + // at the sync queue + pCtx->PutChunk( 0 ); return; }