mirror of
https://github.com/neovim/neovim.git
synced 2025-10-17 23:31:51 +00:00
refactor(shada): devirtualize writer
writer is only ever used with FileDescriptor. We already have separate code paths for serializing shada data into memory, see shada_encode_regs() and friends
This commit is contained in:
@@ -386,26 +386,6 @@ struct sd_read_def {
|
|||||||
///< reader structure initialization). May overflow.
|
///< reader structure initialization). May overflow.
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct sd_write_def ShaDaWriteDef;
|
|
||||||
|
|
||||||
/// Function used to close files defined by ShaDaWriteDef
|
|
||||||
typedef void (*ShaDaWriteCloser)(ShaDaWriteDef *const sd_writer)
|
|
||||||
REAL_FATTR_NONNULL_ALL;
|
|
||||||
|
|
||||||
/// Function used to write ShaDa files
|
|
||||||
typedef ptrdiff_t (*ShaDaFileWriter)(ShaDaWriteDef *const sd_writer,
|
|
||||||
const void *const src,
|
|
||||||
const size_t size)
|
|
||||||
REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT;
|
|
||||||
|
|
||||||
/// Structure containing necessary pointers for writing ShaDa files
|
|
||||||
struct sd_write_def {
|
|
||||||
ShaDaFileWriter write; ///< Writer function.
|
|
||||||
ShaDaWriteCloser close; ///< Close function.
|
|
||||||
FileDescriptor cookie; ///< Data describing object written to.
|
|
||||||
const char *error; ///< Error message in case of error.
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "shada.c.generated.h"
|
# include "shada.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -636,21 +616,6 @@ static int read_char(ShaDaReadDef *const sd_reader)
|
|||||||
return (int)ret;
|
return (int)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for writing to file descriptors
|
|
||||||
///
|
|
||||||
/// @return -1 or number of bytes written.
|
|
||||||
static ptrdiff_t write_file(ShaDaWriteDef *const sd_writer, const void *const dest,
|
|
||||||
const size_t size)
|
|
||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
|
||||||
{
|
|
||||||
const ptrdiff_t ret = file_write(&sd_writer->cookie, dest, size);
|
|
||||||
if (ret < 0) {
|
|
||||||
sd_writer->error = os_strerror((int)ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for closing file descriptors opened for reading
|
/// Wrapper for closing file descriptors opened for reading
|
||||||
static void close_sd_reader(ShaDaReadDef *const sd_reader)
|
static void close_sd_reader(ShaDaReadDef *const sd_reader)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
@@ -659,13 +624,6 @@ static void close_sd_reader(ShaDaReadDef *const sd_reader)
|
|||||||
xfree(sd_reader->cookie);
|
xfree(sd_reader->cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for closing file descriptors opened for writing
|
|
||||||
static void close_sd_writer(ShaDaWriteDef *const sd_writer)
|
|
||||||
FUNC_ATTR_NONNULL_ALL
|
|
||||||
{
|
|
||||||
close_file(&sd_writer->cookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for read that reads to IObuff and ignores bytes read
|
/// Wrapper for read that reads to IObuff and ignores bytes read
|
||||||
///
|
///
|
||||||
/// Used for skipping.
|
/// Used for skipping.
|
||||||
@@ -753,7 +711,7 @@ static int open_shada_file_for_reading(const char *const fname, ShaDaReadDef *sd
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for closing file descriptors
|
/// Wrapper for closing file descriptors
|
||||||
static void close_file(void *cookie)
|
static void close_file(FileDescriptor *cookie)
|
||||||
{
|
{
|
||||||
const int error = file_close(cookie, !!p_fs);
|
const int error = file_close(cookie, !!p_fs);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
@@ -762,16 +720,17 @@ static void close_file(void *cookie)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Msgpack callback for writing to ShaDaWriteDef*
|
/// Msgpack callback for writing to FileDescriptor*
|
||||||
static int msgpack_sd_writer_write(void *data, const char *buf, size_t len)
|
static int msgpack_sd_writer_write(void *data, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *)data;
|
FileDescriptor *const sd_writer = (FileDescriptor *)data;
|
||||||
ptrdiff_t written_bytes = sd_writer->write(sd_writer, buf, len);
|
const ptrdiff_t ret = file_write(sd_writer, buf, len);
|
||||||
if (written_bytes == -1) {
|
if (ret < 0) {
|
||||||
semsg(_(SERR "System error while writing ShaDa file: %s"),
|
semsg(_(SERR "System error while writing ShaDa file: %s"),
|
||||||
sd_writer->error);
|
os_strerror((int)ret));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2524,7 +2483,7 @@ static int hist_type2char(const int type)
|
|||||||
/// @param[in] sd_reader Structure containing file reader definition. If it is
|
/// @param[in] sd_reader Structure containing file reader definition. If it is
|
||||||
/// not NULL then contents of this file will be merged
|
/// not NULL then contents of this file will be merged
|
||||||
/// with current Neovim runtime.
|
/// with current Neovim runtime.
|
||||||
static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef *const sd_reader)
|
static ShaDaWriteResult shada_write(FileDescriptor *const sd_writer, ShaDaReadDef *const sd_reader)
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
ShaDaWriteResult ret = kSDWriteSuccessful;
|
ShaDaWriteResult ret = kSDWriteSuccessful;
|
||||||
@@ -2998,11 +2957,7 @@ int shada_write_file(const char *const file, bool nomerge)
|
|||||||
|
|
||||||
char *const fname = shada_filename(file);
|
char *const fname = shada_filename(file);
|
||||||
char *tempname = NULL;
|
char *tempname = NULL;
|
||||||
ShaDaWriteDef sd_writer = {
|
FileDescriptor sd_writer;
|
||||||
.write = &write_file,
|
|
||||||
.close = &close_sd_writer,
|
|
||||||
.error = NULL,
|
|
||||||
};
|
|
||||||
ShaDaReadDef sd_reader = { .close = NULL };
|
ShaDaReadDef sd_reader = { .close = NULL };
|
||||||
bool did_open_writer = false;
|
bool did_open_writer = false;
|
||||||
|
|
||||||
@@ -3034,7 +2989,7 @@ int shada_write_file(const char *const file, bool nomerge)
|
|||||||
// 3: If somebody happened to delete the file after it was opened for
|
// 3: If somebody happened to delete the file after it was opened for
|
||||||
// reading use u=rw permissions.
|
// reading use u=rw permissions.
|
||||||
shada_write_file_open: {}
|
shada_write_file_open: {}
|
||||||
error = file_open(&sd_writer.cookie, tempname, kFileCreateOnly|kFileNoSymlink, perm);
|
error = file_open(&sd_writer, tempname, kFileCreateOnly|kFileNoSymlink, perm);
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error == UV_EEXIST || error == UV_ELOOP) {
|
if (error == UV_EEXIST || error == UV_ELOOP) {
|
||||||
// File already exists, try another name
|
// File already exists, try another name
|
||||||
@@ -3080,7 +3035,7 @@ shada_write_file_nomerge: {}
|
|||||||
}
|
}
|
||||||
*tail = tail_save;
|
*tail = tail_save;
|
||||||
}
|
}
|
||||||
int error = file_open(&sd_writer.cookie, fname, kFileCreate|kFileTruncate, 0600);
|
int error = file_open(&sd_writer, fname, kFileCreate|kFileTruncate, 0600);
|
||||||
if (error) {
|
if (error) {
|
||||||
semsg(_(SERR "System error while opening ShaDa file %s for writing: %s"),
|
semsg(_(SERR "System error while opening ShaDa file %s for writing: %s"),
|
||||||
fname, os_strerror(error));
|
fname, os_strerror(error));
|
||||||
@@ -3104,9 +3059,7 @@ shada_write_file_nomerge: {}
|
|||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
|
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge ? NULL : &sd_reader));
|
||||||
? NULL
|
|
||||||
: &sd_reader));
|
|
||||||
assert(sw_ret != kSDWriteIgnError);
|
assert(sw_ret != kSDWriteIgnError);
|
||||||
if (!nomerge) {
|
if (!nomerge) {
|
||||||
sd_reader.close(&sd_reader);
|
sd_reader.close(&sd_reader);
|
||||||
@@ -3136,7 +3089,7 @@ shada_write_file_nomerge: {}
|
|||||||
|| old_info.stat.st_gid != getgid()) {
|
|| old_info.stat.st_gid != getgid()) {
|
||||||
const uv_uid_t old_uid = (uv_uid_t)old_info.stat.st_uid;
|
const uv_uid_t old_uid = (uv_uid_t)old_info.stat.st_uid;
|
||||||
const uv_gid_t old_gid = (uv_gid_t)old_info.stat.st_gid;
|
const uv_gid_t old_gid = (uv_gid_t)old_info.stat.st_gid;
|
||||||
const int fchown_ret = os_fchown(file_fd(&sd_writer.cookie),
|
const int fchown_ret = os_fchown(file_fd(&sd_writer),
|
||||||
old_uid, old_gid);
|
old_uid, old_gid);
|
||||||
if (fchown_ret != 0) {
|
if (fchown_ret != 0) {
|
||||||
semsg(_(RNERR "Failed setting uid and gid for file %s: %s"),
|
semsg(_(RNERR "Failed setting uid and gid for file %s: %s"),
|
||||||
@@ -3169,7 +3122,7 @@ shada_write_file_did_not_remove:
|
|||||||
}
|
}
|
||||||
xfree(tempname);
|
xfree(tempname);
|
||||||
}
|
}
|
||||||
sd_writer.close(&sd_writer);
|
close_file(&sd_writer);
|
||||||
|
|
||||||
xfree(fname);
|
xfree(fname);
|
||||||
return OK;
|
return OK;
|
||||||
|
Reference in New Issue
Block a user