diff options
author | Christopher Faylor <me@cgf.cx> | 2010-10-02 01:53:11 +0400 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2010-10-02 01:53:11 +0400 |
commit | b66f254618868f72fca74883c440432300d717bd (patch) | |
tree | 6c6f941d89359e051ae6acc8201f26f09931937d /winsup/cygwin | |
parent | dc9d9c731b53e2128b3ec9bdec340c9b9f7f089d (diff) |
* autoload.cc (std_dll_init): Add a retry loop.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 4 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 25 |
2 files changed, 21 insertions, 8 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 70ef991b1..1fe30a808 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,7 @@ +2010-10-01 Christopher Faylor <me+cygwin@cgf.cx> + + * autoload.cc (std_dll_init): Add a retry loop. + 2010-09-30 Corinna Vinschen <corinna@vinschen.de> * fhandler.cc: Drop including nfs.h. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index c034db51f..bac40b4b9 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -208,7 +208,6 @@ union retchain __attribute__ ((used, noinline)) static long long std_dll_init () { - HANDLE h; struct func_info *func = (struct func_info *) __builtin_return_address (0); struct dll_info *dll = func->dll; retchain ret; @@ -222,21 +221,31 @@ std_dll_init () while (InterlockedIncrement (&dll->here)); else if (!dll->handle) { + HANDLE h; fenv_t fpuenv; fegetenv (&fpuenv); WCHAR dll_path[MAX_PATH]; /* http://www.microsoft.com/technet/security/advisory/2269637.mspx */ wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name); - if ((h = LoadLibraryW (dll_path)) != NULL) - dll->handle = h; - else if (!(func->decoration & 1)) - api_fatal ("could not load %W, %E", dll_path); - else - dll->handle = INVALID_HANDLE_VALUE; + 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); fesetenv (&fpuenv); } - /* Set "arguments for dll_chain. */ + /* Set "arguments" for dll_chain. */ ret.low = (long) dll->init; ret.high = (long) func; |