-
Notifications
You must be signed in to change notification settings - Fork 310
HPCC-36047 hthor refactor temporary file handling #21128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -610,51 +610,85 @@ const char *EclAgent::queryTempfilePath() | |
| return agentTempDir.str(); | ||
| } | ||
|
|
||
| StringBuffer & EclAgent::getTempfileBase(StringBuffer & buff) | ||
| StringBuffer &EclAgent::getTempfileBase(StringBuffer &buff) | ||
| { | ||
| return buff.append(queryTempfilePath()).append(PATHSEPCHAR).appendLower(wuid); | ||
| } | ||
|
|
||
| const char *EclAgent::queryTemporaryFile(const char *fname) | ||
| void EclAgent::buildTempFilename(StringBuffer &tempFilename, const char *name) | ||
| { | ||
| StringBuffer tempfilename; | ||
| getTempfileBase(tempfilename).append(PATHSEPCHAR).append(fname); | ||
| CriticalBlock crit(tfsect); | ||
| ForEachItemIn(idx, tempFiles) | ||
| getTempfileBase(tempFilename).append(PATHSEPCHAR).append(name); | ||
| } | ||
|
|
||
| const char *EclAgent::queryTemporaryFile(const char *name) | ||
| { | ||
| dbgassertex(!isEmptyString(name)); | ||
|
|
||
| StringBuffer tempFilename; | ||
| buildTempFilename(tempFilename, name); | ||
|
|
||
| { | ||
| if (strcmp(tempFiles.item(idx), tempfilename.str())==0) | ||
| return tempFiles.item(idx); | ||
| CriticalBlock crit(tfsect); | ||
|
|
||
| auto it = tempFileSet.find(tempFilename.str()); | ||
| if (it != tempFileSet.end()) | ||
| return it->c_str(); | ||
| } | ||
| StringBuffer errmsg; | ||
| errmsg.append("Attempt to read temp file that has not yet been registered: ").append(tempfilename); | ||
|
|
||
| VStringBuffer errmsg("Attempt to read temp file that has not yet been registered: %s", name); | ||
| fail(0, errmsg.str()); | ||
| return 0; | ||
| return nullptr; | ||
| } | ||
|
|
||
| const char *EclAgent::noteTemporaryFile(const char *fname) | ||
| const char *EclAgent::noteTemporaryFile(const char *name) | ||
| { | ||
| StringBuffer tempfilename; | ||
| getTempfileBase(tempfilename).append(PATHSEPCHAR).append(fname); | ||
| CriticalBlock crit(tfsect); | ||
| tempFiles.append(tempfilename.str()); | ||
| return tempFiles.item(tempFiles.length()-1); | ||
| dbgassertex(!isEmptyString(name)); | ||
|
|
||
| StringBuffer tempFilename; | ||
| buildTempFilename(tempFilename, name); | ||
|
|
||
| std::pair<std::set<std::string>::iterator, bool> inserted; | ||
| { | ||
| CriticalBlock crit(tfsect); | ||
|
|
||
| inserted = tempFileSet.emplace(tempFilename.str()); | ||
| } | ||
|
|
||
| // The returned pointer refers to the std::string stored in tempFileSet and | ||
| // is only valid while that entry remains in the set. | ||
|
|
||
| if (!inserted.second) | ||
| { | ||
| VStringBuffer errmsg("Temp file already registered: %s", name); | ||
| fail(0, errmsg.str()); | ||
| return nullptr; | ||
| } | ||
|
|
||
| return inserted.first->c_str(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is thread-safe afaics, as long as tempFileSet entries are not removed or altered (which should be the case). It is probably worth adding a clarifying comment to make it clear to the casual reader of the semantics.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment added in a4755f1 |
||
| } | ||
|
|
||
| const char *EclAgent::noteTemporaryFilespec(const char *fspec) | ||
| void EclAgent::removeTemporaryFile(const char *fname) | ||
| { | ||
| dbgassertex(!isEmptyString(fname)); | ||
|
|
||
| CriticalBlock crit(tfsect); | ||
| tempFiles.append(fspec); | ||
| return tempFiles.item(tempFiles.length()-1); | ||
|
|
||
| auto it = tempFileSet.find(std::string(fname)); | ||
| dbgassertex(it != tempFileSet.end()); | ||
| if (it != tempFileSet.end()) | ||
| { | ||
| remove(it->c_str()); | ||
| tempFileSet.erase(it); | ||
| } | ||
| } | ||
|
|
||
| void EclAgent::deleteTempFiles() | ||
| { | ||
| CriticalBlock crit(tfsect); | ||
| ForEachItemIn(idx, tempFiles) | ||
| { | ||
| remove(tempFiles.item(idx)); | ||
| } | ||
| tempFiles.kill(); | ||
|
|
||
| for (const auto& f : tempFileSet) | ||
| remove(f.c_str()); | ||
| tempFileSet.clear(); | ||
| } | ||
|
|
||
| const char *EclAgent::loadResource(unsigned id) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move as much as possible outside of the crit, i.e. if it can't contend, don't keep it a mutex.
It's semi needed now, because buildTempFilename does a one-time initialization ("tempFilePrefix"), however, this mutex should really be protecting the std::set only.
See comment re. one-time initialization of the prefix above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code in tfsect critical section moved out where possible in 591f31b