POSIX AIOに対応。 +その他互換性を意識した書き換え

Format
Diff
Post date
2020-03-15 02:10
Publication Period
Unlimited
  1. speedup of update-mime-database by calling fdatasync using AIO API
  2. --- a/update-mime-database.c
  3. +++ b/update-mime-database.c
  4. @@ -37,6 +37,35 @@
  5. #define NOGLOBS "__NOGLOBS__"
  6. #define NOMAGIC "__NOMAGIC__"
  7. +#ifdef HAVE_FDATASYNC
  8. +# if defined(__linux__) && defined(HAVE_LINUX_AIO_ABI_H)
  9. +# if defined(HAVE_IO_SUBMIT)
  10. +# define USE_LINUX_AIO_FDSYNC
  11. +# elif defined(HAVE_SYSCALL)
  12. +# include <sys/syscall.h>
  13. +# ifdef SYS_io_submit
  14. +# define USE_LINUX_AIO_FDSYNC
  15. +# endif
  16. +# endif
  17. +# ifdef USE_LINUX_AIO_FDSYNC
  18. +# include <linux/aio_abi.h>
  19. +# include <sys/eventfd.h>
  20. +# endif
  21. +# endif
  22. +
  23. +# if HAVE_AIO_FSYNC \
  24. + && defined(HAVE_DECL_SIGPROCMASK) && HAVE_DECL_SIGPROCMASK \
  25. + && defined(HAVE_DECL_SIGWAITINFO) && HAVE_DECL_SIGWAITINFO
  26. +# include <aio.h>
  27. +# include <signal.h>
  28. +# define USE_POSIX_AIO_FDSYNC
  29. +# endif
  30. +#endif /* HAVE_FDATASYNC */
  31. +
  32. +#ifndef O_DSYNC
  33. +# define O_DSYNC O_SYNC
  34. +#endif
  35. +
  36. #ifndef PATH_SEPARATOR
  37. # ifdef _WIN32
  38. # define PATH_SEPARATOR ";"
  39. @@ -168,12 +197,34 @@
  40. /* Lists enabled log levels */
  41. static GLogLevelFlags enabled_log_levels = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING;
  42. +static GHashTable *rename_set = NULL;
  43. +
  44. /* Static prototypes */
  45. static Magic *magic_new(xmlNode *node, Type *type, GError **error);
  46. static Match *match_new(void);
  47. static TreeMagic *tree_magic_new(xmlNode *node, Type *type, GError **error);
  48. +#if defined(USE_LINUX_AIO_FDSYNC) && !defined(HAVE_IO_SUBMIT)
  49. +# if defined(HAVE_DECL_SYSCALL) && !HAVE_DECL_SYSCALL
  50. + long syscall(long, ...);
  51. +# endif
  52. +static int io_setup(unsigned nr_events, aio_context_t *ctx_idp){
  53. + return syscall(SYS_io_setup, nr_events, ctx_idp);
  54. +}
  55. +static int io_submit(aio_context_t ctx_id, long nr, struct iocb **iocbpp){
  56. + return syscall(SYS_io_submit, ctx_id, nr, iocbpp);
  57. +}
  58. +static int io_getevents(aio_context_t ctx_id, long min_nr, long nr,
  59. + struct io_event *events, struct timespec *timeout
  60. +){
  61. + return syscall(SYS_io_getevents, ctx_id, min_nr, nr, events, timeout);
  62. +}
  63. +static int io_destroy(aio_context_t ctx_id){
  64. + return syscall(SYS_io_destroy, ctx_id);
  65. +}
  66. +#endif
  67. +
  68. static void g_log_handler (const gchar *log_domain,
  69. GLogLevelFlags log_level,
  70. const gchar *message,
  71. @@ -986,26 +1037,36 @@
  72. return 0;
  73. }
  74. -/* Renames pathname by removing the .new extension */
  75. -static gboolean atomic_update(const gchar *pathname, GError **error)
  76. +static gboolean add_atomic_update(const gchar *pathname, GError **error)
  77. {
  78. - gboolean ret = FALSE;
  79. - gchar *new_name = NULL;
  80. int len;
  81. len = strlen(pathname);
  82. + g_return_val_if_fail(len > 4, FALSE);
  83. + g_return_val_if_fail(strcmp(pathname + len - 4, ".new") == 0, FALSE);
  84. + gchar *dupname = g_strdup(pathname);
  85. + g_hash_table_add(rename_set, dupname);
  86. +
  87. + return TRUE;
  88. +}
  89. +
  90. +static gboolean rename_new_file(const gchar *pathname, GError **error){
  91. + gboolean ret = FALSE;
  92. + int len;
  93. + gchar *new_name = NULL;
  94. +
  95. + len = strlen(pathname);
  96. + g_return_val_if_fail(len > 4, FALSE);
  97. g_return_val_if_fail(strcmp(pathname + len - 4, ".new") == 0, FALSE);
  98. new_name = g_strndup(pathname, len - 4);
  99. - if (sync_file(pathname, error) == -1)
  100. - goto out;
  101. -
  102. #ifdef _WIN32
  103. /* we need to remove the old file first! */
  104. remove(new_name);
  105. #endif
  106. +
  107. if (rename(pathname, new_name) == -1)
  108. {
  109. int errsv = errno;
  110. @@ -1018,6 +1079,540 @@
  111. ret = TRUE;
  112. out:
  113. g_free(new_name);
  114. +
  115. + return ret;
  116. +}
  117. +
  118. +#ifdef HAVE_FDATASYNC
  119. +struct aio_fdsync_result{
  120. + int fd;
  121. + int res; /* if error, negative errno is set */
  122. + void *data;
  123. +};
  124. +struct aio_fdsync_context{
  125. + /* return value
  126. + * 1: success
  127. + * 0: failed
  128. + * -1: fatal error (with *error set)
  129. + */
  130. + int (*init_aio)(struct aio_fdsync_context *context, GError **error);
  131. +
  132. + /* start aio fdsync action with given fd and data
  133. + * return value
  134. + * 1: success
  135. + * 0: resource shortage
  136. + * -1: error (with *error set)
  137. + */
  138. + int (*request_aio)(struct aio_fdsync_context *context,
  139. + int fd, void *data, GError **error);
  140. +
  141. + /* wait for (at least 1) aio
  142. + * finished(out): pointer to Glist* of struct aio_fdsync_result *
  143. + * Its data should be freed using g_free()
  144. + * return value
  145. + * 1: success
  146. + * -1: error (with *error set)
  147. + */
  148. + int (*wait_aio)(struct aio_fdsync_context *context,
  149. + GList **finished, GError **error);
  150. +
  151. + /* abort all aios and deinitialize context
  152. + * fds: pointer to Glist* of fd (witch is not finished)
  153. + * data is not pointer, but int.
  154. + * return value
  155. + * 1: success
  156. + * -1: error (with *error set)
  157. + */
  158. + int (*free_aio)(struct aio_fdsync_context *context,
  159. + GList **fds, GError **error);
  160. +
  161. + guint max_request;
  162. + guint ios_in_prog;
  163. + union{
  164. + struct{
  165. +#ifdef USE_LINUX_AIO_FDSYNC
  166. + aio_context_t aio_context;
  167. + int evfd;
  168. + GList *waitings;
  169. +#else
  170. + int empty;
  171. +#endif
  172. + } li;
  173. + struct{
  174. +#ifdef USE_POSIX_AIO_FDSYNC
  175. + GList *waitings;
  176. + GList *complete;
  177. + sigset_t sigset_m;
  178. + struct sigaction oldact;
  179. +#else
  180. + int empty;
  181. +#endif
  182. + } po;
  183. + } u;
  184. +};
  185. +
  186. +static gboolean
  187. +aio_wait_and_rename(struct aio_fdsync_context *ctx, GError **error){
  188. + gboolean ret = FALSE;
  189. + GList *fin_p, *fin_list = NULL;
  190. +
  191. + if((*ctx->wait_aio)(ctx, &fin_list, error) != 1){
  192. + goto out;
  193. + }
  194. + for(fin_p = fin_list; fin_p; fin_p = fin_p->next){
  195. + struct aio_fdsync_result *r = fin_p->data;
  196. + close(r->fd);
  197. + ctx->ios_in_prog--;
  198. + }
  199. + for(fin_p = fin_list; fin_p; fin_p = fin_p->next){
  200. + struct aio_fdsync_result *r = fin_p->data;
  201. + if(r->res < 0){
  202. + errno = - r->res;
  203. + set_error_from_errno(error);
  204. + goto out;
  205. + }
  206. + if(!rename_new_file(r->data, error)){
  207. + goto out;
  208. + }
  209. + g_hash_table_remove(rename_set, r->data);
  210. + }
  211. +
  212. + ret = TRUE;
  213. +out:
  214. + g_list_free_full(fin_list, g_free);
  215. + return ret;
  216. +}
  217. +
  218. +static gboolean
  219. +aio_do_atomic_update(struct aio_fdsync_context *ctx, GError **error){
  220. + int ret;
  221. + guint fsync_cnt = g_hash_table_size(rename_set);
  222. + GList *list_p, *list = NULL;
  223. +
  224. + if(!sync_enabled() || fsync_cnt == 0){
  225. + return TRUE;
  226. + }
  227. +
  228. + ctx->max_request = fsync_cnt;
  229. + ctx->ios_in_prog = 0;
  230. + if((ret = (*ctx->init_aio)(ctx, error)) <= 0){
  231. + return ret >= 0;
  232. + }
  233. +
  234. + list_p = list = g_hash_table_get_keys(rename_set);
  235. + while(list_p){
  236. + gchar *pathname = list_p->data;
  237. + int fd;
  238. +
  239. + if((fd = open(pathname, O_RDWR)) < 0){
  240. + if(errno==EMFILE || errno==ENFILE || errno==ENOMEM){
  241. + ret = 0;
  242. + goto nores;
  243. + }
  244. + set_error_from_errno(error);
  245. + ret = -1;
  246. + goto out;
  247. + }
  248. +
  249. + if((ret = (*ctx->request_aio)(ctx, fd, pathname, error)) <= 0){
  250. + close(fd);
  251. + if(ret < 0){
  252. + goto out;
  253. + }else{
  254. + goto nores;
  255. + }
  256. + }
  257. + ctx->ios_in_prog++;
  258. +
  259. + list_p = list_p->next;
  260. + continue;
  261. +nores:
  262. + if(ctx->ios_in_prog == 0){
  263. + goto out;
  264. + }
  265. + if(!aio_wait_and_rename(ctx, error)){
  266. + ret = -1;
  267. + goto out;
  268. + }
  269. + }
  270. + while(ctx->ios_in_prog > 0){
  271. + if(!aio_wait_and_rename(ctx, error)){
  272. + ret = -1;
  273. + goto out;
  274. + }
  275. + }
  276. +out:
  277. + g_list_free(list);
  278. + list = NULL;
  279. +
  280. + if(ret < 0){
  281. + (*ctx->free_aio)(ctx, &list, NULL);
  282. + }else{
  283. + ret = (*ctx->free_aio)(ctx, &list, error);
  284. + }
  285. + for(list_p = list; list_p; list_p = list_p->next){
  286. + close(GPOINTER_TO_INT(list_p->data));
  287. + }
  288. + g_list_free(list);
  289. +
  290. + return ret >= 0;
  291. +}
  292. +
  293. +#ifdef USE_LINUX_AIO_FDSYNC
  294. +struct aio_fdsync_linux_waiting{
  295. + struct iocb iocbv;
  296. + GList *list_ent;
  297. + void *data;
  298. +};
  299. +
  300. +static int init_aio_linux(struct aio_fdsync_context *context, GError **error){
  301. + context->u.li.aio_context = 0;
  302. + while(io_setup(context->max_request, &context->u.li.aio_context)){
  303. + if(errno == EAGAIN){
  304. + context->max_request /= 2;
  305. + if(context->max_request < 1){
  306. + return 0;
  307. + }
  308. + }else{
  309. + return 0;
  310. + }
  311. + }
  312. +
  313. + if((context->u.li.evfd = eventfd(0, 0)) < 0){
  314. + io_destroy(context->u.li.aio_context);
  315. + return 0;
  316. + }
  317. +
  318. + context->u.li.waitings = NULL;
  319. +
  320. + return 1;
  321. +}
  322. +
  323. +static int request_aio_linux(
  324. + struct aio_fdsync_context *context, int fd, void *data, GError **error
  325. +){
  326. + int submited;
  327. + struct aio_fdsync_linux_waiting *w;
  328. + struct iocb *iocbp;
  329. + w = g_malloc0(sizeof(struct aio_fdsync_linux_waiting));
  330. + w->data = data;
  331. +
  332. + w->iocbv.aio_data = (__u64)w;
  333. + w->iocbv.aio_lio_opcode = IOCB_CMD_FDSYNC;
  334. + w->iocbv.aio_fildes = fd;
  335. + w->iocbv.aio_resfd = context->u.li.evfd;
  336. +
  337. + iocbp = &w->iocbv;
  338. + submited = io_submit(context->u.li.aio_context, 1, &iocbp);
  339. + if(submited <= 0){
  340. + g_free(w);
  341. + if(submited == 0 || errno == EAGAIN){
  342. + return 0;
  343. + }
  344. + set_error_from_errno(error);
  345. + return -1;
  346. + }
  347. +
  348. + w->list_ent
  349. + = context->u.li.waitings
  350. + = g_list_prepend(context->u.li.waitings, w);
  351. +
  352. + return 1;
  353. +}
  354. +
  355. +static int wait_aio_linux(
  356. + struct aio_fdsync_context *context, GList **finished, GError **error
  357. +){
  358. + int ret = -1;
  359. + int fin_cnt = 0;
  360. + struct io_event *io_event_array
  361. + = g_malloc(sizeof(struct io_event) * context->ios_in_prog);
  362. +
  363. + while(fin_cnt <= 0){
  364. + fin_cnt = io_getevents(context->u.li.aio_context,
  365. + 1, context->ios_in_prog, io_event_array, NULL);
  366. + if(fin_cnt < 0){
  367. + if(errno != EINTR){
  368. + set_error_from_errno(error);
  369. + goto out;
  370. + }
  371. + }
  372. + }
  373. +
  374. + while(fin_cnt){
  375. + struct aio_fdsync_linux_waiting *w;
  376. + struct aio_fdsync_result *res;
  377. + fin_cnt--;
  378. +
  379. + w = (void *)io_event_array[fin_cnt].data;
  380. + res = g_malloc(sizeof(struct aio_fdsync_result));
  381. +
  382. + res->fd = w->iocbv.aio_fildes;
  383. + res->res = io_event_array[fin_cnt].res;
  384. + res->data = w->data;
  385. + *finished = g_list_prepend(*finished, res);
  386. +
  387. + context->u.li.waitings = g_list_delete_link(
  388. + context->u.li.waitings,
  389. + w->list_ent
  390. + );
  391. +
  392. + g_free(w);
  393. + }
  394. +
  395. + ret = 1;
  396. +out:
  397. + g_free(io_event_array);
  398. + return ret;
  399. +}
  400. +
  401. +static int free_aio_linux(
  402. + struct aio_fdsync_context *context, GList **fds, GError **error
  403. +){
  404. + int ret = 1;
  405. + GList *list_p;
  406. +
  407. + if(io_destroy(context->u.li.aio_context) < 0){
  408. + set_error_from_errno(error);
  409. + ret = -1;
  410. + }
  411. + close(context->u.li.evfd);
  412. +
  413. + for(list_p = context->u.li.waitings; list_p; list_p = list_p->next){
  414. + struct aio_fdsync_linux_waiting *w = list_p->data;
  415. + if(fds){
  416. + *fds = g_list_prepend(*fds,
  417. + GINT_TO_POINTER(w->iocbv.aio_fildes));
  418. + }
  419. + g_free(w);
  420. + }
  421. +
  422. + g_list_free(context->u.li.waitings);
  423. + context->u.li.waitings = NULL;
  424. +
  425. + return ret;
  426. +}
  427. +#endif /* USE_LINUX_AIO_FDSYNC */
  428. +
  429. +#ifdef USE_POSIX_AIO_FDSYNC
  430. +struct aio_fdsync_posix_waiting{
  431. + struct aio_fdsync_context *context;
  432. + struct aiocb aiocbv;
  433. + GList *list_ent;
  434. + void *data;
  435. +};
  436. +static void sigaction_aio_posix(int sign, siginfo_t *info, void *con){
  437. + struct aio_fdsync_posix_waiting *w;
  438. + if(info->si_code != SI_ASYNCIO){
  439. + return;
  440. + }
  441. + w = info->si_value.sival_ptr;
  442. + w->context->u.po.complete = g_list_prepend(w->context->u.po.complete, w);
  443. +}
  444. +static int init_aio_posix(struct aio_fdsync_context *context, GError **error){
  445. + struct sigaction act;
  446. + act.sa_sigaction = sigaction_aio_posix;
  447. + if(sigemptyset(&act.sa_mask) < 0){
  448. + return 0;
  449. + }
  450. + act.sa_flags = SA_SIGINFO;
  451. +
  452. + if(sigemptyset(&context->u.po.sigset_m) < 0){
  453. + return 0;
  454. + }
  455. + if(sigaddset(&context->u.po.sigset_m, SIGRTMIN) < 0){
  456. + return 0;
  457. + }
  458. + if(sigaction(SIGRTMIN, &act, &context->u.po.oldact) < 0){
  459. + return 0;
  460. + }
  461. + context->u.po.waitings = NULL;
  462. + context->u.po.complete = NULL;
  463. + return 1;
  464. +
  465. +}
  466. +static int request_aio_posix(
  467. + struct aio_fdsync_context *context, int fd, void *data, GError **error
  468. +){
  469. + struct aio_fdsync_posix_waiting *w;
  470. +
  471. + w = g_malloc0(sizeof(struct aio_fdsync_posix_waiting));
  472. + w->data = data;
  473. + w->context = context;
  474. +
  475. + w->aiocbv.aio_fildes = fd;
  476. + w->aiocbv.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
  477. + w->aiocbv.aio_sigevent.sigev_signo = SIGRTMIN;
  478. + w->aiocbv.aio_sigevent.sigev_value.sival_ptr = w;
  479. + if(aio_fsync(O_DSYNC, &w->aiocbv) < 0){
  480. + g_free(w);
  481. + if(errno == EAGAIN || errno == ENOSYS){
  482. + return 0;
  483. + }
  484. + return -1;
  485. + }
  486. +
  487. + w->list_ent
  488. + = context->u.po.waitings
  489. + = g_list_prepend(context->u.po.waitings, w);
  490. + return 1;
  491. +}
  492. +static int wait_aio_posix(
  493. + struct aio_fdsync_context *context, GList **finished, GError **error
  494. +){
  495. + GList *list_p;
  496. +
  497. + if(sigprocmask(SIG_BLOCK, &context->u.po.sigset_m, NULL) < 0){
  498. + g_error("sigprocmask: %s", g_strerror(errno));
  499. + }
  500. +
  501. + while(!context->u.po.complete){
  502. + siginfo_t sinfo;
  503. + if(sigwaitinfo(&context->u.po.sigset_m, &sinfo) < 0){
  504. + if(errno == EAGAIN || errno == EINTR){
  505. + continue;
  506. + }
  507. + g_error("sigwaitinfo: %s", g_strerror(errno));
  508. + }
  509. + sigaction_aio_posix(SIGRTMIN, &sinfo, NULL);
  510. + break;
  511. + }
  512. +
  513. + for(list_p = context->u.po.complete; list_p; list_p = list_p->next){
  514. + struct aio_fdsync_posix_waiting *w = list_p->data;
  515. + struct aio_fdsync_result *res;
  516. + res = g_malloc(sizeof(struct aio_fdsync_result));
  517. +
  518. + res->fd = w->aiocbv.aio_fildes;
  519. + res->data = w->data;
  520. + if((errno = aio_error(&w->aiocbv)) != 0){
  521. + if(errno < 0){
  522. + g_error("negative errno");
  523. + }
  524. + res->res = -errno;
  525. + }else{
  526. + res->res = 0;
  527. + }
  528. + aio_return(&w->aiocbv);
  529. +
  530. + *finished = g_list_prepend(*finished, res);
  531. +
  532. + context->u.po.waitings = g_list_delete_link(
  533. + context->u.po.waitings,
  534. + w->list_ent
  535. + );
  536. +
  537. + g_free(w);
  538. + }
  539. + g_list_free(context->u.po.complete);
  540. + context->u.po.complete = NULL;
  541. +
  542. + if(sigprocmask(SIG_UNBLOCK, &context->u.po.sigset_m, NULL) < 0){
  543. + g_error("sigprocmask: %s", g_strerror(errno));
  544. + }
  545. +
  546. + return 1;
  547. +}
  548. +static int free_aio_posix(
  549. + struct aio_fdsync_context *context, GList **fds, GError **error
  550. +){
  551. + GList *list_p;
  552. + if(sigprocmask(SIG_BLOCK, &context->u.po.sigset_m, NULL) < 0){
  553. + g_error("sigprocmask: %s", g_strerror(errno));
  554. + }
  555. +
  556. + for(list_p = context->u.po.waitings; list_p; list_p = list_p->next){
  557. + struct aio_fdsync_posix_waiting *w = list_p->data;
  558. + aio_cancel(w->aiocbv.aio_fildes, NULL);
  559. + }
  560. +
  561. + while(context->u.po.waitings){
  562. + siginfo_t sinfo;
  563. + for(
  564. + list_p = context->u.po.complete; list_p;
  565. + list_p = list_p->next
  566. + ){
  567. + struct aio_fdsync_posix_waiting *w = list_p->data;
  568. +
  569. + if(aio_error(&w->aiocbv) == EINPROGRESS){
  570. + continue;
  571. + }
  572. + aio_return(&w->aiocbv);
  573. + if(fds){
  574. + *fds = g_list_prepend(*fds,
  575. + GINT_TO_POINTER(w->aiocbv.aio_fildes));
  576. + }
  577. + context->u.po.waitings = g_list_delete_link(
  578. + context->u.po.waitings,
  579. + w->list_ent
  580. + );
  581. + g_free(w);
  582. + }
  583. + g_list_free(context->u.po.complete);
  584. + context->u.po.complete = NULL;
  585. +
  586. + while(sigwaitinfo(&context->u.po.sigset_m, &sinfo) < 0);
  587. + sigaction_aio_posix(SIGRTMIN, &sinfo, NULL);
  588. + }
  589. +
  590. + sigaction(SIGRTMIN, &context->u.po.oldact, NULL);
  591. + if(sigprocmask(SIG_UNBLOCK, &context->u.po.sigset_m, NULL) < 0){
  592. + g_error("sigprocmask: %s", g_strerror(errno));
  593. + }
  594. +
  595. + return 1;
  596. +}
  597. +#endif /* USE_POSIX_AIO_FDSYNC */
  598. +
  599. +#endif /* HAVE_FDATASYNC */
  600. +
  601. +static gboolean finish_atomic_update(GError **error){
  602. + gboolean ret = FALSE;
  603. + GHashTableIter it;
  604. + gpointer k, v;
  605. +
  606. +#ifdef USE_LINUX_AIO_FDSYNC
  607. + {
  608. + struct aio_fdsync_context ctx;
  609. + ctx.init_aio = init_aio_linux;
  610. + ctx.request_aio = request_aio_linux;
  611. + ctx.wait_aio = wait_aio_linux;
  612. + ctx.free_aio = free_aio_linux;
  613. + if(!aio_do_atomic_update(&ctx, error)){
  614. + goto out;
  615. + }
  616. + }
  617. +#endif
  618. +
  619. +#ifdef USE_POSIX_AIO_FDSYNC
  620. + {
  621. + struct aio_fdsync_context ctx;
  622. + ctx.init_aio = init_aio_posix;
  623. + ctx.request_aio = request_aio_posix;
  624. + ctx.wait_aio = wait_aio_posix;
  625. + ctx.free_aio = free_aio_posix;
  626. + if(!aio_do_atomic_update(&ctx, error)){
  627. + goto out;
  628. + }
  629. + }
  630. +#endif
  631. +
  632. + g_hash_table_iter_init(&it, rename_set);
  633. + while(g_hash_table_iter_next(&it, &k, &v)){
  634. + gchar *pathname = (gchar *)k;
  635. +
  636. + if(sync_file(pathname, error)){
  637. + goto out;
  638. + }
  639. +
  640. + if(!rename_new_file(pathname, error)){
  641. + goto out;
  642. + }
  643. + }
  644. +
  645. + ret = TRUE;
  646. +out:
  647. + g_hash_table_remove_all(rename_set);
  648. return ret;
  649. }
  650. @@ -1048,7 +1643,7 @@
  651. if (!save_xml_file(type->output, filename, &local_error))
  652. fatal_gerror(local_error);
  653. - if (!atomic_update(filename, &local_error))
  654. + if (!add_atomic_update(filename, &local_error))
  655. fatal_gerror(local_error);
  656. g_free(filename);
  657. @@ -3731,6 +4326,8 @@
  658. g_free, NULL);
  659. generic_icon_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
  660. g_free, NULL);
  661. + rename_set = g_hash_table_new_full(g_str_hash, g_str_equal,
  662. + g_free, NULL);
  663. scan_source_dir(package_dir);
  664. g_free(package_dir);
  665. @@ -3756,7 +4353,7 @@
  666. write_out_glob(glob_list, globs);
  667. if (!fclose_gerror(globs, error))
  668. goto out;
  669. - if (!atomic_update(globs_path, error))
  670. + if (!add_atomic_update(globs_path, error))
  671. goto out;
  672. g_free(globs_path);
  673. @@ -3770,7 +4367,7 @@
  674. write_out_glob2 (glob_list, globs);
  675. if (!fclose_gerror(globs, error))
  676. goto out;
  677. - if (!atomic_update(globs_path, error))
  678. + if (!add_atomic_update(globs_path, error))
  679. goto out;
  680. g_free(globs_path);
  681. @@ -3797,7 +4394,7 @@
  682. }
  683. if (!fclose_gerror(stream, error))
  684. goto out;
  685. - if (!atomic_update(magic_path, error))
  686. + if (!add_atomic_update(magic_path, error))
  687. goto out;
  688. g_free(magic_path);
  689. }
  690. @@ -3813,7 +4410,7 @@
  691. write_namespaces(stream);
  692. if (!fclose_gerror(stream, error))
  693. goto out;
  694. - if (!atomic_update(ns_path, error))
  695. + if (!add_atomic_update(ns_path, error))
  696. goto out;
  697. g_free(ns_path);
  698. }
  699. @@ -3829,7 +4426,7 @@
  700. write_subclasses(stream);
  701. if (!fclose_gerror(stream, error))
  702. goto out;
  703. - if (!atomic_update(path, error))
  704. + if (!add_atomic_update(path, error))
  705. goto out;
  706. g_free(path);
  707. }
  708. @@ -3845,7 +4442,7 @@
  709. write_aliases(stream);
  710. if (!fclose_gerror(stream, error))
  711. goto out;
  712. - if (!atomic_update(path, error))
  713. + if (!add_atomic_update(path, error))
  714. goto out;
  715. g_free(path);
  716. }
  717. @@ -3861,7 +4458,7 @@
  718. write_types(stream);
  719. if (!fclose_gerror(stream, error))
  720. goto out;
  721. - if (!atomic_update(path, error))
  722. + if (!add_atomic_update(path, error))
  723. goto out;
  724. g_free(path);
  725. }
  726. @@ -3877,7 +4474,7 @@
  727. write_icons(generic_icon_hash, stream);
  728. if (!fclose_gerror(stream, error))
  729. goto out;
  730. - if (!atomic_update(icon_path, error))
  731. + if (!add_atomic_update(icon_path, error))
  732. goto out;
  733. g_free(icon_path);
  734. }
  735. @@ -3893,7 +4490,7 @@
  736. write_icons(icon_hash, stream);
  737. if (!fclose_gerror(stream, error))
  738. goto out;
  739. - if (!atomic_update(icon_path, error))
  740. + if (!add_atomic_update(icon_path, error))
  741. goto out;
  742. g_free(icon_path);
  743. }
  744. @@ -3918,7 +4515,7 @@
  745. }
  746. if (!fclose_gerror(stream, error))
  747. goto out;
  748. - if (!atomic_update(path, error))
  749. + if (!add_atomic_update(path, error))
  750. goto out;
  751. g_free(path);
  752. }
  753. @@ -3934,7 +4531,7 @@
  754. write_cache(stream);
  755. if (!fclose_gerror(stream, error))
  756. goto out;
  757. - if (!atomic_update(path, error))
  758. + if (!add_atomic_update(path, error))
  759. goto out;
  760. g_free(path);
  761. }
  762. @@ -3951,11 +4548,15 @@
  763. VERSION "\n");
  764. if (!fclose_gerror(stream, error))
  765. goto out;
  766. - if (!atomic_update(path, error))
  767. + if (!add_atomic_update(path, error))
  768. goto out;
  769. g_free(path);
  770. }
  771. + if (!finish_atomic_update(error)){
  772. + goto out;
  773. + }
  774. +
  775. g_ptr_array_foreach(magic_array, (GFunc)magic_free, NULL);
  776. g_ptr_array_free(magic_array, TRUE);
  777. g_ptr_array_foreach(tree_magic_array, (GFunc)tree_magic_free, NULL);
  778. @@ -3968,6 +4569,7 @@
  779. g_hash_table_destroy(alias_hash);
  780. g_hash_table_destroy(icon_hash);
  781. g_hash_table_destroy(generic_icon_hash);
  782. + g_hash_table_destroy(rename_set);
  783. check_in_path_xdg_data(mime_dir);
  784. --- a/configure.ac
  785. +++ b/configure.ac
  786. @@ -20,7 +20,12 @@
  787. AC_SUBST(GETTEXT_PACKAGE)
  788. AM_GLIB_GNU_GETTEXT
  789. -AC_CHECK_FUNCS(fdatasync)
  790. +AC_CHECK_FUNCS(fdatasync syscall aio_fsync io_submit)
  791. +AC_CHECK_DECLS([syscall, sigprocmask, sigwaitinfo], [], [], [
  792. +#include <unistd.h>
  793. +#include <signal.h>
  794. +])
  795. +AC_CHECK_HEADERS(linux/aio_abi.h)
  796. dnl Check for cross compiling
  797. AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
다운로드 Printable view

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text