Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
dyknon's paste: update-mime-database.cのfdatasync呼び出しによる処理時間の問題の対処(for linux) (#6240) - OSDN
[go: Go Back, main page]

Pastebin: update-mime-database.cのfdatasync呼び出しによる処理時間の問題の対処(for linux)

amd64以外ではテストしてない

Format
Diff
Post date
2020-03-11 05:43
Publication Period
Unlimited
  1. --- a/update-mime-database.c
  2. +++ b/update-mime-database.c
  3. @@ -1,3 +1,5 @@
  4. +#define _GNU_SOURCE
  5. +
  6. #include <config.h>
  7. #define N_(x) x
  8. @@ -37,6 +39,15 @@
  9. #define NOGLOBS "__NOGLOBS__"
  10. #define NOMAGIC "__NOMAGIC__"
  11. +#ifdef __linux__
  12. +# include <linux/version.h>
  13. +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
  14. +# include <linux/aio_abi.h>
  15. +# include <sys/syscall.h>
  16. +# include <sys/eventfd.h>
  17. +# endif
  18. +#endif
  19. +
  20. #ifndef PATH_SEPARATOR
  21. # ifdef _WIN32
  22. # define PATH_SEPARATOR ";"
  23. @@ -168,12 +179,31 @@
  24. /* Lists enabled log levels */
  25. static GLogLevelFlags enabled_log_levels = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING;
  26. +static GList *rename_list = NULL;
  27. +
  28. /* Static prototypes */
  29. static Magic *magic_new(xmlNode *node, Type *type, GError **error);
  30. static Match *match_new(void);
  31. static TreeMagic *tree_magic_new(xmlNode *node, Type *type, GError **error);
  32. +#ifdef __LINUX__AIO_ABI_H
  33. +static int io_setup(unsigned nr_events, aio_context_t *ctx_idp){
  34. + return syscall(SYS_io_setup, nr_events, ctx_idp);
  35. +}
  36. +static int io_submit(aio_context_t ctx_id, long nr, struct iocb **iocbpp){
  37. + return syscall(SYS_io_submit, ctx_id, nr, iocbpp);
  38. +}
  39. +static int io_getevents(aio_context_t ctx_id, long min_nr, long nr,
  40. + struct io_event *events, struct timespec *timeout
  41. +){
  42. + return syscall(SYS_io_getevents, ctx_id, min_nr, nr, events, timeout);
  43. +}
  44. +static int io_destroy(aio_context_t ctx_id){
  45. + return syscall(SYS_io_destroy, ctx_id);
  46. +}
  47. +#endif
  48. +
  49. static void g_log_handler (const gchar *log_domain,
  50. GLogLevelFlags log_level,
  51. const gchar *message,
  52. @@ -986,38 +1016,181 @@
  53. return 0;
  54. }
  55. -/* Renames pathname by removing the .new extension */
  56. -static gboolean atomic_update(const gchar *pathname, GError **error)
  57. +static gboolean add_atomic_update(const gchar *pathname, GError **error)
  58. {
  59. - gboolean ret = FALSE;
  60. - gchar *new_name = NULL;
  61. int len;
  62. len = strlen(pathname);
  63. -
  64. + g_return_val_if_fail(len > 4, FALSE);
  65. g_return_val_if_fail(strcmp(pathname + len - 4, ".new") == 0, FALSE);
  66. - new_name = g_strndup(pathname, len - 4);
  67. + rename_list = g_list_prepend(rename_list, g_strdup(pathname));
  68. - if (sync_file(pathname, error) == -1)
  69. - goto out;
  70. + return TRUE;
  71. +}
  72. +
  73. +static gboolean finish_atomic_update(GError **error){
  74. + gboolean ret = FALSE;
  75. + GList *listp;
  76. + gchar *new_name = NULL;
  77. +
  78. +#ifdef __LINUX__AIO_ABI_H
  79. + {
  80. + guint fsync_cnt = g_list_length(rename_list);
  81. + unsigned aio_max_cnt = fsync_cnt;
  82. + aio_context_t aio_context = 0;
  83. + struct iocb *iocb_array = NULL;
  84. + struct io_event *io_event_array = NULL;
  85. + guint aio_submited = 0;
  86. + unsigned aio_waiting = 0;
  87. + int evfd = -1;
  88. + int i;
  89. +
  90. + if(!sync_enabled() || fsync_cnt <= 1){
  91. + goto noaio;
  92. + }
  93. +
  94. + // try to setup aio
  95. + while(io_setup(aio_max_cnt, &aio_context)){
  96. + if(errno == EAGAIN){
  97. + aio_max_cnt = (aio_max_cnt + 1) / 2;
  98. + if(aio_max_cnt <= 1){
  99. + goto noaio;
  100. + }
  101. + }else{
  102. + goto noaio;
  103. + }
  104. + }
  105. +
  106. + if((evfd = eventfd(0, 0)) < 0){
  107. + goto exit_aio;
  108. + }
  109. +
  110. + iocb_array = g_malloc0(sizeof(struct iocb) * fsync_cnt);
  111. + io_event_array
  112. + = g_malloc(sizeof(struct io_event) * aio_max_cnt);
  113. +
  114. + // do fdatasync using aio abi
  115. + for(listp = rename_list; listp; listp = listp->next){
  116. + gchar *pathname = listp->data;
  117. + struct iocb *iocbp;
  118. + int fd;
  119. +
  120. + while(aio_waiting >= aio_max_cnt){
  121. + int fin_cnt;
  122. + fin_cnt = io_getevents(aio_context,
  123. + 1, aio_max_cnt, io_event_array, NULL);
  124. + if(fin_cnt < 0){
  125. + if(errno == EINTR){
  126. + continue;
  127. + }
  128. + goto exit_aio;
  129. + }
  130. + for(i = 0; i < fin_cnt; i++){
  131. + __u32 finfd = iocb_array[
  132. + io_event_array[i].data
  133. + ].aio_fildes;
  134. + close(finfd);
  135. + iocb_array[io_event_array[i].data]
  136. + .aio_data = -1;
  137. + }
  138. + aio_waiting -= fin_cnt;
  139. + }
  140. +
  141. + if((fd = open(pathname, O_RDWR)) < 0){
  142. + continue;
  143. + }
  144. +
  145. + iocbp = &iocb_array[aio_submited];
  146. + iocbp->aio_data = aio_submited;
  147. + //iocbp->aio_rw_flags = 0;
  148. + iocbp->aio_lio_opcode = IOCB_CMD_FDSYNC;
  149. + //iocbp->aio_reqprio = 0;
  150. + iocbp->aio_fildes = fd;
  151. + //iocbp->aio_buf = 0;
  152. + //iocbp->aio_nbytes = 0;
  153. + //iocbp->aio_offset = 0;
  154. + //iocbp->aio_flags = 0;
  155. + iocbp->aio_resfd = evfd;
  156. +
  157. + if(io_submit(aio_context, (long)1, &iocbp) != 1){
  158. + close(fd);
  159. + continue;
  160. + }
  161. +
  162. + aio_waiting++;
  163. + aio_submited++;
  164. + }
  165. +
  166. + while(aio_waiting > 0){
  167. + int fin_cnt;
  168. + fin_cnt = io_getevents(aio_context,
  169. + aio_waiting, aio_max_cnt, io_event_array, NULL);
  170. + if(fin_cnt < 0){
  171. + if(errno == EINTR){
  172. + continue;
  173. + }
  174. + goto exit_aio;
  175. + }
  176. + aio_waiting -= fin_cnt;
  177. + }
  178. +
  179. +exit_aio:
  180. + io_destroy(aio_context);
  181. + if(evfd >= 0){
  182. + close(evfd);
  183. + }
  184. + for(i = 0; i < aio_submited; i++){
  185. + struct iocb *iocbp = &iocb_array[i];
  186. + if(iocbp->aio_data != (__u64)-1){
  187. + close(iocbp->aio_fildes);
  188. + }
  189. + }
  190. +
  191. +noaio:
  192. + g_free(iocb_array);
  193. + g_free(io_event_array);
  194. + }
  195. +#endif
  196. +
  197. + for(listp = g_list_last(rename_list); listp; listp = listp->prev){
  198. + int len;
  199. + gchar *pathname = listp->data;
  200. +
  201. + len = strlen(pathname);
  202. + g_return_val_if_fail(len > 4, FALSE);
  203. + g_return_val_if_fail(
  204. + strcmp(pathname + len - 4, ".new") == 0, FALSE);
  205. +
  206. + new_name = g_strndup(pathname, len - 4);
  207. +
  208. + if (sync_file(pathname, error) == -1)
  209. + goto out;
  210. #ifdef _WIN32
  211. - /* we need to remove the old file first! */
  212. - remove(new_name);
  213. + /* we need to remove the old file first! */
  214. + remove(new_name);
  215. #endif
  216. - if (rename(pathname, new_name) == -1)
  217. - {
  218. - int errsv = errno;
  219. - g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errsv),
  220. - "Failed to rename %s as %s: %s", pathname, new_name,
  221. - g_strerror(errsv));
  222. - goto out;
  223. +
  224. + if (rename(pathname, new_name) == -1)
  225. + {
  226. + int errsv = errno;
  227. + g_set_error(error, G_FILE_ERROR,
  228. + g_file_error_from_errno(errsv),
  229. + "Failed to rename %s as %s: %s",
  230. + pathname, new_name, g_strerror(errsv));
  231. + goto out;
  232. + }
  233. +
  234. + g_free(new_name);
  235. + new_name = NULL;
  236. }
  237. ret = TRUE;
  238. out:
  239. g_free(new_name);
  240. + g_list_free_full(rename_list, g_free);
  241. + rename_list = NULL;
  242. return ret;
  243. }
  244. @@ -1048,7 +1221,7 @@
  245. if (!save_xml_file(type->output, filename, &local_error))
  246. fatal_gerror(local_error);
  247. - if (!atomic_update(filename, &local_error))
  248. + if (!add_atomic_update(filename, &local_error))
  249. fatal_gerror(local_error);
  250. g_free(filename);
  251. @@ -3756,7 +3929,7 @@
  252. write_out_glob(glob_list, globs);
  253. if (!fclose_gerror(globs, error))
  254. goto out;
  255. - if (!atomic_update(globs_path, error))
  256. + if (!add_atomic_update(globs_path, error))
  257. goto out;
  258. g_free(globs_path);
  259. @@ -3770,7 +3943,7 @@
  260. write_out_glob2 (glob_list, globs);
  261. if (!fclose_gerror(globs, error))
  262. goto out;
  263. - if (!atomic_update(globs_path, error))
  264. + if (!add_atomic_update(globs_path, error))
  265. goto out;
  266. g_free(globs_path);
  267. @@ -3797,7 +3970,7 @@
  268. }
  269. if (!fclose_gerror(stream, error))
  270. goto out;
  271. - if (!atomic_update(magic_path, error))
  272. + if (!add_atomic_update(magic_path, error))
  273. goto out;
  274. g_free(magic_path);
  275. }
  276. @@ -3813,7 +3986,7 @@
  277. write_namespaces(stream);
  278. if (!fclose_gerror(stream, error))
  279. goto out;
  280. - if (!atomic_update(ns_path, error))
  281. + if (!add_atomic_update(ns_path, error))
  282. goto out;
  283. g_free(ns_path);
  284. }
  285. @@ -3829,7 +4002,7 @@
  286. write_subclasses(stream);
  287. if (!fclose_gerror(stream, error))
  288. goto out;
  289. - if (!atomic_update(path, error))
  290. + if (!add_atomic_update(path, error))
  291. goto out;
  292. g_free(path);
  293. }
  294. @@ -3845,7 +4018,7 @@
  295. write_aliases(stream);
  296. if (!fclose_gerror(stream, error))
  297. goto out;
  298. - if (!atomic_update(path, error))
  299. + if (!add_atomic_update(path, error))
  300. goto out;
  301. g_free(path);
  302. }
  303. @@ -3861,7 +4034,7 @@
  304. write_types(stream);
  305. if (!fclose_gerror(stream, error))
  306. goto out;
  307. - if (!atomic_update(path, error))
  308. + if (!add_atomic_update(path, error))
  309. goto out;
  310. g_free(path);
  311. }
  312. @@ -3877,7 +4050,7 @@
  313. write_icons(generic_icon_hash, stream);
  314. if (!fclose_gerror(stream, error))
  315. goto out;
  316. - if (!atomic_update(icon_path, error))
  317. + if (!add_atomic_update(icon_path, error))
  318. goto out;
  319. g_free(icon_path);
  320. }
  321. @@ -3893,7 +4066,7 @@
  322. write_icons(icon_hash, stream);
  323. if (!fclose_gerror(stream, error))
  324. goto out;
  325. - if (!atomic_update(icon_path, error))
  326. + if (!add_atomic_update(icon_path, error))
  327. goto out;
  328. g_free(icon_path);
  329. }
  330. @@ -3918,7 +4091,7 @@
  331. }
  332. if (!fclose_gerror(stream, error))
  333. goto out;
  334. - if (!atomic_update(path, error))
  335. + if (!add_atomic_update(path, error))
  336. goto out;
  337. g_free(path);
  338. }
  339. @@ -3934,7 +4107,7 @@
  340. write_cache(stream);
  341. if (!fclose_gerror(stream, error))
  342. goto out;
  343. - if (!atomic_update(path, error))
  344. + if (!add_atomic_update(path, error))
  345. goto out;
  346. g_free(path);
  347. }
  348. @@ -3951,11 +4124,15 @@
  349. VERSION "\n");
  350. if (!fclose_gerror(stream, error))
  351. goto out;
  352. - if (!atomic_update(path, error))
  353. + if (!add_atomic_update(path, error))
  354. goto out;
  355. g_free(path);
  356. }
  357. + if (!finish_atomic_update(error)){
  358. + goto out;
  359. + }
  360. +
  361. g_ptr_array_foreach(magic_array, (GFunc)magic_free, NULL);
  362. g_ptr_array_free(magic_array, TRUE);
  363. g_ptr_array_foreach(tree_magic_array, (GFunc)tree_magic_free, NULL);
Download Printable view

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text