diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index 99051f02c8c7c4dc6162bfff2ea1a54978e834ed..7122c4abe000368b7827c2fa963d068eba9f4db0 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -671,6 +671,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, { DWORD size_high; DWORD size_low; + DWORD errcode; /* Shifts >= the width of the type are undefined. */ #ifdef _WIN64 @@ -686,27 +687,31 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, size_high, /* Upper 32 bits of size */ size_low, /* Lower 32 bits of size */ name); + + errcode = GetLastError(); + if (errcode == ERROR_ALREADY_EXISTS || errcode == ERROR_ACCESS_DENIED) + { + /* + * On Windows, when the segment already exists, a handle for the + * existing segment is returned. We must close it before + * returning. However, if the existing segment is created by a + * service, then it returns ERROR_ACCESS_DENIED. We don't do + * _dosmaperr here, so errno won't be modified. + */ + if (hmap) + CloseHandle(hmap); + return false; + } + if (!hmap) { - _dosmaperr(GetLastError()); + _dosmaperr(errcode); ereport(elevel, (errcode_for_dynamic_shared_memory(), errmsg("could not create shared memory segment \"%s\": %m", name))); return false; } - _dosmaperr(GetLastError()); - if (errno == EEXIST) - { - /* - * On Windows, when the segment already exists, a handle for the - * existing segment is returned. We must close it before - * returning. We don't do _dosmaperr here, so errno won't be - * modified. - */ - CloseHandle(hmap); - return false; - } } else {