POSIX AIOに対応。 +その他互換性を意識した書き換え
- speedup of update-mime-database by calling fdatasync using AIO API
- --- a/update-mime-database.c
- +++ b/update-mime-database.c
- @@ -37,6 +37,35 @@
- #define NOGLOBS "__NOGLOBS__"
- #define NOMAGIC "__NOMAGIC__"
- +#ifdef HAVE_FDATASYNC
- +# if defined(__linux__) && defined(HAVE_LINUX_AIO_ABI_H)
- +# if defined(HAVE_IO_SUBMIT)
- +# define USE_LINUX_AIO_FDSYNC
- +# elif defined(HAVE_SYSCALL)
- +# include <sys/syscall.h>
- +# ifdef SYS_io_submit
- +# define USE_LINUX_AIO_FDSYNC
- +# endif
- +# endif
- +# ifdef USE_LINUX_AIO_FDSYNC
- +# include <linux/aio_abi.h>
- +# include <sys/eventfd.h>
- +# endif
- +# endif
- +
- +# if HAVE_AIO_FSYNC \
- + && defined(HAVE_DECL_SIGPROCMASK) && HAVE_DECL_SIGPROCMASK \
- + && defined(HAVE_DECL_SIGWAITINFO) && HAVE_DECL_SIGWAITINFO
- +# include <aio.h>
- +# include <signal.h>
- +# define USE_POSIX_AIO_FDSYNC
- +# endif
- +#endif /* HAVE_FDATASYNC */
- +
- +#ifndef O_DSYNC
- +# define O_DSYNC O_SYNC
- +#endif
- +
- #ifndef PATH_SEPARATOR
- # ifdef _WIN32
- # define PATH_SEPARATOR ";"
- @@ -168,12 +197,34 @@
- /* Lists enabled log levels */
- static GLogLevelFlags enabled_log_levels = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING;
- +static GHashTable *rename_set = NULL;
- +
- /* Static prototypes */
- static Magic *magic_new(xmlNode *node, Type *type, GError **error);
- static Match *match_new(void);
- static TreeMagic *tree_magic_new(xmlNode *node, Type *type, GError **error);
- +#if defined(USE_LINUX_AIO_FDSYNC) && !defined(HAVE_IO_SUBMIT)
- +# if defined(HAVE_DECL_SYSCALL) && !HAVE_DECL_SYSCALL
- + long syscall(long, ...);
- +# endif
- +static int io_setup(unsigned nr_events, aio_context_t *ctx_idp){
- + return syscall(SYS_io_setup, nr_events, ctx_idp);
- +}
- +static int io_submit(aio_context_t ctx_id, long nr, struct iocb **iocbpp){
- + return syscall(SYS_io_submit, ctx_id, nr, iocbpp);
- +}
- +static int io_getevents(aio_context_t ctx_id, long min_nr, long nr,
- + struct io_event *events, struct timespec *timeout
- +){
- + return syscall(SYS_io_getevents, ctx_id, min_nr, nr, events, timeout);
- +}
- +static int io_destroy(aio_context_t ctx_id){
- + return syscall(SYS_io_destroy, ctx_id);
- +}
- +#endif
- +
- static void g_log_handler (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *message,
- @@ -986,26 +1037,36 @@
- return 0;
- }
- -/* Renames pathname by removing the .new extension */
- -static gboolean atomic_update(const gchar *pathname, GError **error)
- +static gboolean add_atomic_update(const gchar *pathname, GError **error)
- {
- - gboolean ret = FALSE;
- - gchar *new_name = NULL;
- int len;
- len = strlen(pathname);
- + g_return_val_if_fail(len > 4, FALSE);
- + g_return_val_if_fail(strcmp(pathname + len - 4, ".new") == 0, FALSE);
- + gchar *dupname = g_strdup(pathname);
- + g_hash_table_add(rename_set, dupname);
- +
- + return TRUE;
- +}
- +
- +static gboolean rename_new_file(const gchar *pathname, GError **error){
- + gboolean ret = FALSE;
- + int len;
- + gchar *new_name = NULL;
- +
- + len = strlen(pathname);
- + g_return_val_if_fail(len > 4, FALSE);
- g_return_val_if_fail(strcmp(pathname + len - 4, ".new") == 0, FALSE);
- new_name = g_strndup(pathname, len - 4);
- - if (sync_file(pathname, error) == -1)
- - goto out;
- -
- #ifdef _WIN32
- /* we need to remove the old file first! */
- remove(new_name);
- #endif
- +
- if (rename(pathname, new_name) == -1)
- {
- int errsv = errno;
- @@ -1018,6 +1079,540 @@
- ret = TRUE;
- out:
- g_free(new_name);
- +
- + return ret;
- +}
- +
- +#ifdef HAVE_FDATASYNC
- +struct aio_fdsync_result{
- + int fd;
- + int res; /* if error, negative errno is set */
- + void *data;
- +};
- +struct aio_fdsync_context{
- + /* return value
- + * 1: success
- + * 0: failed
- + * -1: fatal error (with *error set)
- + */
- + int (*init_aio)(struct aio_fdsync_context *context, GError **error);
- +
- + /* start aio fdsync action with given fd and data
- + * return value
- + * 1: success
- + * 0: resource shortage
- + * -1: error (with *error set)
- + */
- + int (*request_aio)(struct aio_fdsync_context *context,
- + int fd, void *data, GError **error);
- +
- + /* wait for (at least 1) aio
- + * finished(out): pointer to Glist* of struct aio_fdsync_result *
- + * Its data should be freed using g_free()
- + * return value
- + * 1: success
- + * -1: error (with *error set)
- + */
- + int (*wait_aio)(struct aio_fdsync_context *context,
- + GList **finished, GError **error);
- +
- + /* abort all aios and deinitialize context
- + * fds: pointer to Glist* of fd (witch is not finished)
- + * data is not pointer, but int.
- + * return value
- + * 1: success
- + * -1: error (with *error set)
- + */
- + int (*free_aio)(struct aio_fdsync_context *context,
- + GList **fds, GError **error);
- +
- + guint max_request;
- + guint ios_in_prog;
- + union{
- + struct{
- +#ifdef USE_LINUX_AIO_FDSYNC
- + aio_context_t aio_context;
- + int evfd;
- + GList *waitings;
- +#else
- + int empty;
- +#endif
- + } li;
- + struct{
- +#ifdef USE_POSIX_AIO_FDSYNC
- + GList *waitings;
- + GList *complete;
- + sigset_t sigset_m;
- + struct sigaction oldact;
- +#else
- + int empty;
- +#endif
- + } po;
- + } u;
- +};
- +
- +static gboolean
- +aio_wait_and_rename(struct aio_fdsync_context *ctx, GError **error){
- + gboolean ret = FALSE;
- + GList *fin_p, *fin_list = NULL;
- +
- + if((*ctx->wait_aio)(ctx, &fin_list, error) != 1){
- + goto out;
- + }
- + for(fin_p = fin_list; fin_p; fin_p = fin_p->next){
- + struct aio_fdsync_result *r = fin_p->data;
- + close(r->fd);
- + ctx->ios_in_prog--;
- + }
- + for(fin_p = fin_list; fin_p; fin_p = fin_p->next){
- + struct aio_fdsync_result *r = fin_p->data;
- + if(r->res < 0){
- + errno = - r->res;
- + set_error_from_errno(error);
- + goto out;
- + }
- + if(!rename_new_file(r->data, error)){
- + goto out;
- + }
- + g_hash_table_remove(rename_set, r->data);
- + }
- +
- + ret = TRUE;
- +out:
- + g_list_free_full(fin_list, g_free);
- + return ret;
- +}
- +
- +static gboolean
- +aio_do_atomic_update(struct aio_fdsync_context *ctx, GError **error){
- + int ret;
- + guint fsync_cnt = g_hash_table_size(rename_set);
- + GList *list_p, *list = NULL;
- +
- + if(!sync_enabled() || fsync_cnt == 0){
- + return TRUE;
- + }
- +
- + ctx->max_request = fsync_cnt;
- + ctx->ios_in_prog = 0;
- + if((ret = (*ctx->init_aio)(ctx, error)) <= 0){
- + return ret >= 0;
- + }
- +
- + list_p = list = g_hash_table_get_keys(rename_set);
- + while(list_p){
- + gchar *pathname = list_p->data;
- + int fd;
- +
- + if((fd = open(pathname, O_RDWR)) < 0){
- + if(errno==EMFILE || errno==ENFILE || errno==ENOMEM){
- + ret = 0;
- + goto nores;
- + }
- + set_error_from_errno(error);
- + ret = -1;
- + goto out;
- + }
- +
- + if((ret = (*ctx->request_aio)(ctx, fd, pathname, error)) <= 0){
- + close(fd);
- + if(ret < 0){
- + goto out;
- + }else{
- + goto nores;
- + }
- + }
- + ctx->ios_in_prog++;
- +
- + list_p = list_p->next;
- + continue;
- +nores:
- + if(ctx->ios_in_prog == 0){
- + goto out;
- + }
- + if(!aio_wait_and_rename(ctx, error)){
- + ret = -1;
- + goto out;
- + }
- + }
- + while(ctx->ios_in_prog > 0){
- + if(!aio_wait_and_rename(ctx, error)){
- + ret = -1;
- + goto out;
- + }
- + }
- +out:
- + g_list_free(list);
- + list = NULL;
- +
- + if(ret < 0){
- + (*ctx->free_aio)(ctx, &list, NULL);
- + }else{
- + ret = (*ctx->free_aio)(ctx, &list, error);
- + }
- + for(list_p = list; list_p; list_p = list_p->next){
- + close(GPOINTER_TO_INT(list_p->data));
- + }
- + g_list_free(list);
- +
- + return ret >= 0;
- +}
- +
- +#ifdef USE_LINUX_AIO_FDSYNC
- +struct aio_fdsync_linux_waiting{
- + struct iocb iocbv;
- + GList *list_ent;
- + void *data;
- +};
- +
- +static int init_aio_linux(struct aio_fdsync_context *context, GError **error){
- + context->u.li.aio_context = 0;
- + while(io_setup(context->max_request, &context->u.li.aio_context)){
- + if(errno == EAGAIN){
- + context->max_request /= 2;
- + if(context->max_request < 1){
- + return 0;
- + }
- + }else{
- + return 0;
- + }
- + }
- +
- + if((context->u.li.evfd = eventfd(0, 0)) < 0){
- + io_destroy(context->u.li.aio_context);
- + return 0;
- + }
- +
- + context->u.li.waitings = NULL;
- +
- + return 1;
- +}
- +
- +static int request_aio_linux(
- + struct aio_fdsync_context *context, int fd, void *data, GError **error
- +){
- + int submited;
- + struct aio_fdsync_linux_waiting *w;
- + struct iocb *iocbp;
- + w = g_malloc0(sizeof(struct aio_fdsync_linux_waiting));
- + w->data = data;
- +
- + w->iocbv.aio_data = (__u64)w;
- + w->iocbv.aio_lio_opcode = IOCB_CMD_FDSYNC;
- + w->iocbv.aio_fildes = fd;
- + w->iocbv.aio_resfd = context->u.li.evfd;
- +
- + iocbp = &w->iocbv;
- + submited = io_submit(context->u.li.aio_context, 1, &iocbp);
- + if(submited <= 0){
- + g_free(w);
- + if(submited == 0 || errno == EAGAIN){
- + return 0;
- + }
- + set_error_from_errno(error);
- + return -1;
- + }
- +
- + w->list_ent
- + = context->u.li.waitings
- + = g_list_prepend(context->u.li.waitings, w);
- +
- + return 1;
- +}
- +
- +static int wait_aio_linux(
- + struct aio_fdsync_context *context, GList **finished, GError **error
- +){
- + int ret = -1;
- + int fin_cnt = 0;
- + struct io_event *io_event_array
- + = g_malloc(sizeof(struct io_event) * context->ios_in_prog);
- +
- + while(fin_cnt <= 0){
- + fin_cnt = io_getevents(context->u.li.aio_context,
- + 1, context->ios_in_prog, io_event_array, NULL);
- + if(fin_cnt < 0){
- + if(errno != EINTR){
- + set_error_from_errno(error);
- + goto out;
- + }
- + }
- + }
- +
- + while(fin_cnt){
- + struct aio_fdsync_linux_waiting *w;
- + struct aio_fdsync_result *res;
- + fin_cnt--;
- +
- + w = (void *)io_event_array[fin_cnt].data;
- + res = g_malloc(sizeof(struct aio_fdsync_result));
- +
- + res->fd = w->iocbv.aio_fildes;
- + res->res = io_event_array[fin_cnt].res;
- + res->data = w->data;
- + *finished = g_list_prepend(*finished, res);
- +
- + context->u.li.waitings = g_list_delete_link(
- + context->u.li.waitings,
- + w->list_ent
- + );
- +
- + g_free(w);
- + }
- +
- + ret = 1;
- +out:
- + g_free(io_event_array);
- + return ret;
- +}
- +
- +static int free_aio_linux(
- + struct aio_fdsync_context *context, GList **fds, GError **error
- +){
- + int ret = 1;
- + GList *list_p;
- +
- + if(io_destroy(context->u.li.aio_context) < 0){
- + set_error_from_errno(error);
- + ret = -1;
- + }
- + close(context->u.li.evfd);
- +
- + for(list_p = context->u.li.waitings; list_p; list_p = list_p->next){
- + struct aio_fdsync_linux_waiting *w = list_p->data;
- + if(fds){
- + *fds = g_list_prepend(*fds,
- + GINT_TO_POINTER(w->iocbv.aio_fildes));
- + }
- + g_free(w);
- + }
- +
- + g_list_free(context->u.li.waitings);
- + context->u.li.waitings = NULL;
- +
- + return ret;
- +}
- +#endif /* USE_LINUX_AIO_FDSYNC */
- +
- +#ifdef USE_POSIX_AIO_FDSYNC
- +struct aio_fdsync_posix_waiting{
- + struct aio_fdsync_context *context;
- + struct aiocb aiocbv;
- + GList *list_ent;
- + void *data;
- +};
- +static void sigaction_aio_posix(int sign, siginfo_t *info, void *con){
- + struct aio_fdsync_posix_waiting *w;
- + if(info->si_code != SI_ASYNCIO){
- + return;
- + }
- + w = info->si_value.sival_ptr;
- + w->context->u.po.complete = g_list_prepend(w->context->u.po.complete, w);
- +}
- +static int init_aio_posix(struct aio_fdsync_context *context, GError **error){
- + struct sigaction act;
- + act.sa_sigaction = sigaction_aio_posix;
- + if(sigemptyset(&act.sa_mask) < 0){
- + return 0;
- + }
- + act.sa_flags = SA_SIGINFO;
- +
- + if(sigemptyset(&context->u.po.sigset_m) < 0){
- + return 0;
- + }
- + if(sigaddset(&context->u.po.sigset_m, SIGRTMIN) < 0){
- + return 0;
- + }
- + if(sigaction(SIGRTMIN, &act, &context->u.po.oldact) < 0){
- + return 0;
- + }
- + context->u.po.waitings = NULL;
- + context->u.po.complete = NULL;
- + return 1;
- +
- +}
- +static int request_aio_posix(
- + struct aio_fdsync_context *context, int fd, void *data, GError **error
- +){
- + struct aio_fdsync_posix_waiting *w;
- +
- + w = g_malloc0(sizeof(struct aio_fdsync_posix_waiting));
- + w->data = data;
- + w->context = context;
- +
- + w->aiocbv.aio_fildes = fd;
- + w->aiocbv.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
- + w->aiocbv.aio_sigevent.sigev_signo = SIGRTMIN;
- + w->aiocbv.aio_sigevent.sigev_value.sival_ptr = w;
- + if(aio_fsync(O_DSYNC, &w->aiocbv) < 0){
- + g_free(w);
- + if(errno == EAGAIN || errno == ENOSYS){
- + return 0;
- + }
- + return -1;
- + }
- +
- + w->list_ent
- + = context->u.po.waitings
- + = g_list_prepend(context->u.po.waitings, w);
- + return 1;
- +}
- +static int wait_aio_posix(
- + struct aio_fdsync_context *context, GList **finished, GError **error
- +){
- + GList *list_p;
- +
- + if(sigprocmask(SIG_BLOCK, &context->u.po.sigset_m, NULL) < 0){
- + g_error("sigprocmask: %s", g_strerror(errno));
- + }
- +
- + while(!context->u.po.complete){
- + siginfo_t sinfo;
- + if(sigwaitinfo(&context->u.po.sigset_m, &sinfo) < 0){
- + if(errno == EAGAIN || errno == EINTR){
- + continue;
- + }
- + g_error("sigwaitinfo: %s", g_strerror(errno));
- + }
- + sigaction_aio_posix(SIGRTMIN, &sinfo, NULL);
- + break;
- + }
- +
- + for(list_p = context->u.po.complete; list_p; list_p = list_p->next){
- + struct aio_fdsync_posix_waiting *w = list_p->data;
- + struct aio_fdsync_result *res;
- + res = g_malloc(sizeof(struct aio_fdsync_result));
- +
- + res->fd = w->aiocbv.aio_fildes;
- + res->data = w->data;
- + if((errno = aio_error(&w->aiocbv)) != 0){
- + if(errno < 0){
- + g_error("negative errno");
- + }
- + res->res = -errno;
- + }else{
- + res->res = 0;
- + }
- + aio_return(&w->aiocbv);
- +
- + *finished = g_list_prepend(*finished, res);
- +
- + context->u.po.waitings = g_list_delete_link(
- + context->u.po.waitings,
- + w->list_ent
- + );
- +
- + g_free(w);
- + }
- + g_list_free(context->u.po.complete);
- + context->u.po.complete = NULL;
- +
- + if(sigprocmask(SIG_UNBLOCK, &context->u.po.sigset_m, NULL) < 0){
- + g_error("sigprocmask: %s", g_strerror(errno));
- + }
- +
- + return 1;
- +}
- +static int free_aio_posix(
- + struct aio_fdsync_context *context, GList **fds, GError **error
- +){
- + GList *list_p;
- + if(sigprocmask(SIG_BLOCK, &context->u.po.sigset_m, NULL) < 0){
- + g_error("sigprocmask: %s", g_strerror(errno));
- + }
- +
- + for(list_p = context->u.po.waitings; list_p; list_p = list_p->next){
- + struct aio_fdsync_posix_waiting *w = list_p->data;
- + aio_cancel(w->aiocbv.aio_fildes, NULL);
- + }
- +
- + while(context->u.po.waitings){
- + siginfo_t sinfo;
- + for(
- + list_p = context->u.po.complete; list_p;
- + list_p = list_p->next
- + ){
- + struct aio_fdsync_posix_waiting *w = list_p->data;
- +
- + if(aio_error(&w->aiocbv) == EINPROGRESS){
- + continue;
- + }
- + aio_return(&w->aiocbv);
- + if(fds){
- + *fds = g_list_prepend(*fds,
- + GINT_TO_POINTER(w->aiocbv.aio_fildes));
- + }
- + context->u.po.waitings = g_list_delete_link(
- + context->u.po.waitings,
- + w->list_ent
- + );
- + g_free(w);
- + }
- + g_list_free(context->u.po.complete);
- + context->u.po.complete = NULL;
- +
- + while(sigwaitinfo(&context->u.po.sigset_m, &sinfo) < 0);
- + sigaction_aio_posix(SIGRTMIN, &sinfo, NULL);
- + }
- +
- + sigaction(SIGRTMIN, &context->u.po.oldact, NULL);
- + if(sigprocmask(SIG_UNBLOCK, &context->u.po.sigset_m, NULL) < 0){
- + g_error("sigprocmask: %s", g_strerror(errno));
- + }
- +
- + return 1;
- +}
- +#endif /* USE_POSIX_AIO_FDSYNC */
- +
- +#endif /* HAVE_FDATASYNC */
- +
- +static gboolean finish_atomic_update(GError **error){
- + gboolean ret = FALSE;
- + GHashTableIter it;
- + gpointer k, v;
- +
- +#ifdef USE_LINUX_AIO_FDSYNC
- + {
- + struct aio_fdsync_context ctx;
- + ctx.init_aio = init_aio_linux;
- + ctx.request_aio = request_aio_linux;
- + ctx.wait_aio = wait_aio_linux;
- + ctx.free_aio = free_aio_linux;
- + if(!aio_do_atomic_update(&ctx, error)){
- + goto out;
- + }
- + }
- +#endif
- +
- +#ifdef USE_POSIX_AIO_FDSYNC
- + {
- + struct aio_fdsync_context ctx;
- + ctx.init_aio = init_aio_posix;
- + ctx.request_aio = request_aio_posix;
- + ctx.wait_aio = wait_aio_posix;
- + ctx.free_aio = free_aio_posix;
- + if(!aio_do_atomic_update(&ctx, error)){
- + goto out;
- + }
- + }
- +#endif
- +
- + g_hash_table_iter_init(&it, rename_set);
- + while(g_hash_table_iter_next(&it, &k, &v)){
- + gchar *pathname = (gchar *)k;
- +
- + if(sync_file(pathname, error)){
- + goto out;
- + }
- +
- + if(!rename_new_file(pathname, error)){
- + goto out;
- + }
- + }
- +
- + ret = TRUE;
- +out:
- + g_hash_table_remove_all(rename_set);
- return ret;
- }
- @@ -1048,7 +1643,7 @@
- if (!save_xml_file(type->output, filename, &local_error))
- fatal_gerror(local_error);
- - if (!atomic_update(filename, &local_error))
- + if (!add_atomic_update(filename, &local_error))
- fatal_gerror(local_error);
- g_free(filename);
- @@ -3731,6 +4326,8 @@
- g_free, NULL);
- generic_icon_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
- + rename_set = g_hash_table_new_full(g_str_hash, g_str_equal,
- + g_free, NULL);
- scan_source_dir(package_dir);
- g_free(package_dir);
- @@ -3756,7 +4353,7 @@
- write_out_glob(glob_list, globs);
- if (!fclose_gerror(globs, error))
- goto out;
- - if (!atomic_update(globs_path, error))
- + if (!add_atomic_update(globs_path, error))
- goto out;
- g_free(globs_path);
- @@ -3770,7 +4367,7 @@
- write_out_glob2 (glob_list, globs);
- if (!fclose_gerror(globs, error))
- goto out;
- - if (!atomic_update(globs_path, error))
- + if (!add_atomic_update(globs_path, error))
- goto out;
- g_free(globs_path);
- @@ -3797,7 +4394,7 @@
- }
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(magic_path, error))
- + if (!add_atomic_update(magic_path, error))
- goto out;
- g_free(magic_path);
- }
- @@ -3813,7 +4410,7 @@
- write_namespaces(stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(ns_path, error))
- + if (!add_atomic_update(ns_path, error))
- goto out;
- g_free(ns_path);
- }
- @@ -3829,7 +4426,7 @@
- write_subclasses(stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- @@ -3845,7 +4442,7 @@
- write_aliases(stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- @@ -3861,7 +4458,7 @@
- write_types(stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- @@ -3877,7 +4474,7 @@
- write_icons(generic_icon_hash, stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(icon_path, error))
- + if (!add_atomic_update(icon_path, error))
- goto out;
- g_free(icon_path);
- }
- @@ -3893,7 +4490,7 @@
- write_icons(icon_hash, stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(icon_path, error))
- + if (!add_atomic_update(icon_path, error))
- goto out;
- g_free(icon_path);
- }
- @@ -3918,7 +4515,7 @@
- }
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- @@ -3934,7 +4531,7 @@
- write_cache(stream);
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- @@ -3951,11 +4548,15 @@
- VERSION "\n");
- if (!fclose_gerror(stream, error))
- goto out;
- - if (!atomic_update(path, error))
- + if (!add_atomic_update(path, error))
- goto out;
- g_free(path);
- }
- + if (!finish_atomic_update(error)){
- + goto out;
- + }
- +
- g_ptr_array_foreach(magic_array, (GFunc)magic_free, NULL);
- g_ptr_array_free(magic_array, TRUE);
- g_ptr_array_foreach(tree_magic_array, (GFunc)tree_magic_free, NULL);
- @@ -3968,6 +4569,7 @@
- g_hash_table_destroy(alias_hash);
- g_hash_table_destroy(icon_hash);
- g_hash_table_destroy(generic_icon_hash);
- + g_hash_table_destroy(rename_set);
- check_in_path_xdg_data(mime_dir);
- --- a/configure.ac
- +++ b/configure.ac
- @@ -20,7 +20,12 @@
- AC_SUBST(GETTEXT_PACKAGE)
- AM_GLIB_GNU_GETTEXT
- -AC_CHECK_FUNCS(fdatasync)
- +AC_CHECK_FUNCS(fdatasync syscall aio_fsync io_submit)
- +AC_CHECK_DECLS([syscall, sigprocmask, sigwaitinfo], [], [], [
- +#include <unistd.h>
- +#include <signal.h>
- +])
- +AC_CHECK_HEADERS(linux/aio_abi.h)
- dnl Check for cross compiling
- AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)