4650: Lower chance of losing written files by syncing them to disk on close, my try r=def- a=heinrich5991

Not sure if it helps, but now it only syncs the config file.

Would supersede #4407.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [x] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: def <dennis@felsin9.de>
Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
bors[bot] 2022-02-01 08:57:57 +00:00 committed by GitHub
commit bc443ce4b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 0 deletions

View file

@ -69,6 +69,7 @@
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <share.h>
#include <shellapi.h>
@ -469,6 +470,19 @@ int io_flush(IOHANDLE io)
return fflush((FILE *)io);
}
int io_sync(IOHANDLE io)
{
if(io_flush(io))
{
return 1;
}
#if defined(CONF_FAMILY_WINDOWS)
return FlushFileBuffers((HANDLE)_get_osfhandle(_fileno((FILE *)io))) == 0;
#else
return fsync(fileno((FILE *)io)) != 0;
#endif
}
#define ASYNC_BUFSIZE 8 * 1024
#define ASYNC_LOCAL_BUFSIZE 64 * 1024

View file

@ -303,6 +303,18 @@ int io_close(IOHANDLE io);
*/
int io_flush(IOHANDLE io);
/*
Function: io_sync
Synchronize file changes to disk.
Parameters:
io - Handle to the file.
Returns:
Returns 0 on success.
*/
int io_sync(IOHANDLE io);
/*
Function: io_error
Checks whether an error occurred during I/O with the file.

View file

@ -110,6 +110,11 @@ bool CConfigManager::Save()
for(int i = 0; i < m_NumCallbacks; i++)
m_aCallbacks[i].m_pfnFunc(this, m_aCallbacks[i].m_pUserData);
if(io_sync(m_ConfigFile) != 0)
{
m_Failed = true;
}
if(io_close(m_ConfigFile) != 0)
m_Failed = true;

View file

@ -68,3 +68,13 @@ TEST(Io, CurrentExe)
EXPECT_GE(io_length(CurrentExe), 1024);
io_close(CurrentExe);
}
TEST(Io, SyncWorks)
{
CTestInfo Info;
IOHANDLE File = io_open(Info.m_aFilename, IOFLAG_WRITE);
ASSERT_TRUE(File);
EXPECT_EQ(io_write(File, "abc\n", 4), 4);
EXPECT_FALSE(io_sync(File));
EXPECT_FALSE(io_close(File));
EXPECT_FALSE(fs_remove(Info.m_aFilename));
}