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

Retry directory creation when ERROR_ALREADY_EXISTS is returned. #118

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

masamitsu-murase
Copy link

First of all, let me thank you for your great work.

This is a bug fix for a corner case.

Issue:

  • When I ran multiple *.exe files simultaneously, which was packaged by Ocra, I faced a fatal error, "Failed to create installation directory.", in rare cases.

Cause:

  • This issue is caused by the following source code in OpCreateInstDirectory:
   UINT tempResult = GetTempFileName(TempPath, _T("ocrastub"), 0, InstDir);
   if (tempResult == 0u)
   {
      FATAL("Failed to get temp file name.");
      return FALSE;
   }

   DEBUG("Creating installation directory: '%s'", InstDir);

   /* Attempt to delete the temp file created by GetTempFileName.
      Ignore errors, i.e. if it doesn't exist. */
   (void)DeleteFile(InstDir);

   if (!CreateDirectory(InstDir, NULL))
   {
      FATAL("Failed to create installation directory.");
      return FALSE;
   }
   return TRUE;

In the above function, the function may fail to create a directory.
Let's assume that we run 2 *exe files packaged by Ocra.

  1. Run exe 1 and exe 2 simultaneously.
  2. Exe 1 calls GetTempFileName to create a temporary file.
    Let's assume that the name of the file is "ocr0123.tmp".
  3. Exe 1 removes the file immediately.
  4. Exe 2 calls GetTempFileName.
    In rare cases, it creates a temporary file, "ocr0123.tmp", whose file name is same as step 2.
  5. Then, exe 1 fails to create a directory because step 4 already created "ocr0123.tmp".

Let me explain the detailed background.

  • Windows generates a temporary file name based on the system time in millisecond.
  • Therefore, step 2 and step 4 may generate identical file name because recent CPUs are so fast...

My changeset retries directory creation when ERROR_ALREADY_EXISTS is returned.

Regards,
Murase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant