8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Fixed bug #6949 : On windows, engine may hung on initialization when another instance with different lock directory is running.

WIP
This commit is contained in:
Vlad Khorsun 2021-09-07 12:52:43 +03:00
parent 31103de33d
commit b59435e3d6
4 changed files with 77 additions and 3 deletions

View File

@ -33,6 +33,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Bscmake>
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>

View File

@ -33,6 +33,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Bscmake>
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>

View File

@ -33,6 +33,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Bscmake>
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>

View File

@ -132,6 +132,7 @@ static size_t getpagesize()
#include <process.h>
#include <windows.h>
#include <psapi.h>
#endif
@ -1460,8 +1461,46 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
#endif // UNIX
#ifdef WIN_NT
// Get name of the file that was mapped into memory at given address.
// This routine should not throw as caller is not ready currently.
static bool getMappedFileName(void* addr, PathName& mappedName)
{
char* mapName = mappedName.getBuffer(MAXPATHLEN + 1);
const DWORD mapLen = GetMappedFileName(GetCurrentProcess(), addr, mapName, MAXPATHLEN);
mappedName.resize(mapLen);
if (!mapLen)
//system_call_failed::raise("GetMappedFileName");
return false;
char dosDevice[] = {'A', ':', 0};
DWORD drives = GetLogicalDrives();
for (; drives; drives >>= 1, dosDevice[0]++)
if (drives & 1)
{
char ntDevice[MAXPATHLEN + 1];
DWORD ntLen = QueryDosDevice(dosDevice, ntDevice, MAXPATHLEN);
if (!ntLen)
//system_call_failed::raise("QueryDosDevice");
return false;
ntLen = strlen(ntDevice);
if (ntLen <= mapLen &&
_memicmp(ntDevice, mapName, ntLen) == 0 &&
mapName[ntLen] == '\\')
{
mappedName.replace(0, ntLen, dosDevice);
return true;
}
}
return false;
}
SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject* cb)
: sh_mem_mutex(0), sh_mem_length_mapped(0),
sh_mem_handle(0), sh_mem_object(0), sh_mem_interest(0), sh_mem_hdr_object(0),
@ -1632,16 +1671,29 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
system_call_failed::raise("SetFilePointer", err);
}
}
/*
else
{
if ((err != ERROR_ALREADY_EXISTS) || SetFilePointer(file_handle, 0, NULL, FILE_END) == 0)
{
CloseHandle(event_handle);
CloseHandle(file_handle);
goto retry;
// We are not initializer but file is created by us.
//if (err == NO_ERROR)
// DeleteFile(expanded_filename);
if (retry_count < 100) // 1 sec
goto retry;
if (err == ERROR_ALREADY_EXISTS)
(Arg::Gds(isc_random) << Arg::Str("File for memory mapping is empty.")).raise();
// unexpected error
system_call_failed::raise("CreateFile", err);
}
}
*/
// Create a file mapping object that will be used to make remapping possible.
// The current length of real mapped file and its name are saved in it.
@ -1755,6 +1807,25 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
system_call_failed::raise("MapViewOfFile", err);
}
PathName mappedName;
if (!getMappedFileName(address, mappedName) || mappedName != expanded_filename)
{
UnmapViewOfFile(address);
CloseHandle(file_obj);
UnmapViewOfFile(header_address);
CloseHandle(header_obj);
CloseHandle(event_handle);
CloseHandle(file_handle);
gds__log("Wrong file for memory mapping:\n"
"\t expected %s\n"
"\talready mapped %s\n"
"\tCheck for presence of another Firebird instance with different lock directory",
expanded_filename, mappedName.c_str());
(Arg::Gds(isc_random) << Arg::Str("Wrong file for memory mapping, see details in firebird.log")).raise();
}
sh_mem_header = (MemoryHeader*) address;
sh_mem_length_mapped = length;
sh_mem_handle = file_handle;