Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-12-09 19:50:36 +0300
committerCorinna Vinschen <corinna@vinschen.de>2010-12-09 19:50:36 +0300
commit0dcfb061cf1e2ed2acfb0b605ac3933ff726e17f (patch)
treeaea009c4ffdd2338a1942fc5cf6dccb2f6f6bec6 /winsup/cygwin/autoload.cc
parent23dbdc2aaa4b620a40596a50e24f2ea0a8ecb78f (diff)
* autoload.cc (RETRY_COUNT): New define.
(std_dll_init): Restructure loop to retry loading a DLL only if specific errors occur. If these errors persist, try to load DLL with name only.
Diffstat (limited to 'winsup/cygwin/autoload.cc')
-rw-r--r--winsup/cygwin/autoload.cc46
1 files changed, 32 insertions, 14 deletions
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 1c6429204..2e495ad6a 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -204,6 +204,8 @@ union retchain
long long ll;
};
+#define RETRY_COUNT 10
+
/* The standard DLL initialization routine. */
__attribute__ ((used, noinline)) static long long
std_dll_init ()
@@ -221,27 +223,43 @@ std_dll_init ()
while (InterlockedIncrement (&dll->here));
else if (!dll->handle)
{
- HANDLE h;
fenv_t fpuenv;
fegetenv (&fpuenv);
WCHAR dll_path[MAX_PATH];
+ DWORD err = ERROR_SUCCESS;
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
- dll->handle = NULL;
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
since there have been reports of this in the mailing list, retry
- several times before giving up. */
- for (int i = 1; !dll->handle && i <= 5; i++)
- if ((h = LoadLibraryW (dll_path)) != NULL)
- dll->handle = h;
- /* FIXME: This isn't quite right. Probably should check for specific
- error codes. */
- else if ((func->decoration & 1))
- dll->handle = INVALID_HANDLE_VALUE;
- else if (i < 5)
- yield ();
- else
- api_fatal ("could not load %W, %E", dll_path);
+ several times before giving up. */
+ for (int i = 1; i <= RETRY_COUNT; i++)
+ {
+ /* If loading the library succeeds, just leave the loop. */
+ if ((dll->handle = LoadLibraryW (dll_path)) != NULL)
+ break;
+ /* Otherwise check error code returned by LoadLibrary. If the
+ error code is neither NOACCESS nor DLL_INIT_FAILED, break out
+ of the loop. */
+ err = GetLastError ();
+ if (err != ERROR_NOACCESS && err != ERROR_DLL_INIT_FAILED)
+ break;
+ if (i < RETRY_COUNT)
+ yield ();
+ }
+ if (!dll->handle)
+ {
+ /* If LoadLibrary with full path returns one of the weird errors
+ reported on the Cygwin mailing list, retry with only the DLL
+ name. Checking the error codes allows to restrict loading
+ with just the DLL name to this specific problem. */
+ if ((err == ERROR_NOACCESS || err == ERROR_DLL_INIT_FAILED)
+ && (dll->handle = LoadLibraryW (dll->name)) != NULL)
+ ;
+ else if ((func->decoration & 1))
+ dll->handle = INVALID_HANDLE_VALUE;
+ else
+ api_fatal ("could not load %W, %E", dll_path);
+ }
fesetenv (&fpuenv);
}