Skip to content
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

Get current working dir fix #431

Merged
merged 4 commits into from Jan 13, 2020
Merged

Conversation

carneyweb
Copy link
Contributor

modified GetCurrentWorkingDir to not cause an infinite loop if an error occurs other than ERANGE.

Logic error was in GetCurrentWorkingDirectory.

Also removed a global variable that was used to cache this value and the initialization of
the global variable. There's no need to cache this value as the call is made very
infrequently.

Also fixed up some formatting.
It turns out that the reason the static initialization code was written is to ensure that
the thread-unsafe code for finding the current working directory (specifically on windows)
happens on a single thread during static initialization.

std::string GetCurrentWorkingDirectory()
{
return s_CurrWorkingDir;
static const std::string currentWorkingDir = InitCurrentWorkingDirectory();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a local static here (instead of a static global as before) makes the code potentially racy with other code executing in a different thread, trying to change the current working directory. The original usage of a static global variable avoids this issue. (Local statics are initialized on first use, which may well be after main() was called, which means their initialization code is potentially executed while other threads are already created, possibly calling OS functions like SetCurrentDirectory. Global statics do not have this problem).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's entirely correct. Here's what the standard says:

"It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or object defined in the same translation unit as the object to be initialized"

In other words, I don't think the standard guarantees that static global initialization happens before main. And even if it did, the order of initialization is not guaranteed, and customer written constructors for global object could also call SetCurrentDirectory, and this may or may not happen before the initialization of s_CurrentWorkingDirectory in FileSystem.cpp.

I will change it back if you think it's better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a MSDN specific article in mind, but I cannot find a reference anymore (maybe my memory doesn't serve me well). Thanks for digging out the standard paragraph. I agree that this doesn't guarantee what we would actually need.

After all, it doesn't look like we can reliably retrieve the current working directory on Windows. My original point about main() is moot, since the framework is typically loaded (and initialized) as a shared library from some user's program, which can occur well after main was called.

Long story short: Your current solution is not worse than before, but both are flawed. I think we should (in a subsequent task) remove that code completely and either make the framework operate without knowing about the current working directory, or require that information to be passed in during framework initialization.

@jeffdiclemente jeffdiclemente merged commit 9e82fc6 into development Jan 13, 2020
@jeffdiclemente jeffdiclemente deleted the getCurrentWorkingDirFix branch January 13, 2020 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants