Skip to content

Commit fb93439

Browse files
authored
Merge pull request #7919 from FirebirdSQL/work/gh_7896
Fixed bug #7896 : replication.log remains empty (and without any error in firebird.log)
2 parents 6a06fe5 + 0a5a4f3 commit fb93439

File tree

3 files changed

+115
-61
lines changed

3 files changed

+115
-61
lines changed

src/jrd/replication/Utils.cpp

+25-8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
#include <stdlib.h>
5151
#include <time.h>
52+
#include <atomic>
5253

5354
using namespace Firebird;
5455
using namespace Replication;
@@ -80,15 +81,17 @@ namespace
8081
char host[BUFFER_LARGE];
8182
ISC_get_host(host, sizeof(host));
8283
m_hostname = host;
84+
m_error = false;
8385
#ifdef WIN_NT
84-
m_mutex = CreateMutex(NULL, FALSE, "firebird_repl_mutex");
86+
m_mutex = CreateMutex(ISC_get_security_desc(), FALSE, "firebird_repl_mutex");
8587
#endif
8688
}
8789

8890
~LogWriter()
8991
{
9092
#ifdef WIN_NT
91-
CloseHandle(m_mutex);
93+
if (m_mutex != INVALID_HANDLE_VALUE)
94+
CloseHandle(m_mutex);
9295
#endif
9396
}
9497

@@ -107,6 +110,9 @@ namespace
107110
return;
108111
}
109112

113+
if (m_error)
114+
m_error = false;
115+
110116
string dbname, text;
111117

112118
if (database.hasData())
@@ -121,25 +127,34 @@ namespace
121127
fclose(file);
122128
unlock();
123129
}
130+
else if (!m_error && !m_error.exchange(true))
131+
{
132+
gds__log("Failed to open log file \'%s\', errno %d",
133+
m_filename.c_str(), errno);
134+
}
124135
}
125136

126137
private:
127138
bool lock(FILE* file)
128139
{
140+
const bool ret =
129141
#ifdef WIN_NT
130-
return (WaitForSingleObject(m_mutex, INFINITE) == WAIT_OBJECT_0);
142+
(WaitForSingleObject(m_mutex, INFINITE) == WAIT_OBJECT_0);
131143
#else
132144
#ifdef HAVE_FLOCK
133-
if (flock(fileno(file), LOCK_EX))
145+
flock(fileno(file), LOCK_EX);
134146
#else
135-
if (os_utils::lockf(fileno(file), F_LOCK, 0))
147+
os_utils::lockf(fileno(file), F_LOCK, 0);
136148
#endif
149+
#endif
150+
151+
if (!ret && !m_error && !m_error.exchange(true))
137152
{
138-
return false;
153+
gds__log("Failed to lock log file \'%s\', error %d",
154+
m_filename.c_str(), ERRNO);
139155
}
140156

141-
return true;
142-
#endif
157+
return ret;
143158
}
144159

145160
void unlock()
@@ -154,6 +169,8 @@ namespace
154169
#ifdef WIN_NT
155170
HANDLE m_mutex;
156171
#endif
172+
// used to not pollute firebird.log with too many messages
173+
std::atomic_bool m_error;
157174
};
158175

159176
void logMessage(LogMsgSide side, LogMsgType type,

src/remote/server/ReplServer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ namespace
162162
#ifdef WIN_NT
163163
string name;
164164
name.printf("firebird_replctl_%s", guidStr);
165-
m_mutex = CreateMutex(NULL, FALSE, name.c_str());
165+
m_mutex = CreateMutex(ISC_get_security_desc(), FALSE, name.c_str());
166166
if (WaitForSingleObject(m_mutex, INFINITE) != WAIT_OBJECT_0)
167167
#else // POSIX
168168
#ifdef HAVE_FLOCK

src/yvalve/gds.cpp

+89-52
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
974974
}
975975

976976
if (!found) {
977-
sprintf(s, "unknown ISC error %ld", code); // TXNN
977+
sprintf(s, "unknown ISC error %ld", (SLONG) code); // TXNN
978978
}
979979
}
980980
}
@@ -999,11 +999,11 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
999999
break;
10001000

10011001
case isc_arg_dos:
1002-
sprintf(s, "unknown dos error %ld", code); // TXNN
1002+
sprintf(s, "unknown dos error %ld", (SLONG) code); // TXNN
10031003
break;
10041004

10051005
case isc_arg_next_mach:
1006-
sprintf(s, "next/mach error %ld", code); // AP
1006+
sprintf(s, "next/mach error %ld", (SLONG) code); // AP
10071007
break;
10081008

10091009
case isc_arg_win32:
@@ -1015,7 +1015,7 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
10151015
s, bufsize, NULL))
10161016
#endif
10171017
{
1018-
sprintf(s, "unknown Win32 error %ld", code); // TXNN
1018+
sprintf(s, "unknown Win32 error %ld", (SLONG) code); // TXNN
10191019
}
10201020
break;
10211021

@@ -1083,80 +1083,122 @@ const int SECS_PER_HOUR = 60 * 60;
10831083
const int SECS_PER_DAY = SECS_PER_HOUR * 24;
10841084

10851085
#ifdef WIN_NT
1086-
class CleanupTraceHandles
1086+
1087+
namespace {
1088+
1089+
class LogFileHandles
10871090
{
10881091
public:
1089-
~CleanupTraceHandles()
1092+
LogFileHandles(Firebird::MemoryPool&)
1093+
{
1094+
mutex_handle = CreateMutex(ISC_get_security_desc(), FALSE, "firebird_trace_mutex");
1095+
}
1096+
1097+
~LogFileHandles()
10901098
{
1091-
CloseHandle(trace_mutex_handle);
1092-
trace_mutex_handle = INVALID_HANDLE_VALUE;
1099+
if (mutex_handle != INVALID_HANDLE_VALUE)
1100+
CloseHandle(mutex_handle);
10931101

1094-
if (trace_file_handle != INVALID_HANDLE_VALUE)
1095-
CloseHandle(trace_file_handle);
1102+
mutex_handle = INVALID_HANDLE_VALUE;
10961103

1097-
trace_file_handle = INVALID_HANDLE_VALUE;
1104+
if (file_handle != INVALID_HANDLE_VALUE)
1105+
CloseHandle(file_handle);
1106+
1107+
file_handle = INVALID_HANDLE_VALUE;
10981108
}
10991109

1110+
void trace_raw(const char* text, unsigned int length);
1111+
1112+
private:
11001113
// This is machine-global. Can be made instance-global.
11011114
// For as long you don't trace two instances in parallel this shouldn't matter.
1102-
static HANDLE trace_mutex_handle;
1103-
static HANDLE trace_file_handle;
1104-
};
1105-
1106-
HANDLE CleanupTraceHandles::trace_mutex_handle = CreateMutex(NULL, FALSE, "firebird_trace_mutex");
1107-
HANDLE CleanupTraceHandles::trace_file_handle = INVALID_HANDLE_VALUE;
1115+
static HANDLE mutex_handle;
1116+
static HANDLE file_handle;
11081117

1109-
CleanupTraceHandles cleanupHandles;
1110-
1111-
#endif
1118+
friend class LogGuard;
1119+
};
11121120

1113-
void API_ROUTINE gds__trace_raw(const char* text, unsigned int length)
1121+
void LogFileHandles::trace_raw(const char* text, unsigned int length)
11141122
{
1115-
/**************************************
1116-
*
1117-
* g d s _ t r a c e _ r a w
1118-
*
1119-
**************************************
1120-
*
1121-
* Functional description
1122-
* Write trace event to a log file
1123-
*
1124-
**************************************/
1125-
if (!length)
1126-
length = static_cast<unsigned>(strlen(text));
1127-
#ifdef WIN_NT
1128-
// Note: thread-safe code
1129-
11301123
// Nickolay Samofatov, 12 Sept 2003. Windows opens files extremely slowly.
11311124
// Slowly enough to make such trace useless. Thus we cache file handle !
1132-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1125+
11331126
while (true)
11341127
{
1135-
if (CleanupTraceHandles::trace_file_handle == INVALID_HANDLE_VALUE)
1128+
if (file_handle == INVALID_HANDLE_VALUE)
11361129
{
11371130
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
1131+
11381132
// We do not care to close this file.
11391133
// It will be closed automatically when our process terminates.
1140-
CleanupTraceHandles::trace_file_handle = CreateFile(name.c_str(), GENERIC_WRITE,
1134+
file_handle = CreateFile(name.c_str(), GENERIC_WRITE,
11411135
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
11421136
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1143-
if (CleanupTraceHandles::trace_file_handle == INVALID_HANDLE_VALUE)
1137+
1138+
if (file_handle == INVALID_HANDLE_VALUE)
11441139
break;
11451140
}
1141+
1142+
SetFilePointer(file_handle, 0, NULL, FILE_END);
1143+
11461144
DWORD bytesWritten;
1147-
SetFilePointer(CleanupTraceHandles::trace_file_handle, 0, NULL, FILE_END);
1148-
WriteFile(CleanupTraceHandles::trace_file_handle, text, length, &bytesWritten, NULL);
1145+
WriteFile(file_handle, text, length, &bytesWritten, NULL);
1146+
11491147
if (bytesWritten != length)
11501148
{
11511149
// Handle the case when file was deleted by another process on Win9x
11521150
// On WinNT we are not going to notice that fact :(
1153-
CloseHandle(CleanupTraceHandles::trace_file_handle);
1154-
CleanupTraceHandles::trace_file_handle = INVALID_HANDLE_VALUE;
1151+
CloseHandle(file_handle);
1152+
file_handle = INVALID_HANDLE_VALUE;
11551153
continue;
11561154
}
11571155
break;
11581156
}
1159-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
1157+
}
1158+
1159+
Firebird::InitInstance<LogFileHandles> logFileHandles;
1160+
1161+
HANDLE LogFileHandles::mutex_handle = INVALID_HANDLE_VALUE;
1162+
HANDLE LogFileHandles::file_handle = INVALID_HANDLE_VALUE;
1163+
1164+
1165+
class LogGuard
1166+
{
1167+
public:
1168+
LogGuard()
1169+
{
1170+
WaitForSingleObject(logFileHandles().mutex_handle, INFINITE);
1171+
}
1172+
1173+
~LogGuard()
1174+
{
1175+
ReleaseMutex(logFileHandles().mutex_handle);
1176+
}
1177+
};
1178+
1179+
} // namespace
1180+
1181+
#endif
1182+
1183+
void API_ROUTINE gds__trace_raw(const char* text, unsigned int length)
1184+
{
1185+
/**************************************
1186+
*
1187+
* g d s _ t r a c e _ r a w
1188+
*
1189+
**************************************
1190+
*
1191+
* Functional description
1192+
* Write trace event to a log file
1193+
*
1194+
**************************************/
1195+
if (!length)
1196+
length = static_cast<unsigned>(strlen(text));
1197+
#ifdef WIN_NT
1198+
// Note: thread-safe code
1199+
1200+
LogGuard guard;
1201+
logFileHandles().trace_raw(text, length);
11601202
#else
11611203
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
11621204
int file = os_utils::open(name.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0660);
@@ -1290,7 +1332,7 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
12901332
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
12911333

12921334
#ifdef WIN_NT
1293-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1335+
LogGuard guard;
12941336
#endif
12951337

12961338
FILE* file = os_utils::fopen(name.c_str(), "a");
@@ -1328,8 +1370,6 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
13281370
va_start(ptr, text);
13291371
__android_log_vprint(ANDROID_LOG_INFO, "FIREBIRD", text, ptr);
13301372
va_end(ptr);
1331-
#elif defined(WIN_NT)
1332-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
13331373
#endif
13341374
}
13351375

@@ -1362,7 +1402,7 @@ void gds__print_pool(MemoryPool* pool, const TEXT* text, ...)
13621402

13631403
const int oldmask = umask(0111);
13641404
#ifdef WIN_NT
1365-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1405+
LogGuard guard;
13661406
#endif
13671407
FILE* file = os_utils::fopen(name.c_str(), "a");
13681408
if (file != NULL)
@@ -1377,9 +1417,6 @@ void gds__print_pool(MemoryPool* pool, const TEXT* text, ...)
13771417
fprintf(file, "\n");
13781418
fclose(file);
13791419
}
1380-
#ifdef WIN_NT
1381-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
1382-
#endif
13831420

13841421
umask(oldmask);
13851422

0 commit comments

Comments
 (0)