mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00: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
@ -1147,7 +1147,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
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
|
||||
verify(HERE), ::ftruncate(fd, 0) == 0;
|
||||
|
@ -62,17 +62,13 @@ namespace logs
|
||||
|
||||
class file_writer
|
||||
{
|
||||
fs::file m_file;
|
||||
std::string m_name;
|
||||
std::thread m_writer;
|
||||
fs::file m_fout;
|
||||
fs::file m_fout2;
|
||||
u64 m_max_size;
|
||||
|
||||
#ifdef _WIN32
|
||||
::HANDLE m_fmap;
|
||||
#endif
|
||||
uchar* m_fptr{};
|
||||
std::unique_ptr<uchar[]> m_fptr;
|
||||
z_stream m_zs{};
|
||||
shared_mutex m_m;
|
||||
|
||||
@ -345,61 +341,9 @@ logs::file_writer::file_writer(const std::string& name)
|
||||
: m_name(name)
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
fs::device_stat stats{};
|
||||
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
|
||||
m_max_size = stats.avail_free / 4;
|
||||
|
||||
// Initialize memory mapped file
|
||||
#ifdef _WIN32
|
||||
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;
|
||||
// Initialize ringbuffer
|
||||
m_fptr = std::make_unique<uchar[]>(s_log_size);
|
||||
|
||||
// Rotate backups (TODO)
|
||||
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;
|
||||
disp.DeleteFileW = false;
|
||||
SetFileInformationByHandle(m_fout2.get_handle(), FileDispositionInfo, &disp, sizeof(disp));
|
||||
|
||||
UnmapViewOfFile(m_fptr);
|
||||
CloseHandle(m_fmap);
|
||||
#else
|
||||
// Restore compressed log file permissions
|
||||
::fchmod(m_fout2.get_handle(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
::munmap(m_fptr, s_log_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -556,7 +488,7 @@ bool logs::file_writer::flush(u64 bufv)
|
||||
const u64 size = std::min<u64>(end - st, sizeof(m_zout) / 2);
|
||||
|
||||
// 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();
|
||||
}
|
||||
@ -565,7 +497,7 @@ bool logs::file_writer::flush(u64 bufv)
|
||||
if (m_fout2 && st < m_max_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
|
||||
{
|
||||
@ -613,7 +545,7 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
}
|
||||
|
||||
v += size;
|
||||
return m_fptr + (v1 + v2) % s_log_size;
|
||||
return m_fptr.get() + (v1 + v2) % s_log_size;
|
||||
});
|
||||
|
||||
if (!pos) [[unlikely]]
|
||||
@ -631,11 +563,11 @@ void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
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(m_fptr, text + frag, size - frag);
|
||||
std::memcpy(m_fptr.get(), text + frag, size - frag);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResoluti
|
||||
|
||||
#include "rpcs3_version.h"
|
||||
#include "Emu/System.h"
|
||||
#include <thread>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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();
|
||||
|
||||
#ifdef __linux__
|
||||
|
@ -561,10 +561,6 @@ bool update_manager::handle_rpcs3(const QByteArray& rpcs3_data, bool /*automatic
|
||||
|
||||
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
|
||||
|
||||
m_progress_dialog->close();
|
||||
|
Loading…
Reference in New Issue
Block a user