Skip to content

Retry directory creation when ERROR_ALREADY_EXISTS is returned. - #118

Open
masamitsu-murase wants to merge 1 commit into
larsch:masterfrom
masamitsu-murase:retry_directory_creation
Open

Retry directory creation when ERROR_ALREADY_EXISTS is returned.#118
masamitsu-murase wants to merge 1 commit into
larsch:masterfrom
masamitsu-murase:retry_directory_creation

Conversation

@masamitsu-murase

Copy link
Copy Markdown

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