mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +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:
parent
31103de33d
commit
b59435e3d6
@ -33,6 +33,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||||
|
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Bscmake>
|
<Bscmake>
|
||||||
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||||
|
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Bscmake>
|
<Bscmake>
|
||||||
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||||
|
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<Bscmake>
|
<Bscmake>
|
||||||
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
<OutputFile>$(IntDir)$(TargetName).bsc</OutputFile>
|
||||||
|
@ -132,6 +132,7 @@ static size_t getpagesize()
|
|||||||
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <psapi.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1460,8 +1461,46 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
|
|||||||
|
|
||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#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)
|
SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject* cb)
|
||||||
: sh_mem_mutex(0), sh_mem_length_mapped(0),
|
: 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),
|
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);
|
system_call_failed::raise("SetFilePointer", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((err != ERROR_ALREADY_EXISTS) || SetFilePointer(file_handle, 0, NULL, FILE_END) == 0)
|
if ((err != ERROR_ALREADY_EXISTS) || SetFilePointer(file_handle, 0, NULL, FILE_END) == 0)
|
||||||
{
|
{
|
||||||
CloseHandle(event_handle);
|
CloseHandle(event_handle);
|
||||||
CloseHandle(file_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.
|
// 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.
|
// 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);
|
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_header = (MemoryHeader*) address;
|
||||||
sh_mem_length_mapped = length;
|
sh_mem_length_mapped = length;
|
||||||
sh_mem_handle = file_handle;
|
sh_mem_handle = file_handle;
|
||||||
|
Loading…
Reference in New Issue
Block a user