Skip to content

Commit

Permalink
settings: use fsync / fdatasync on Linux to sync contents
Browse files Browse the repository at this point in the history
Avoid an OS-level sync by using fsync and fdatasync when they are available.

Related-to: #1305
Signed-off-by: David Aguilar <davvid@gmail.com>
  • Loading branch information
davvid committed Mar 29, 2024
1 parent 69e32f0 commit 51efb05
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
26 changes: 23 additions & 3 deletions cola/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
The @interruptable functions retry when system calls are interrupted,
e.g. when python raises an IOError or OSError with errno == EINTR.
"""
import ctypes
import functools
import itertools
import mimetypes
Expand Down Expand Up @@ -481,9 +482,28 @@ def _find_executable(executable, path=None):
return executable


def sync():
"""Force writing of everything to disk. No-op on systems without os.sync()"""
if hasattr(os, 'sync'):
def sync(path):
"""Flush contents to disk. No-op on systems without os.sync() or libc.so.6"""
try:
libc = ctypes.CDLL('libc.so.6')
except OSError:
libc = None
synced = False
has_fdatasync = libc and hasattr(libc, 'fdatasync')
has_fsync = libc and hasattr(libc, 'fsync')
if has_fdatasync:
try:
with open(path, 'a', encoding='utf-8') as fd:
synced = libc.fdatasync(fd.fileno()) == 0
except (OSError, IOError):
pass
elif has_fsync:
try:
with open(path, 'a', encoding='utf-8') as fd:
synced = libc.fsync(fd.fileno()) == 0
except (OSError, IOError):
pass
if not synced and hasattr(os, 'sync'):
os.sync()


Expand Down
2 changes: 1 addition & 1 deletion cola/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def save(self, sync=True):
return
# Flush the data to disk.
if sync:
core.sync()
core.sync(path)
# Delete the .bak file.
if core.exists(path_bak):
remove_path(path_bak)
Expand Down
6 changes: 3 additions & 3 deletions docs/git-cola.rst
Original file line number Diff line number Diff line change
Expand Up @@ -857,9 +857,9 @@ Defaults to `false`.

cola.sync
---------
Set to `false` to disable calling `os.sync()` when saving settings.
Defaults to `true`, which means that `os.sync()` is called when windows are closed
and their settings are saved.
Set to `false` to disable calling `os.sync()` / `fdatasync(2)` / `fsync(2)` when saving
settings. Defaults to `true`, which means that these functions are called when windows
are closed and their settings are saved.

cola.tabwidth
-------------
Expand Down

0 comments on commit 51efb05

Please sign in to comment.