Skip to content

Commit dd71073

Browse files
committed
Fixed bug #7896 : replication.log remains empty (and without any error in firebird.log)
1 parent e2999cd commit dd71073

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) == 0;
134146
#else
135-
if (os_utils::lockf(fileno(file), F_LOCK, 0))
147+
os_utils::lockf(fileno(file), F_LOCK, 0) == 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
@@ -969,7 +969,7 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
969969
}
970970

971971
if (!found) {
972-
sprintf(s, "unknown ISC error %ld", code); // TXNN
972+
sprintf(s, "unknown ISC error %ld", (SLONG) code); // TXNN
973973
}
974974
}
975975
}
@@ -994,11 +994,11 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
994994
break;
995995

996996
case isc_arg_dos:
997-
sprintf(s, "unknown dos error %ld", code); // TXNN
997+
sprintf(s, "unknown dos error %ld", (SLONG) code); // TXNN
998998
break;
999999

10001000
case isc_arg_next_mach:
1001-
sprintf(s, "next/mach error %ld", code); // AP
1001+
sprintf(s, "next/mach error %ld", (SLONG) code); // AP
10021002
break;
10031003

10041004
case isc_arg_win32:
@@ -1010,7 +1010,7 @@ static SLONG safe_interpret(char* const s, const FB_SIZE_T bufsize,
10101010
s, bufsize, NULL))
10111011
#endif
10121012
{
1013-
sprintf(s, "unknown Win32 error %ld", code); // TXNN
1013+
sprintf(s, "unknown Win32 error %ld", (SLONG) code); // TXNN
10141014
}
10151015
break;
10161016

@@ -1078,80 +1078,122 @@ const int SECS_PER_HOUR = 60 * 60;
10781078
const int SECS_PER_DAY = SECS_PER_HOUR * 24;
10791079

10801080
#ifdef WIN_NT
1081-
class CleanupTraceHandles
1081+
1082+
namespace {
1083+
1084+
class LogFileHandles
10821085
{
10831086
public:
1084-
~CleanupTraceHandles()
1087+
LogFileHandles(Firebird::MemoryPool&)
1088+
{
1089+
mutex_handle = CreateMutex(ISC_get_security_desc(), FALSE, "firebird_trace_mutex");
1090+
}
1091+
1092+
~LogFileHandles()
10851093
{
1086-
CloseHandle(trace_mutex_handle);
1087-
trace_mutex_handle = INVALID_HANDLE_VALUE;
1094+
if (mutex_handle != INVALID_HANDLE_VALUE)
1095+
CloseHandle(mutex_handle);
10881096

1089-
if (trace_file_handle != INVALID_HANDLE_VALUE)
1090-
CloseHandle(trace_file_handle);
1097+
mutex_handle = INVALID_HANDLE_VALUE;
10911098

1092-
trace_file_handle = INVALID_HANDLE_VALUE;
1099+
if (file_handle != INVALID_HANDLE_VALUE)
1100+
CloseHandle(file_handle);
1101+
1102+
file_handle = INVALID_HANDLE_VALUE;
10931103
}
10941104

1105+
void trace_raw(const char* text, unsigned int length);
1106+
1107+
private:
10951108
// This is machine-global. Can be made instance-global.
10961109
// For as long you don't trace two instances in parallel this shouldn't matter.
1097-
static HANDLE trace_mutex_handle;
1098-
static HANDLE trace_file_handle;
1099-
};
1100-
1101-
HANDLE CleanupTraceHandles::trace_mutex_handle = CreateMutex(NULL, FALSE, "firebird_trace_mutex");
1102-
HANDLE CleanupTraceHandles::trace_file_handle = INVALID_HANDLE_VALUE;
1110+
static HANDLE mutex_handle;
1111+
static HANDLE file_handle;
11031112

1104-
CleanupTraceHandles cleanupHandles;
1105-
1106-
#endif
1113+
friend class LogGuard;
1114+
};
11071115

1108-
void API_ROUTINE gds__trace_raw(const char* text, unsigned int length)
1116+
void LogFileHandles::trace_raw(const char* text, unsigned int length)
11091117
{
1110-
/**************************************
1111-
*
1112-
* g d s _ t r a c e _ r a w
1113-
*
1114-
**************************************
1115-
*
1116-
* Functional description
1117-
* Write trace event to a log file
1118-
*
1119-
**************************************/
1120-
if (!length)
1121-
length = static_cast<unsigned>(strlen(text));
1122-
#ifdef WIN_NT
1123-
// Note: thread-safe code
1124-
11251118
// Nickolay Samofatov, 12 Sept 2003. Windows opens files extremely slowly.
11261119
// Slowly enough to make such trace useless. Thus we cache file handle !
1127-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1120+
11281121
while (true)
11291122
{
1130-
if (CleanupTraceHandles::trace_file_handle == INVALID_HANDLE_VALUE)
1123+
if (file_handle == INVALID_HANDLE_VALUE)
11311124
{
11321125
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
1126+
11331127
// We do not care to close this file.
11341128
// It will be closed automatically when our process terminates.
1135-
CleanupTraceHandles::trace_file_handle = CreateFile(name.c_str(), GENERIC_WRITE,
1129+
file_handle = CreateFile(name.c_str(), GENERIC_WRITE,
11361130
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
11371131
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1138-
if (CleanupTraceHandles::trace_file_handle == INVALID_HANDLE_VALUE)
1132+
1133+
if (file_handle == INVALID_HANDLE_VALUE)
11391134
break;
11401135
}
1136+
1137+
SetFilePointer(file_handle, 0, NULL, FILE_END);
1138+
11411139
DWORD bytesWritten;
1142-
SetFilePointer(CleanupTraceHandles::trace_file_handle, 0, NULL, FILE_END);
1143-
WriteFile(CleanupTraceHandles::trace_file_handle, text, length, &bytesWritten, NULL);
1140+
WriteFile(file_handle, text, length, &bytesWritten, NULL);
1141+
11441142
if (bytesWritten != length)
11451143
{
11461144
// Handle the case when file was deleted by another process on Win9x
11471145
// On WinNT we are not going to notice that fact :(
1148-
CloseHandle(CleanupTraceHandles::trace_file_handle);
1149-
CleanupTraceHandles::trace_file_handle = INVALID_HANDLE_VALUE;
1146+
CloseHandle(file_handle);
1147+
file_handle = INVALID_HANDLE_VALUE;
11501148
continue;
11511149
}
11521150
break;
11531151
}
1154-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
1152+
}
1153+
1154+
Firebird::InitInstance<LogFileHandles> logFileHandles;
1155+
1156+
HANDLE LogFileHandles::mutex_handle = INVALID_HANDLE_VALUE;
1157+
HANDLE LogFileHandles::file_handle = INVALID_HANDLE_VALUE;
1158+
1159+
1160+
class LogGuard
1161+
{
1162+
public:
1163+
LogGuard()
1164+
{
1165+
WaitForSingleObject(logFileHandles().mutex_handle, INFINITE);
1166+
}
1167+
1168+
~LogGuard()
1169+
{
1170+
ReleaseMutex(logFileHandles().mutex_handle);
1171+
}
1172+
};
1173+
1174+
} // namespace
1175+
1176+
#endif
1177+
1178+
void API_ROUTINE gds__trace_raw(const char* text, unsigned int length)
1179+
{
1180+
/**************************************
1181+
*
1182+
* g d s _ t r a c e _ r a w
1183+
*
1184+
**************************************
1185+
*
1186+
* Functional description
1187+
* Write trace event to a log file
1188+
*
1189+
**************************************/
1190+
if (!length)
1191+
length = static_cast<unsigned>(strlen(text));
1192+
#ifdef WIN_NT
1193+
// Note: thread-safe code
1194+
1195+
LogGuard guard;
1196+
logFileHandles().trace_raw(text, length);
11551197
#else
11561198
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
11571199
int file = os_utils::open(name.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0660);
@@ -1285,7 +1327,7 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
12851327
Firebird::PathName name = fb_utils::getPrefix(Firebird::IConfigManager::DIR_LOG, LOGFILE);
12861328

12871329
#ifdef WIN_NT
1288-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1330+
LogGuard guard;
12891331
#endif
12901332

12911333
FILE* file = os_utils::fopen(name.c_str(), "a");
@@ -1323,8 +1365,6 @@ void API_ROUTINE gds__log(const TEXT* text, ...)
13231365
va_start(ptr, text);
13241366
__android_log_vprint(ANDROID_LOG_INFO, "FIREBIRD", text, ptr);
13251367
va_end(ptr);
1326-
#elif defined(WIN_NT)
1327-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
13281368
#endif
13291369
}
13301370

@@ -1357,7 +1397,7 @@ void gds__print_pool(MemoryPool* pool, const TEXT* text, ...)
13571397

13581398
const int oldmask = umask(0111);
13591399
#ifdef WIN_NT
1360-
WaitForSingleObject(CleanupTraceHandles::trace_mutex_handle, INFINITE);
1400+
LogGuard guard;
13611401
#endif
13621402
FILE* file = os_utils::fopen(name.c_str(), "a");
13631403
if (file != NULL)
@@ -1372,9 +1412,6 @@ void gds__print_pool(MemoryPool* pool, const TEXT* text, ...)
13721412
fprintf(file, "\n");
13731413
fclose(file);
13741414
}
1375-
#ifdef WIN_NT
1376-
ReleaseMutex(CleanupTraceHandles::trace_mutex_handle);
1377-
#endif
13781415

13791416
umask(oldmask);
13801417

0 commit comments

Comments
 (0)