mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
Logs: remove mem-mapped buffer and move instance lock to main.cpp
Part of the work to untangle utilities from RPCS3-specific things.
This commit is contained in:
parent
1669e95870
commit
2209be5216
4 changed files with 54 additions and 82 deletions
|
@ -1147,7 +1147,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode & fs::trunc && mode & (fs::lock + fs::unread))
|
if (mode & fs::trunc && mode & (fs::lock + fs::unread) && mode & fs::write)
|
||||||
{
|
{
|
||||||
// Postpone truncation in order to avoid using O_TRUNC on a locked file
|
// Postpone truncation in order to avoid using O_TRUNC on a locked file
|
||||||
verify(HERE), ::ftruncate(fd, 0) == 0;
|
verify(HERE), ::ftruncate(fd, 0) == 0;
|
||||||
|
|
|
@ -62,17 +62,13 @@ namespace logs
|
||||||
|
|
||||||
class file_writer
|
class file_writer
|
||||||
{
|
{
|
||||||
fs::file m_file;
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::thread m_writer;
|
std::thread m_writer;
|
||||||
fs::file m_fout;
|
fs::file m_fout;
|
||||||
fs::file m_fout2;
|
fs::file m_fout2;
|
||||||
u64 m_max_size;
|
u64 m_max_size;
|
||||||
|
|
||||||
#ifdef _WIN32
|
std::unique_ptr<uchar[]> m_fptr;
|
||||||
::HANDLE m_fmap;
|
|
||||||
#endif
|
|
||||||
uchar* m_fptr{};
|
|
||||||
z_stream m_zs{};
|
z_stream m_zs{};
|
||||||
shared_mutex m_m;
|
shared_mutex m_m;
|
||||||
|
|
||||||
|
@ -345,61 +341,9 @@ logs::file_writer::file_writer(const std::string& name)
|
||||||
: m_name(name)
|
: m_name(name)
|
||||||
{
|
{
|
||||||
const std::string log_name = fs::get_cache_dir() + name + ".log";
|
const std::string log_name = fs::get_cache_dir() + name + ".log";
|
||||||
const std::string buf_name = fs::get_cache_dir() + name + ".buf";
|
|
||||||
|
|
||||||
const std::string s_filelock = fs::get_cache_dir() + ".restart_lock";
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!m_file.open(buf_name, fs::read + fs::rewrite + fs::lock))
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
auto prev_error = fs::g_tls_error;
|
|
||||||
|
|
||||||
if (fs::exists(s_filelock))
|
|
||||||
{
|
|
||||||
// A restart is happening, wait for the file to be accessible
|
|
||||||
u32 tries = 0;
|
|
||||||
while (!m_file.open(buf_name, fs::read + fs::rewrite + fs::lock) && tries < 100)
|
|
||||||
{
|
|
||||||
std::this_thread::sleep_for(100ms);
|
|
||||||
tries++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fs::g_tls_error = prev_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_file)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (fs::g_tls_error == fs::error::acces)
|
|
||||||
{
|
|
||||||
if (fs::exists(buf_name))
|
|
||||||
{
|
|
||||||
fmt::throw_exception("Another instance of %s is running. Close it or kill its process, if necessary.", name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fmt::throw_exception("Cannot create %s.log (access denied)."
|
|
||||||
#ifdef _WIN32
|
|
||||||
"\nNote that %s cannot be installed in Program Files or similar directory with limited permissions."
|
|
||||||
#else
|
|
||||||
"\nPlease, check %s permissions in '~/.config/'."
|
|
||||||
#endif
|
|
||||||
, name, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt::throw_exception("Cannot create %s.log (error %s)", name, fs::g_tls_error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
fs::remove_file(s_filelock); // remove restart token if it exists
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check free space
|
// Check free space
|
||||||
fs::device_stat stats{};
|
fs::device_stat stats{};
|
||||||
if (!fs::statfs(fs::get_cache_dir(), stats) || stats.avail_free < s_log_size * 8)
|
if (!fs::statfs(fs::get_cache_dir(), stats) || stats.avail_free < s_log_size * 8)
|
||||||
|
@ -410,16 +354,8 @@ logs::file_writer::file_writer(const std::string& name)
|
||||||
// Limit log size to ~25% of free space
|
// Limit log size to ~25% of free space
|
||||||
m_max_size = stats.avail_free / 4;
|
m_max_size = stats.avail_free / 4;
|
||||||
|
|
||||||
// Initialize memory mapped file
|
// Initialize ringbuffer
|
||||||
#ifdef _WIN32
|
m_fptr = std::make_unique<uchar[]>(s_log_size);
|
||||||
m_fmap = CreateFileMappingW(m_file.get_handle(), 0, PAGE_READWRITE, s_log_size >> 32, s_log_size & 0xffffffff, 0);
|
|
||||||
m_fptr = m_fmap ? static_cast<uchar*>(MapViewOfFile(m_fmap, FILE_MAP_WRITE, 0, 0, 0)) : nullptr;
|
|
||||||
#else
|
|
||||||
m_file.trunc(s_log_size);
|
|
||||||
m_fptr = static_cast<uchar*>(::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
verify(name.c_str()), m_fptr;
|
|
||||||
|
|
||||||
// Rotate backups (TODO)
|
// Rotate backups (TODO)
|
||||||
if (std::string gz_file_name = fs::get_cache_dir() + m_name + ".log.gz"; fs::is_file(gz_file_name))
|
if (std::string gz_file_name = fs::get_cache_dir() + m_name + ".log.gz"; fs::is_file(gz_file_name))
|
||||||
|
@ -533,13 +469,9 @@ logs::file_writer::~file_writer()
|
||||||
FILE_DISPOSITION_INFO disp;
|
FILE_DISPOSITION_INFO disp;
|
||||||
disp.DeleteFileW = false;
|
disp.DeleteFileW = false;
|
||||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||||
|
|
||||||
UnmapViewOfFile(m_fptr);
|
|
||||||
CloseHandle(m_fmap);
|
|
||||||
#else
|
#else
|
||||||
// Restore compressed log file permissions
|
// Restore compressed log file permissions
|
||||||
::fchmod(m_fout2.get_handle(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
::fchmod(m_fout2.get_handle(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
::munmap(m_fptr, s_log_size);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +488,7 @@ bool logs::file_writer::flush(u64 bufv)
|
||||||
const u64 size = std::min<u64>(end - st, sizeof(m_zout) / 2);
|
const u64 size = std::min<u64>(end - st, sizeof(m_zout) / 2);
|
||||||
|
|
||||||
// Write uncompressed
|
// Write uncompressed
|
||||||
if (m_fout && st < m_max_size && m_fout.write(m_fptr + st % s_log_size, size) != size)
|
if (m_fout && st < m_max_size && m_fout.write(m_fptr.get() + st % s_log_size, size) != size)
|
||||||
{
|
{
|
||||||
m_fout.close();
|
m_fout.close();
|
||||||
}
|
}
|
||||||
|
@ -565,7 +497,7 @@ bool logs::file_writer::flush(u64 bufv)
|
||||||
if (m_fout2 && st < m_max_size)
|
if (m_fout2 && st < m_max_size)
|
||||||
{
|
{
|
||||||
m_zs.avail_in = static_cast<uInt>(size);
|
m_zs.avail_in = static_cast<uInt>(size);
|
||||||
m_zs.next_in = m_fptr + st % s_log_size;
|
m_zs.next_in = m_fptr.get() + st % s_log_size;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -613,7 +545,7 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
v += size;
|
v += size;
|
||||||
return m_fptr + (v1 + v2) % s_log_size;
|
return m_fptr.get() + (v1 + v2) % s_log_size;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!pos) [[unlikely]]
|
if (!pos) [[unlikely]]
|
||||||
|
@ -631,11 +563,11 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos + size > m_fptr + s_log_size)
|
if (pos + size > m_fptr.get() + s_log_size)
|
||||||
{
|
{
|
||||||
const auto frag = m_fptr + s_log_size - pos;
|
const auto frag = m_fptr.get() + s_log_size - pos;
|
||||||
std::memcpy(pos, text, frag);
|
std::memcpy(pos, text, frag);
|
||||||
std::memcpy(m_fptr, text + frag, size - frag);
|
std::memcpy(m_fptr.get(), text + frag, size - frag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResoluti
|
||||||
|
|
||||||
#include "rpcs3_version.h"
|
#include "rpcs3_version.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
|
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
|
||||||
|
|
||||||
|
@ -203,8 +204,51 @@ QCoreApplication* createApplication(int& argc, char* argv[])
|
||||||
return new gui_application(argc, argv);
|
return new gui_application(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
const std::string lock_name = fs::get_cache_dir() + "RPCS3.buf";
|
||||||
|
|
||||||
|
fs::file instance_lock;
|
||||||
|
|
||||||
|
for (u32 num = 0; num < 100 && !instance_lock.open(lock_name, fs::rewrite + fs::lock); num++)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(30ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!instance_lock)
|
||||||
|
{
|
||||||
|
QApplication app0{argc, argv};
|
||||||
|
|
||||||
|
s_qt_init.unlock();
|
||||||
|
|
||||||
|
if (fs::g_tls_error == fs::error::acces)
|
||||||
|
{
|
||||||
|
if (fs::exists(lock_name))
|
||||||
|
{
|
||||||
|
report_fatal_error("Another instance of RPCS3 is running. Close it or kill its process, if necessary.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
report_fatal_error("Cannot create RPCS3.log (access denied)."
|
||||||
|
#ifdef _WIN32
|
||||||
|
"\nNote that RPCS3 cannot be installed in Program Files or similar directory with limited permissions."
|
||||||
|
#else
|
||||||
|
"\nPlease, check RPCS3 permissions in '~/.config/rpcs3'."
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
report_fatal_error(fmt::format("Cannot create RPCS3.log (error %s)", fs::g_tls_error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
logs::set_init();
|
logs::set_init();
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
|
@ -561,10 +561,6 @@ bool update_manager::handle_rpcs3(const QByteArray& rpcs3_data, bool /*automatic
|
||||||
|
|
||||||
replace_path = Emulator::GetEmuDir() + "rpcs3.exe";
|
replace_path = Emulator::GetEmuDir() + "rpcs3.exe";
|
||||||
|
|
||||||
// Creating a file to indicate we're restarting
|
|
||||||
const std::string s_filelock = fs::get_cache_dir() + ".restart_lock";
|
|
||||||
verify("Restart lock" HERE), !!fs::file(s_filelock, fs::create);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_progress_dialog->close();
|
m_progress_dialog->close();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue