librats 1.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +43 -0
  73. package/native-src/src/librats/core/types.h +103 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,632 +0,0 @@
1
- #include "disk_io.h"
2
- #include "fs.h"
3
- #include "sha1.h"
4
- #include "logger.h"
5
- #include <algorithm>
6
-
7
- #define LOG_DISK_DEBUG(message) LOG_DEBUG("disk_io", message)
8
- #define LOG_DISK_INFO(message) LOG_INFO("disk_io", message)
9
- #define LOG_DISK_WARN(message) LOG_WARN("disk_io", message)
10
- #define LOG_DISK_ERROR(message) LOG_ERROR("disk_io", message)
11
-
12
- namespace librats {
13
-
14
- //=============================================================================
15
- // DiskIOThreadPool Implementation
16
- //=============================================================================
17
-
18
- DiskIOThreadPool::DiskIOThreadPool(const DiskIOConfig& config)
19
- : config_(config)
20
- , running_(false)
21
- , num_write_threads_(config.num_write_threads)
22
- , num_read_threads_(config.num_read_threads)
23
- , total_bytes_written_(0)
24
- , total_bytes_read_(0)
25
- , jobs_completed_(0)
26
- , under_pressure_(false) {
27
- }
28
-
29
- DiskIOThreadPool::~DiskIOThreadPool() {
30
- stop();
31
- }
32
-
33
- bool DiskIOThreadPool::start() {
34
- if (running_.load()) {
35
- return true;
36
- }
37
-
38
- running_.store(true);
39
-
40
- // Start worker threads
41
- start_write_threads(num_write_threads_.load());
42
- start_read_threads(num_read_threads_.load());
43
-
44
- LOG_DISK_INFO("Disk I/O thread pool started with "
45
- << num_write_threads_.load() << " write threads and "
46
- << num_read_threads_.load() << " read threads");
47
- return true;
48
- }
49
-
50
- void DiskIOThreadPool::stop() {
51
- if (!running_.load()) {
52
- return;
53
- }
54
-
55
- running_.store(false);
56
-
57
- // Wake up all waiting threads
58
- write_cv_.notify_all();
59
- read_cv_.notify_all();
60
-
61
- // Wait for all threads to finish
62
- stop_write_threads();
63
- stop_read_threads();
64
-
65
- LOG_DISK_INFO("Disk I/O thread pool stopped. Total jobs completed: " << jobs_completed_.load());
66
- }
67
-
68
- void DiskIOThreadPool::set_num_write_threads(int count) {
69
- if (count < 1) count = 1;
70
- int old_count = num_write_threads_.exchange(count);
71
-
72
- if (!running_.load()) return;
73
-
74
- if (count > old_count) {
75
- // Start additional threads
76
- start_write_threads(count - old_count);
77
- }
78
- // Note: Reducing threads happens naturally when threads check the count
79
- }
80
-
81
- void DiskIOThreadPool::set_num_read_threads(int count) {
82
- if (count < 1) count = 1;
83
- int old_count = num_read_threads_.exchange(count);
84
-
85
- if (!running_.load()) return;
86
-
87
- if (count > old_count) {
88
- // Start additional threads
89
- start_read_threads(count - old_count);
90
- }
91
- }
92
-
93
- void DiskIOThreadPool::start_write_threads(int count) {
94
- std::lock_guard<std::mutex> lock(write_mutex_);
95
- for (int i = 0; i < count; ++i) {
96
- write_threads_.emplace_back(&DiskIOThreadPool::write_worker_loop, this);
97
- }
98
- }
99
-
100
- void DiskIOThreadPool::start_read_threads(int count) {
101
- std::lock_guard<std::mutex> lock(read_mutex_);
102
- for (int i = 0; i < count; ++i) {
103
- read_threads_.emplace_back(&DiskIOThreadPool::read_worker_loop, this);
104
- }
105
- }
106
-
107
- void DiskIOThreadPool::stop_write_threads() {
108
- for (auto& t : write_threads_) {
109
- if (t.joinable()) {
110
- t.join();
111
- }
112
- }
113
- write_threads_.clear();
114
- }
115
-
116
- void DiskIOThreadPool::stop_read_threads() {
117
- for (auto& t : read_threads_) {
118
- if (t.joinable()) {
119
- t.join();
120
- }
121
- }
122
- read_threads_.clear();
123
- }
124
-
125
- //=============================================================================
126
- // Async Job Submission
127
- //=============================================================================
128
-
129
- void DiskIOThreadPool::async_write_block(
130
- const std::string& download_path,
131
- const std::vector<FileMappingInfo>& files,
132
- uint32_t piece_index,
133
- uint32_t piece_length_standard,
134
- uint32_t block_offset,
135
- const std::vector<uint8_t>& data,
136
- WriteCompleteCallback callback,
137
- DiskJobPriority priority)
138
- {
139
- DiskJob job;
140
- job.type = DiskJobType::WRITE_BLOCK;
141
- job.priority = priority;
142
- job.piece_index = piece_index;
143
- job.offset = block_offset;
144
- job.download_path = download_path;
145
- job.data = data; // Copy the data
146
- job.piece_length = piece_length_standard;
147
- job.piece_offset_in_torrent = static_cast<uint64_t>(piece_index) * piece_length_standard;
148
- job.write_callback = callback;
149
- job.file_mappings = files;
150
-
151
- {
152
- std::lock_guard<std::mutex> lock(write_mutex_);
153
- write_queue_.push(std::move(job));
154
- }
155
- write_cv_.notify_one();
156
-
157
- LOG_DISK_DEBUG("Queued write block: piece " << piece_index << " offset " << block_offset
158
- << " size " << data.size());
159
- }
160
-
161
- void DiskIOThreadPool::async_read_piece(
162
- const std::string& download_path,
163
- const std::vector<FileMappingInfo>& files,
164
- uint32_t piece_index,
165
- uint32_t piece_length_standard,
166
- uint32_t actual_piece_length,
167
- ReadCompleteCallback callback,
168
- DiskJobPriority priority)
169
- {
170
- DiskJob job;
171
- job.type = DiskJobType::READ_PIECE;
172
- job.priority = priority;
173
- job.piece_index = piece_index;
174
- job.download_path = download_path;
175
- job.piece_length = actual_piece_length;
176
- job.piece_offset_in_torrent = static_cast<uint64_t>(piece_index) * piece_length_standard;
177
- job.read_callback = callback;
178
- job.file_mappings = files;
179
-
180
- {
181
- std::lock_guard<std::mutex> lock(read_mutex_);
182
- read_queue_.push(std::move(job));
183
- }
184
- read_cv_.notify_one();
185
-
186
- LOG_DISK_DEBUG("Queued read piece: piece " << piece_index << " length " << actual_piece_length);
187
- }
188
-
189
- void DiskIOThreadPool::async_hash_piece(
190
- const std::string& download_path,
191
- const std::vector<FileMappingInfo>& files,
192
- uint32_t piece_index,
193
- uint32_t piece_length_standard,
194
- uint32_t actual_piece_length,
195
- HashCompleteCallback callback,
196
- DiskJobPriority priority)
197
- {
198
- DiskJob job;
199
- job.type = DiskJobType::HASH_PIECE;
200
- job.priority = priority;
201
- job.piece_index = piece_index;
202
- job.download_path = download_path;
203
- job.piece_length = actual_piece_length;
204
- job.piece_offset_in_torrent = static_cast<uint64_t>(piece_index) * piece_length_standard;
205
- job.hash_callback = callback;
206
- job.file_mappings = files;
207
-
208
- {
209
- std::lock_guard<std::mutex> lock(read_mutex_);
210
- read_queue_.push(std::move(job));
211
- }
212
- read_cv_.notify_one();
213
-
214
- LOG_DISK_DEBUG("Queued hash piece: piece " << piece_index << " length " << actual_piece_length);
215
- }
216
-
217
- void DiskIOThreadPool::async_flush(FlushCompleteCallback callback) {
218
- // Flush goes to write queue with high priority
219
- DiskJob job;
220
- job.type = DiskJobType::FLUSH;
221
- job.priority = DiskJobPriority::HIGH;
222
- job.flush_callback = callback;
223
-
224
- {
225
- std::lock_guard<std::mutex> lock(write_mutex_);
226
- write_queue_.push(std::move(job));
227
- }
228
- write_cv_.notify_one();
229
-
230
- LOG_DISK_DEBUG("Queued flush operation");
231
- }
232
-
233
- //=============================================================================
234
- // Statistics
235
- //=============================================================================
236
-
237
- size_t DiskIOThreadPool::get_pending_write_jobs() const {
238
- std::lock_guard<std::mutex> lock(write_mutex_);
239
- return write_queue_.size();
240
- }
241
-
242
- size_t DiskIOThreadPool::get_pending_read_jobs() const {
243
- std::lock_guard<std::mutex> lock(read_mutex_);
244
- return read_queue_.size();
245
- }
246
-
247
- size_t DiskIOThreadPool::get_total_pending_jobs() const {
248
- return get_pending_write_jobs() + get_pending_read_jobs();
249
- }
250
-
251
- //=============================================================================
252
- // Backpressure Control
253
- //=============================================================================
254
-
255
- bool DiskIOThreadPool::can_accept_write() const {
256
- size_t pending = get_pending_write_jobs();
257
- size_t high_mark = static_cast<size_t>(config_.max_pending_jobs * config_.high_watermark_percent / 100);
258
- size_t low_mark = static_cast<size_t>(config_.max_pending_jobs * config_.low_watermark_percent / 100);
259
-
260
- // Hysteresis: once under pressure, stay under pressure until below low watermark
261
- if (under_pressure_.load()) {
262
- if (pending <= low_mark) {
263
- under_pressure_.store(false);
264
- LOG_DISK_DEBUG("Disk I/O backpressure released, pending jobs: " << pending);
265
- return true;
266
- }
267
- return false;
268
- } else {
269
- if (pending >= high_mark) {
270
- under_pressure_.store(true);
271
- LOG_DISK_DEBUG("Disk I/O under backpressure, pending jobs: " << pending);
272
- return false;
273
- }
274
- return true;
275
- }
276
- }
277
-
278
- //=============================================================================
279
- // Worker Loops
280
- //=============================================================================
281
-
282
- void DiskIOThreadPool::write_worker_loop() {
283
- LOG_DISK_DEBUG("Write worker thread started");
284
-
285
- while (running_.load()) {
286
- DiskJob job;
287
-
288
- {
289
- std::unique_lock<std::mutex> lock(write_mutex_);
290
-
291
- // Wait for a job or shutdown
292
- write_cv_.wait(lock, [this] {
293
- return !write_queue_.empty() || !running_.load();
294
- });
295
-
296
- if (!running_.load() && write_queue_.empty()) {
297
- break;
298
- }
299
-
300
- if (!write_queue_.empty()) {
301
- job = std::move(const_cast<DiskJob&>(write_queue_.top()));
302
- write_queue_.pop();
303
- } else {
304
- continue;
305
- }
306
- }
307
-
308
- // Execute the job outside the lock
309
- switch (job.type) {
310
- case DiskJobType::WRITE_BLOCK:
311
- execute_write_block(job);
312
- break;
313
- case DiskJobType::FLUSH:
314
- execute_flush(job);
315
- break;
316
- default:
317
- LOG_DISK_WARN("Invalid job type in write queue: " << static_cast<int>(job.type));
318
- break;
319
- }
320
-
321
- jobs_completed_++;
322
- }
323
-
324
- LOG_DISK_DEBUG("Write worker thread ended");
325
- }
326
-
327
- void DiskIOThreadPool::read_worker_loop() {
328
- LOG_DISK_DEBUG("Read worker thread started");
329
-
330
- while (running_.load()) {
331
- DiskJob job;
332
-
333
- {
334
- std::unique_lock<std::mutex> lock(read_mutex_);
335
-
336
- // Wait for a job or shutdown
337
- read_cv_.wait(lock, [this] {
338
- return !read_queue_.empty() || !running_.load();
339
- });
340
-
341
- if (!running_.load() && read_queue_.empty()) {
342
- break;
343
- }
344
-
345
- if (!read_queue_.empty()) {
346
- job = std::move(const_cast<DiskJob&>(read_queue_.top()));
347
- read_queue_.pop();
348
- } else {
349
- continue;
350
- }
351
- }
352
-
353
- // Execute the job outside the lock
354
- switch (job.type) {
355
- case DiskJobType::READ_PIECE:
356
- execute_read_piece(job);
357
- break;
358
- case DiskJobType::HASH_PIECE:
359
- execute_hash_piece(job);
360
- break;
361
- default:
362
- LOG_DISK_WARN("Invalid job type in read queue: " << static_cast<int>(job.type));
363
- break;
364
- }
365
-
366
- jobs_completed_++;
367
- }
368
-
369
- LOG_DISK_DEBUG("Read worker thread ended");
370
- }
371
-
372
- //=============================================================================
373
- // File Mapping Helper
374
- //=============================================================================
375
-
376
- std::vector<std::tuple<std::string, uint64_t, size_t>> DiskIOThreadPool::map_to_files(
377
- const std::string& download_path,
378
- const std::vector<FileMappingInfo>& files,
379
- uint64_t torrent_offset,
380
- size_t length)
381
- {
382
- std::vector<std::tuple<std::string, uint64_t, size_t>> result;
383
-
384
- size_t remaining = length;
385
- uint64_t current_offset = torrent_offset;
386
-
387
- for (const auto& file : files) {
388
- if (remaining == 0) break;
389
-
390
- uint64_t file_end = file.torrent_offset + file.length;
391
-
392
- // Check if we've passed this file entirely
393
- if (current_offset >= file_end) {
394
- continue;
395
- }
396
-
397
- // Check if we haven't reached this file yet
398
- if (current_offset + remaining <= file.torrent_offset) {
399
- break;
400
- }
401
-
402
- // Calculate overlap with this file
403
- uint64_t read_start_in_torrent = (std::max)(current_offset, file.torrent_offset);
404
- uint64_t read_end_in_torrent = (std::min)(current_offset + remaining, file_end);
405
- size_t read_length = static_cast<size_t>(read_end_in_torrent - read_start_in_torrent);
406
-
407
- if (read_length == 0) continue;
408
-
409
- // Calculate file offset
410
- uint64_t file_offset = read_start_in_torrent - file.torrent_offset;
411
-
412
- // Construct full file path
413
- std::string file_path = download_path + "/" + file.path;
414
-
415
- result.emplace_back(file_path, file_offset, read_length);
416
-
417
- // Advance
418
- current_offset = read_end_in_torrent;
419
- remaining -= read_length;
420
- }
421
-
422
- return result;
423
- }
424
-
425
- //=============================================================================
426
- // Job Execution
427
- //=============================================================================
428
-
429
- void DiskIOThreadPool::execute_write_block(const DiskJob& job) {
430
- bool success = true;
431
-
432
- // Calculate absolute torrent offset for this block
433
- uint64_t torrent_offset = static_cast<uint64_t>(job.piece_offset_in_torrent) + job.offset;
434
-
435
- // Map to file(s) using the complete file mapping info
436
- auto mappings = map_to_files(job.download_path, job.file_mappings, torrent_offset, job.data.size());
437
-
438
- size_t data_offset = 0;
439
- for (const auto& [file_path, file_offset, write_length] : mappings) {
440
- if (!write_file_chunk(file_path.c_str(), file_offset,
441
- job.data.data() + data_offset, write_length)) {
442
- LOG_DISK_ERROR("Failed to write block to file: " << file_path);
443
- success = false;
444
- break;
445
- }
446
- data_offset += write_length;
447
- }
448
-
449
- if (success) {
450
- total_bytes_written_ += job.data.size();
451
- LOG_DISK_DEBUG("Write complete: piece " << job.piece_index << " offset " << job.offset);
452
- }
453
-
454
- if (job.write_callback) {
455
- job.write_callback(success);
456
- }
457
- }
458
-
459
- void DiskIOThreadPool::execute_read_piece(const DiskJob& job) {
460
- std::vector<uint8_t> data(job.piece_length);
461
- bool success = true;
462
-
463
- // Calculate absolute torrent offset for this piece
464
- uint64_t torrent_offset = job.piece_offset_in_torrent;
465
-
466
- // Map to file(s) using the complete file mapping info
467
- auto mappings = map_to_files(job.download_path, job.file_mappings, torrent_offset, job.piece_length);
468
-
469
- size_t data_offset = 0;
470
- for (const auto& [file_path, file_offset, read_length] : mappings) {
471
- if (!read_file_chunk(file_path.c_str(), file_offset,
472
- data.data() + data_offset, read_length)) {
473
- LOG_DISK_ERROR("Failed to read piece from file: " << file_path);
474
- success = false;
475
- break;
476
- }
477
- data_offset += read_length;
478
- }
479
-
480
- if (success) {
481
- total_bytes_read_ += job.piece_length;
482
- LOG_DISK_DEBUG("Read complete: piece " << job.piece_index);
483
- }
484
-
485
- if (job.read_callback) {
486
- job.read_callback(success, success ? data : std::vector<uint8_t>());
487
- }
488
- }
489
-
490
- void DiskIOThreadPool::execute_hash_piece(const DiskJob& job) {
491
- std::vector<uint8_t> data(job.piece_length);
492
- bool success = true;
493
-
494
- // Calculate absolute torrent offset for this piece
495
- uint64_t torrent_offset = job.piece_offset_in_torrent;
496
-
497
- // Map to file(s) using the complete file mapping info
498
- auto mappings = map_to_files(job.download_path, job.file_mappings, torrent_offset, job.piece_length);
499
-
500
- size_t data_offset = 0;
501
- for (const auto& [file_path, file_offset, read_length] : mappings) {
502
- if (!read_file_chunk(file_path.c_str(), file_offset,
503
- data.data() + data_offset, read_length)) {
504
- LOG_DISK_ERROR("Failed to read piece for hashing from file: " << file_path);
505
- success = false;
506
- break;
507
- }
508
- data_offset += read_length;
509
- }
510
-
511
- std::string hash;
512
- if (success) {
513
- // Calculate SHA1 hash
514
- hash = SHA1::hash_bytes(data);
515
- total_bytes_read_ += job.piece_length;
516
- LOG_DISK_DEBUG("Hash complete: piece " << job.piece_index << " hash " << hash.substr(0, 8) << "...");
517
- }
518
-
519
- if (job.hash_callback) {
520
- job.hash_callback(success, hash);
521
- }
522
- }
523
-
524
- void DiskIOThreadPool::execute_flush(const DiskJob& job) {
525
- // On most systems, writes are already flushed when write_file_chunk returns
526
- // For additional safety, we could call fsync() here, but it's costly
527
-
528
- LOG_DISK_DEBUG("Flush complete");
529
-
530
- if (job.flush_callback) {
531
- job.flush_callback(true);
532
- }
533
- }
534
-
535
- //=============================================================================
536
- // Legacy DiskIOThread Implementation (wrapper around DiskIOThreadPool)
537
- //=============================================================================
538
-
539
- DiskIOThread::DiskIOThread()
540
- : pool_(std::make_unique<DiskIOThreadPool>()) {
541
- }
542
-
543
- DiskIOThread::~DiskIOThread() {
544
- stop();
545
- }
546
-
547
- bool DiskIOThread::start() {
548
- return pool_->start();
549
- }
550
-
551
- void DiskIOThread::stop() {
552
- pool_->stop();
553
- }
554
-
555
- bool DiskIOThread::is_running() const {
556
- return pool_->is_running();
557
- }
558
-
559
- void DiskIOThread::async_write_block(
560
- const std::string& download_path,
561
- const std::vector<FileMappingInfo>& files,
562
- uint32_t piece_index,
563
- uint32_t piece_length_standard,
564
- uint32_t block_offset,
565
- const std::vector<uint8_t>& data,
566
- WriteCompleteCallback callback)
567
- {
568
- pool_->async_write_block(download_path, files, piece_index, piece_length_standard,
569
- block_offset, data, callback);
570
- }
571
-
572
- void DiskIOThread::async_read_piece(
573
- const std::string& download_path,
574
- const std::vector<FileMappingInfo>& files,
575
- uint32_t piece_index,
576
- uint32_t piece_length_standard,
577
- uint32_t actual_piece_length,
578
- ReadCompleteCallback callback)
579
- {
580
- pool_->async_read_piece(download_path, files, piece_index, piece_length_standard,
581
- actual_piece_length, callback);
582
- }
583
-
584
- void DiskIOThread::async_hash_piece(
585
- const std::string& download_path,
586
- const std::vector<FileMappingInfo>& files,
587
- uint32_t piece_index,
588
- uint32_t piece_length_standard,
589
- uint32_t actual_piece_length,
590
- HashCompleteCallback callback)
591
- {
592
- pool_->async_hash_piece(download_path, files, piece_index, piece_length_standard,
593
- actual_piece_length, callback);
594
- }
595
-
596
- void DiskIOThread::async_flush(FlushCompleteCallback callback) {
597
- pool_->async_flush(callback);
598
- }
599
-
600
- size_t DiskIOThread::get_pending_jobs() const {
601
- return pool_->get_total_pending_jobs();
602
- }
603
-
604
- uint64_t DiskIOThread::get_total_bytes_written() const {
605
- return pool_->get_total_bytes_written();
606
- }
607
-
608
- uint64_t DiskIOThread::get_total_bytes_read() const {
609
- return pool_->get_total_bytes_read();
610
- }
611
-
612
- //=============================================================================
613
- // DiskIO Singleton Implementation
614
- //=============================================================================
615
-
616
- std::unique_ptr<DiskIOThreadPool> DiskIO::instance_;
617
- std::once_flag DiskIO::init_flag_;
618
- DiskIOConfig DiskIO::config_;
619
-
620
- void DiskIO::configure(const DiskIOConfig& config) {
621
- config_ = config;
622
- }
623
-
624
- DiskIOThreadPool& DiskIO::instance() {
625
- std::call_once(init_flag_, []() {
626
- instance_ = std::make_unique<DiskIOThreadPool>(config_);
627
- instance_->start();
628
- });
629
- return *instance_;
630
- }
631
-
632
- } // namespace librats