@@ -615,46 +615,90 @@ StringBuffer & EclAgent::getTempfileBase(StringBuffer & buff)
615615 return buff.append (queryTempfilePath ()).append (PATHSEPCHAR).appendLower (wuid);
616616}
617617
618- const char *EclAgent::queryTemporaryFile (const char *fname)
618+ const char *EclAgent::queryTemporaryFile (const char * fname)
619619{
620- StringBuffer tempfilename ;
621- getTempfileBase (tempfilename). append (PATHSEPCHAR). append (fname);
620+ dbgassertex (! isEmptyString (fname)) ;
621+
622622 CriticalBlock crit (tfsect);
623- ForEachItemIn (idx, tempFiles)
624- {
625- if (strcmp (tempFiles. item (idx), tempfilename. str ())== 0 )
626- return tempFiles. item (idx );
627- }
623+
624+ Linked<CTempFileInfo> tempFileInfo = tempFileInfoMap. getValue (fname);
625+ if (tempFileInfo )
626+ return tempFileInfo-> tempFileName . str ( );
627+
628628 StringBuffer errmsg;
629- errmsg.append (" Attempt to read temp file that has not yet been registered: " ).append (tempfilename );
629+ errmsg.append (" Attempt to read temp file that has not yet been registered: " ).append (tempFileInfo-> tempFileName . str () );
630630 fail (0 , errmsg.str ());
631- return 0 ;
632631}
633632
634- const char *EclAgent::noteTemporaryFile (const char *fname)
633+ const char *EclAgent::noteTemporaryFile (const char * fname)
635634{
636- StringBuffer tempfilename;
637- getTempfileBase (tempfilename).append (PATHSEPCHAR).append (fname);
635+ if (isEmptyString (fname))
636+ fail (0 , " Attempt to register empty temp file name" );
637+
638638 CriticalBlock crit (tfsect);
639- tempFiles.append (tempfilename.str ());
640- return tempFiles.item (tempFiles.length ()-1 );
639+
640+ Linked<CTempFileInfo> tempFileInfo = tempFileInfoMap.getValue (fname);
641+ if (tempFileInfo)
642+ {
643+ WARNLOG (" Warning: temp file already registered %s" , fname);
644+ return tempFileInfo->tempFileName .str ();
645+ }
646+
647+ /* tempOwnerId is used at the end of the temporary file name to ensure
648+ * that in the event of a crash, we can use the pid and start time to
649+ * determine if temp files are from a currently running process or not,
650+ * and therefore whether they can be safely deleted.
651+ */
652+ if (tempOwnerId.isEmpty ())
653+ {
654+ unsigned pid = (unsigned )GetCurrentProcessId ();
655+ unsigned __int64 startEpoch = (unsigned __int64)time (nullptr );
656+ tempOwnerId.append (' .' ).append (pid).append (' .' ).append (startEpoch);
657+ }
658+
659+ tempFileInfo.setown (new CTempFileInfo);
660+ tempFileInfoMap.setValue (fname, tempFileInfo.getLink ());
661+
662+ StringBuffer base;
663+ getTempfileBase (base);
664+ base.append (PATHSEPCHAR);
665+ StringBuffer tail;
666+ splitFilename (fname, nullptr , nullptr , &tail, nullptr );
667+ tempFileInfo->tempFileName .append (base).append (tail).append (tempOwnerId);
668+
669+ return tempFileInfo->tempFileName .str ();
641670}
642671
643- const char * EclAgent::noteTemporaryFilespec (const char *fspec )
672+ void EclAgent::removeTemporaryFile (const char * fname )
644673{
645- CriticalBlock crit (tfsect);
646- tempFiles.append (fspec);
647- return tempFiles.item (tempFiles.length ()-1 );
674+ dbgassertex (!isEmptyString (fname));
675+
676+ const char *tempFileName = queryTemporaryFile (fname);
677+ if (tempFileName)
678+ {
679+ Owned<IFile> file = createIFile (tempFileName);
680+ if (file->isFile () != fileBool::foundYes)
681+ return ;
682+
683+ file->remove ();
684+ }
648685}
649686
650687void EclAgent::deleteTempFiles ()
651688{
652689 CriticalBlock crit (tfsect);
653- ForEachItemIn (idx, tempFiles)
690+
691+ if (!tempOwnerId.isEmpty ())
654692 {
655- remove (tempFiles.item (idx));
693+ HashIterator it (tempFileInfoMap);
694+ ForEach (it)
695+ {
696+ const char *originalId = static_cast <const char *>(it.query ().getKey ());
697+ CTempFileInfo *tempFileInfo = tempFileInfoMap.getValue (originalId);
698+ if (tempFileInfo)
699+ removeTemporaryFile (originalId);
700+ }
656701 }
657- tempFiles.kill ();
658702}
659703
660704const char *EclAgent::loadResource (unsigned id)
0 commit comments