diff --git a/src/XrdOuc/XrdOucCache.hh b/src/XrdOuc/XrdOucCache.hh index 0c63f5003aa..d64083dbd6a 100644 --- a/src/XrdOuc/XrdOucCache.hh +++ b/src/XrdOuc/XrdOucCache.hh @@ -244,6 +244,12 @@ virtual XrdOucCacheIO *Base() {return this;} // virtual XrdOucCacheIO *Detach() {return this;} + +// ioActive() returns true if there is any ongoing IO operation. The function is +// used in XrdPosixXrootd::Close() to check if destruction od PosixFile +// has to be done in a separate task. +virtual bool ioActive() { return false; } + // Preread() places Length bytes into the cache from a data source at Offset. // When there is no cache or the associated cache does not support or // allow pre-reads, it's a no-op. Cache placement limits do not apply. diff --git a/src/XrdPosix/XrdPosixFile.cc b/src/XrdPosix/XrdPosixFile.cc index b4eb34433cb..da71d908b00 100644 --- a/src/XrdPosix/XrdPosixFile.cc +++ b/src/XrdPosix/XrdPosixFile.cc @@ -91,7 +91,22 @@ XrdPosixFile::~XrdPosixFile() // if (fPath) free(fPath); } - + +/******************************************************************************/ +/* D e l a y e d D e s t r o y */ +/******************************************************************************/ + +void* XrdPosixFile::DelayedDestroy(void* vpf) +{ +// Static function. +// Called within a dedicated thread if XrdOucCacheIO is io-active. + + XrdPosixFile* pf = (XrdPosixFile*)vpf; + delete pf; + + return 0; +} + /******************************************************************************/ /* C l o s e */ /******************************************************************************/ @@ -250,3 +265,14 @@ bool XrdPosixFile::Stat(XrdCl::XRootDStatus &Status, bool force) delete sInfo; return true; } + +/******************************************************************************/ +/* D o I t */ +/******************************************************************************/ +void XrdPosixFile::DoIt() +{ +// Virtual function of XrdJob. +// Called from XrdPosixXrootd::Close if the file is still IO active. + + delete this; +} diff --git a/src/XrdPosix/XrdPosixFile.hh b/src/XrdPosix/XrdPosixFile.hh index 272b3355b69..9448d092e37 100644 --- a/src/XrdPosix/XrdPosixFile.hh +++ b/src/XrdPosix/XrdPosixFile.hh @@ -47,6 +47,7 @@ #include "XrdPosix/XrdPosixMap.hh" #include "XrdPosix/XrdPosixObject.hh" +#include "Xrd/XrdJob.hh" /******************************************************************************/ /* X r d P o s i x F i l e C l a s s */ /******************************************************************************/ @@ -55,10 +56,11 @@ class XrdPosixCallBack; class XrdPosixFile : public XrdPosixObject, public XrdOucCacheIO, - public XrdCl::ResponseHandler + public XrdCl::ResponseHandler, + public XrdJob { public: - + XrdOucCacheIO *XCio; XrdCl::File clFile; @@ -71,6 +73,8 @@ XrdCl::File clFile; static XrdPosixFile *Alloc(const char *path, XrdPosixCallBack *cbP, int Opts); +static void* DelayedDestroy(void*); + bool Close(XrdCl::XRootDStatus &Status); bool Finalize(XrdCl::XRootDStatus &Status); @@ -112,6 +116,8 @@ static XrdPosixFile *Alloc(const char *path, XrdPosixCallBack *cbP, int Opts); (uint32_t)Len, Buff)); } + void DoIt(); + size_t mySize; time_t myMtime; ino_t myInode; diff --git a/src/XrdPosix/XrdPosixXrootd.cc b/src/XrdPosix/XrdPosixXrootd.cc index a9795e3550b..fcf21734857 100644 --- a/src/XrdPosix/XrdPosixXrootd.cc +++ b/src/XrdPosix/XrdPosixXrootd.cc @@ -146,11 +146,26 @@ int XrdPosixXrootd::Close(int fildes) int ret; if (!(fP = XrdPosixObject::ReleaseFile(fildes))) - {errno = EBADF; return -1;} + {errno = EBADF; return -1;} - ret = fP->Close(Status); - delete fP; - return (ret ? 0 : XrdPosixMap::Result(Status)); + if (fP->XCio->ioActive()) + { + if (XrdPosixGlobals::schedP ) + { + XrdPosixGlobals::schedP->Schedule(fP); + } + else { + pthread_t tid; + XrdSysThread::Run(&tid, XrdPosixFile::DelayedDestroy, fP, 0, "PosixFileDestroy"); + } + return 0; + } + else + { + ret = fP->Close(Status); + delete fP; + return (ret ? 0 : XrdPosixMap::Result(Status)); + } } /******************************************************************************/