mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 04:03:04 +01:00
Port from CVS Vlad's fixes for CORE-3015, CORE-3016 and CORE-3017
This commit is contained in:
parent
8d8413da02
commit
3940feef1f
@ -96,6 +96,9 @@ DatabaseSnapshot::SharedData::~SharedData()
|
||||
{ // scope
|
||||
DumpGuard guard(this);
|
||||
cleanup();
|
||||
|
||||
if (base->used == sizeof(Header))
|
||||
ISC_remove_map_file(&handle);
|
||||
}
|
||||
|
||||
#ifdef WIN_NT
|
||||
|
@ -276,6 +276,9 @@ int CCH_down_grade_dbb(void* ast_object)
|
||||
{
|
||||
Database::SyncGuard dsGuard(dbb, true);
|
||||
|
||||
if (dbb->dbb_flags & DBB_not_in_use)
|
||||
return 0;
|
||||
|
||||
Lock* const lock = dbb->dbb_lock;
|
||||
|
||||
// Since this routine will be called asynchronously,
|
||||
|
@ -105,6 +105,7 @@ struct sh_mem
|
||||
UCHAR *sh_mem_address;
|
||||
ULONG sh_mem_length_mapped;
|
||||
SLONG sh_mem_handle;
|
||||
TEXT sh_mem_name[MAXPATHLEN];
|
||||
};
|
||||
|
||||
#endif // UNIX
|
||||
|
@ -72,5 +72,6 @@ UCHAR* ISC_remap_file(Firebird::Arg::StatusVector&, struct sh_mem*, ULONG, bool)
|
||||
void ISC_unmap_file(Firebird::Arg::StatusVector&, struct sh_mem*);
|
||||
|
||||
void ISC_remove_map_file(const TEXT* filename);
|
||||
void ISC_remove_map_file(const struct sh_mem*);
|
||||
|
||||
#endif // JRD_ISC_S_PROTO_H
|
||||
|
@ -1678,12 +1678,19 @@ ULONG ISC_exception_post(ULONG except_code, const TEXT* err_msg)
|
||||
|
||||
void ISC_remove_map_file(const TEXT* filename)
|
||||
{
|
||||
#ifndef WIN_NT
|
||||
TEXT expanded_filename[MAXPATHLEN];
|
||||
gds__prefix_lock(expanded_filename, filename);
|
||||
|
||||
// We can't do much (specially in dtors) when it fails
|
||||
// therefore do not check for errors - at least it's just /tmp.
|
||||
unlink(expanded_filename);
|
||||
#endif // WIN_NT
|
||||
}
|
||||
|
||||
void ISC_remove_map_file(const struct sh_mem* shmem_data)
|
||||
{
|
||||
ISC_remove_map_file(shmem_data->sh_mem_name);
|
||||
}
|
||||
|
||||
#ifdef UNIX
|
||||
@ -1821,6 +1828,7 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
shmem_data->sh_mem_address = address;
|
||||
shmem_data->sh_mem_length_mapped = length;
|
||||
shmem_data->sh_mem_handle = fd;
|
||||
strcpy(shmem_data->sh_mem_name, filename);
|
||||
|
||||
#ifdef USE_SYS5SEMAPHORE
|
||||
// register mapped file
|
||||
@ -1923,18 +1931,21 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
* routine (if given) or punt (leaving the file unmapped).
|
||||
*
|
||||
**************************************/
|
||||
HANDLE file_handle, event_handle;
|
||||
HANDLE file_handle;
|
||||
HANDLE event_handle = 0;
|
||||
int retry_count = 0;
|
||||
|
||||
TEXT expanded_filename[MAXPATHLEN];
|
||||
gds__prefix_lock(expanded_filename, filename);
|
||||
|
||||
const bool trunc_flag = (length != 0);
|
||||
bool init_flag = false;
|
||||
|
||||
// retry to attach to mmapped file if the process initializing dies during initialization.
|
||||
|
||||
retry:
|
||||
retry_count++;
|
||||
if (retry_count++ > 0)
|
||||
THREAD_SLEEP(10);
|
||||
|
||||
file_handle = CreateFile(expanded_filename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
@ -1943,15 +1954,19 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
DWORD err = GetLastError();
|
||||
if (file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (err == ERROR_SHARING_VIOLATION)
|
||||
goto retry;
|
||||
|
||||
error(statusVector, "CreateFile", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if file already exists
|
||||
|
||||
const bool file_exists = (GetLastError() == ERROR_ALREADY_EXISTS);
|
||||
const bool file_exists = (err == ERROR_ALREADY_EXISTS);
|
||||
|
||||
// Create an event that can be used to determine if someone has already
|
||||
// initialized shared memory.
|
||||
@ -1964,22 +1979,25 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event_handle = CreateEvent(ISC_get_security_desc(), TRUE, FALSE, object_name);
|
||||
if (!event_handle)
|
||||
if (!init_flag)
|
||||
{
|
||||
error(statusVector, "CreateEvent", GetLastError());
|
||||
CloseHandle(file_handle);
|
||||
return NULL;
|
||||
}
|
||||
event_handle = CreateEvent(ISC_get_security_desc(), TRUE, FALSE, object_name);
|
||||
if (!event_handle)
|
||||
{
|
||||
error(statusVector, "CreateEvent", GetLastError());
|
||||
CloseHandle(file_handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const bool init_flag = (GetLastError() != ERROR_ALREADY_EXISTS);
|
||||
init_flag = (GetLastError() != ERROR_ALREADY_EXISTS);
|
||||
|
||||
if (init_flag && !init_routine)
|
||||
{
|
||||
CloseHandle(event_handle);
|
||||
CloseHandle(file_handle);
|
||||
statusVector << Arg::Gds(isc_unavailable);
|
||||
return NULL;
|
||||
if (init_flag && !init_routine)
|
||||
{
|
||||
CloseHandle(event_handle);
|
||||
CloseHandle(file_handle);
|
||||
statusVector << Arg::Gds(isc_unavailable);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
@ -2016,7 +2034,7 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
CloseHandle(event_handle);
|
||||
if (retry_count > 10)
|
||||
{
|
||||
error(statusVector, "WaitForSingleObject", GetLastError());
|
||||
error(statusVector, "WaitForSingleObject", 0);
|
||||
return NULL;
|
||||
}
|
||||
goto retry;
|
||||
@ -2040,6 +2058,14 @@ UCHAR* ISC_map_file(Arg::StatusVector& statusVector,
|
||||
{
|
||||
const DWORD err = GetLastError();
|
||||
|
||||
if ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_FILE_NOT_FOUND && fdw_create == TRUNCATE_EXISTING))
|
||||
{
|
||||
if (!init_flag) {
|
||||
CloseHandle(event_handle);
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (err == ERROR_USER_MAPPED_FILE && init_flag && file_exists && trunc_flag)
|
||||
statusVector << Arg::Gds(isc_instance_conflict);
|
||||
else
|
||||
@ -3388,11 +3414,18 @@ void ISC_unmap_file(Arg::StatusVector& statusVector, sh_mem* shmem_data)
|
||||
|
||||
TEXT expanded_filename[MAXPATHLEN];
|
||||
gds__prefix_lock(expanded_filename, shmem_data->sh_mem_name);
|
||||
if (!DeleteFile(expanded_filename))
|
||||
{
|
||||
error(statusVector, "DeleteFile", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete file only if it is not used by anyone else
|
||||
HANDLE hFile = CreateFile(expanded_filename,
|
||||
DELETE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL);
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -137,6 +137,8 @@ ConfigStorage::~ConfigStorage()
|
||||
{
|
||||
unlink(m_base->cfg_file_name);
|
||||
memset(m_base->cfg_file_name, 0, sizeof(m_base->cfg_file_name));
|
||||
|
||||
ISC_remove_map_file(&m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user