noderb 0.0.4 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (361) hide show
  1. data/ext/noderb_extension/libuv/AUTHORS +11 -1
  2. data/ext/noderb_extension/libuv/LICENSE +0 -8
  3. data/ext/noderb_extension/libuv/Makefile +5 -5
  4. data/ext/noderb_extension/libuv/README +11 -6
  5. data/ext/noderb_extension/libuv/common.gypi +158 -7
  6. data/ext/noderb_extension/libuv/config-unix.mk +34 -26
  7. data/ext/noderb_extension/libuv/gyp_uv +22 -4
  8. data/ext/noderb_extension/libuv/include/{eio.h → uv-private/eio.h} +2 -2
  9. data/ext/noderb_extension/libuv/include/{uv-unix.h → uv-private/uv-unix.h} +40 -0
  10. data/ext/noderb_extension/libuv/include/{uv-win.h → uv-private/uv-win.h} +96 -14
  11. data/ext/noderb_extension/libuv/include/uv.h +508 -83
  12. data/ext/noderb_extension/libuv/src/unix/cares.c +185 -0
  13. data/ext/noderb_extension/libuv/src/unix/core.c +828 -0
  14. data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config_darwin.h +4 -0
  15. data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config_linux.h +5 -15
  16. data/ext/noderb_extension/libuv/src/{eio → unix/eio}/eio.c +23 -2
  17. data/ext/noderb_extension/libuv/src/unix/error.c +102 -0
  18. data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config_linux.h +26 -15
  19. data/ext/noderb_extension/libuv/src/unix/fs.c +562 -0
  20. data/ext/noderb_extension/libuv/src/unix/internal.h +75 -0
  21. data/ext/noderb_extension/libuv/src/unix/pipe.c +282 -0
  22. data/ext/noderb_extension/libuv/src/unix/process.c +287 -0
  23. data/ext/noderb_extension/libuv/src/unix/stream.c +727 -0
  24. data/ext/noderb_extension/libuv/src/unix/tcp.c +226 -0
  25. data/ext/noderb_extension/libuv/src/unix/udp.c +524 -0
  26. data/ext/noderb_extension/libuv/src/{uv-eio.c → unix/uv-eio.c} +48 -27
  27. data/ext/noderb_extension/libuv/src/{uv-eio.h → unix/uv-eio.h} +1 -1
  28. data/ext/noderb_extension/libuv/src/uv-common.c +24 -14
  29. data/ext/noderb_extension/libuv/src/uv-common.h +12 -7
  30. data/ext/noderb_extension/libuv/src/win/async.c +14 -16
  31. data/ext/noderb_extension/libuv/src/win/cares.c +64 -79
  32. data/ext/noderb_extension/libuv/src/win/core.c +105 -53
  33. data/ext/noderb_extension/libuv/src/win/error.c +23 -13
  34. data/ext/noderb_extension/libuv/src/win/fs.c +807 -0
  35. data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +61 -41
  36. data/ext/noderb_extension/libuv/src/win/handle.c +56 -30
  37. data/ext/noderb_extension/libuv/src/win/internal.h +134 -95
  38. data/ext/noderb_extension/libuv/src/win/loop-watcher.c +21 -18
  39. data/ext/noderb_extension/libuv/src/win/pipe.c +313 -158
  40. data/ext/noderb_extension/libuv/src/win/process.c +117 -131
  41. data/ext/noderb_extension/libuv/src/win/req.c +55 -31
  42. data/ext/noderb_extension/libuv/src/win/stdio.c +5 -5
  43. data/ext/noderb_extension/libuv/src/win/stream.c +19 -14
  44. data/ext/noderb_extension/libuv/src/win/tcp.c +278 -336
  45. data/ext/noderb_extension/libuv/src/win/threadpool.c +73 -0
  46. data/ext/noderb_extension/libuv/src/win/timer.c +44 -37
  47. data/ext/noderb_extension/libuv/src/win/udp.c +592 -0
  48. data/ext/noderb_extension/libuv/src/win/util.c +20 -6
  49. data/ext/noderb_extension/libuv/src/win/winapi.c +23 -6
  50. data/ext/noderb_extension/libuv/src/win/winapi.h +4206 -0
  51. data/ext/noderb_extension/libuv/src/win/winsock.c +270 -0
  52. data/ext/noderb_extension/libuv/src/win/winsock.h +134 -0
  53. data/ext/noderb_extension/libuv/test/benchmark-ares.c +10 -6
  54. data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +10 -7
  55. data/ext/noderb_extension/libuv/test/benchmark-list.h +21 -0
  56. data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +11 -7
  57. data/ext/noderb_extension/libuv/test/benchmark-pound.c +147 -58
  58. data/ext/noderb_extension/libuv/test/benchmark-pump.c +29 -23
  59. data/ext/noderb_extension/libuv/test/benchmark-spawn.c +13 -10
  60. data/ext/noderb_extension/libuv/test/benchmark-udp-packet-storm.c +250 -0
  61. data/ext/noderb_extension/libuv/test/dns-server.c +11 -6
  62. data/ext/noderb_extension/libuv/test/echo-server.c +30 -22
  63. data/ext/noderb_extension/libuv/test/test-async.c +3 -3
  64. data/ext/noderb_extension/libuv/test/test-callback-stack.c +6 -6
  65. data/ext/noderb_extension/libuv/test/test-connection-fail.c +6 -5
  66. data/ext/noderb_extension/libuv/test/test-delayed-accept.c +13 -13
  67. data/ext/noderb_extension/libuv/test/test-fs.c +715 -0
  68. data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +11 -8
  69. data/ext/noderb_extension/libuv/test/test-gethostbyname.c +8 -9
  70. data/ext/noderb_extension/libuv/test/test-getsockname.c +142 -16
  71. data/ext/noderb_extension/libuv/test/test-idle.c +4 -3
  72. data/ext/noderb_extension/libuv/test/test-list.h +29 -2
  73. data/ext/noderb_extension/libuv/test/test-loop-handles.c +9 -8
  74. data/ext/noderb_extension/libuv/test/test-ping-pong.c +9 -9
  75. data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +18 -14
  76. data/ext/noderb_extension/libuv/test/test-ref.c +17 -16
  77. data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +5 -5
  78. data/ext/noderb_extension/libuv/test/test-spawn.c +17 -17
  79. data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +24 -18
  80. data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +19 -14
  81. data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +6 -5
  82. data/ext/noderb_extension/libuv/test/test-threadpool.c +59 -0
  83. data/ext/noderb_extension/libuv/test/test-timer-again.c +15 -12
  84. data/ext/noderb_extension/libuv/test/test-timer.c +8 -8
  85. data/ext/noderb_extension/libuv/test/test-udp-dgram-too-big.c +88 -0
  86. data/ext/noderb_extension/libuv/test/test-udp-ipv6.c +158 -0
  87. data/ext/noderb_extension/libuv/test/test-udp-send-and-recv.c +210 -0
  88. data/ext/noderb_extension/libuv/{all.gyp → uv.gyp} +75 -77
  89. data/ext/noderb_extension/libuv/vcbuild.bat +93 -0
  90. data/ext/noderb_extension/noderb.c +13 -0
  91. data/ext/noderb_extension/noderb_common.h +2 -1
  92. data/ext/noderb_extension/noderb_defer.c +54 -0
  93. data/ext/noderb_extension/noderb_defer.h +15 -0
  94. data/ext/noderb_extension/noderb_dns.c +1 -1
  95. data/ext/noderb_extension/noderb_fs.c +277 -0
  96. data/ext/noderb_extension/noderb_fs.h +27 -0
  97. data/ext/noderb_extension/noderb_process.c +5 -5
  98. data/ext/noderb_extension/noderb_tcp.c +10 -6
  99. data/ext/noderb_extension/noderb_timers.c +1 -1
  100. data/ext/noderb_extension/noderb_tools.c +42 -8
  101. data/ext/noderb_extension/noderb_tools.h +3 -1
  102. data/lib/noderb/defer.rb +25 -0
  103. data/lib/noderb/file.rb +119 -0
  104. data/lib/noderb/fs.rb +72 -0
  105. data/lib/noderb/version.rb +1 -1
  106. data/lib/noderb.rb +8 -0
  107. metadata +102 -266
  108. data/ext/noderb_extension/libuv/BSDmakefile +0 -2
  109. data/ext/noderb_extension/libuv/create-msvs-files.bat +0 -21
  110. data/ext/noderb_extension/libuv/deps/pthread-win32/ANNOUNCE +0 -482
  111. data/ext/noderb_extension/libuv/deps/pthread-win32/BUGS +0 -141
  112. data/ext/noderb_extension/libuv/deps/pthread-win32/Bmakefile +0 -268
  113. data/ext/noderb_extension/libuv/deps/pthread-win32/CONTRIBUTORS +0 -140
  114. data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING +0 -150
  115. data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING.LIB +0 -504
  116. data/ext/noderb_extension/libuv/deps/pthread-win32/ChangeLog +0 -5194
  117. data/ext/noderb_extension/libuv/deps/pthread-win32/FAQ +0 -451
  118. data/ext/noderb_extension/libuv/deps/pthread-win32/GNUmakefile +0 -593
  119. data/ext/noderb_extension/libuv/deps/pthread-win32/MAINTAINERS +0 -4
  120. data/ext/noderb_extension/libuv/deps/pthread-win32/Makefile +0 -516
  121. data/ext/noderb_extension/libuv/deps/pthread-win32/NEWS +0 -1245
  122. data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile +0 -24
  123. data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile.tests +0 -260
  124. data/ext/noderb_extension/libuv/deps/pthread-win32/PROGRESS +0 -4
  125. data/ext/noderb_extension/libuv/deps/pthread-win32/README +0 -601
  126. data/ext/noderb_extension/libuv/deps/pthread-win32/README.Borland +0 -57
  127. data/ext/noderb_extension/libuv/deps/pthread-win32/README.CV +0 -3036
  128. data/ext/noderb_extension/libuv/deps/pthread-win32/README.NONPORTABLE +0 -783
  129. data/ext/noderb_extension/libuv/deps/pthread-win32/README.Watcom +0 -62
  130. data/ext/noderb_extension/libuv/deps/pthread-win32/README.WinCE +0 -6
  131. data/ext/noderb_extension/libuv/deps/pthread-win32/TODO +0 -7
  132. data/ext/noderb_extension/libuv/deps/pthread-win32/WinCE-PORT +0 -222
  133. data/ext/noderb_extension/libuv/deps/pthread-win32/attr.c +0 -53
  134. data/ext/noderb_extension/libuv/deps/pthread-win32/autostatic.c +0 -69
  135. data/ext/noderb_extension/libuv/deps/pthread-win32/barrier.c +0 -47
  136. data/ext/noderb_extension/libuv/deps/pthread-win32/build/all.gyp +0 -207
  137. data/ext/noderb_extension/libuv/deps/pthread-win32/builddmc.bat +0 -9
  138. data/ext/noderb_extension/libuv/deps/pthread-win32/cancel.c +0 -44
  139. data/ext/noderb_extension/libuv/deps/pthread-win32/cleanup.c +0 -148
  140. data/ext/noderb_extension/libuv/deps/pthread-win32/condvar.c +0 -50
  141. data/ext/noderb_extension/libuv/deps/pthread-win32/config.h +0 -153
  142. data/ext/noderb_extension/libuv/deps/pthread-win32/context.h +0 -74
  143. data/ext/noderb_extension/libuv/deps/pthread-win32/create.c +0 -308
  144. data/ext/noderb_extension/libuv/deps/pthread-win32/dll.c +0 -92
  145. data/ext/noderb_extension/libuv/deps/pthread-win32/errno.c +0 -94
  146. data/ext/noderb_extension/libuv/deps/pthread-win32/exit.c +0 -44
  147. data/ext/noderb_extension/libuv/deps/pthread-win32/fork.c +0 -39
  148. data/ext/noderb_extension/libuv/deps/pthread-win32/global.c +0 -107
  149. data/ext/noderb_extension/libuv/deps/pthread-win32/implement.h +0 -944
  150. data/ext/noderb_extension/libuv/deps/pthread-win32/misc.c +0 -50
  151. data/ext/noderb_extension/libuv/deps/pthread-win32/mutex.c +0 -62
  152. data/ext/noderb_extension/libuv/deps/pthread-win32/need_errno.h +0 -145
  153. data/ext/noderb_extension/libuv/deps/pthread-win32/nonportable.c +0 -47
  154. data/ext/noderb_extension/libuv/deps/pthread-win32/private.c +0 -54
  155. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.c +0 -66
  156. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsp +0 -142
  157. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsw +0 -29
  158. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.h +0 -1368
  159. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_destroy.c +0 -79
  160. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getdetachstate.c +0 -86
  161. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getinheritsched.c +0 -51
  162. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedparam.c +0 -52
  163. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedpolicy.c +0 -61
  164. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getscope.c +0 -54
  165. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstackaddr.c +0 -97
  166. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstacksize.c +0 -100
  167. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_init.c +0 -117
  168. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setdetachstate.c +0 -91
  169. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setinheritsched.c +0 -57
  170. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedparam.c +0 -63
  171. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedpolicy.c +0 -55
  172. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setscope.c +0 -62
  173. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstackaddr.c +0 -97
  174. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstacksize.c +0 -110
  175. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_destroy.c +0 -103
  176. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_init.c +0 -69
  177. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_wait.c +0 -104
  178. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_destroy.c +0 -83
  179. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_getpshared.c +0 -95
  180. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_init.c +0 -85
  181. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_setpshared.c +0 -119
  182. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cancel.c +0 -189
  183. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_destroy.c +0 -253
  184. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_init.c +0 -167
  185. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_signal.c +0 -231
  186. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_wait.c +0 -567
  187. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_destroy.c +0 -86
  188. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_getpshared.c +0 -97
  189. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_init.c +0 -87
  190. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_setpshared.c +0 -117
  191. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_delay_np.c +0 -172
  192. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_detach.c +0 -136
  193. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_equal.c +0 -76
  194. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_exit.c +0 -106
  195. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getconcurrency.c +0 -45
  196. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getschedparam.c +0 -75
  197. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getspecific.c +0 -87
  198. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getunique_np.c +0 -47
  199. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getw32threadhandle_np.c +0 -65
  200. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_join.c +0 -157
  201. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_create.c +0 -108
  202. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_delete.c +0 -125
  203. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_kill.c +0 -105
  204. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_consistent.c +0 -187
  205. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_destroy.c +0 -148
  206. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_init.c +0 -130
  207. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_lock.c +0 -269
  208. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_timedlock.c +0 -324
  209. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_trylock.c +0 -154
  210. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_unlock.c +0 -175
  211. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_destroy.c +0 -83
  212. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getkind_np.c +0 -44
  213. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getpshared.c +0 -95
  214. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getrobust.c +0 -113
  215. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_gettype.c +0 -56
  216. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_init.c +0 -86
  217. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setkind_np.c +0 -44
  218. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setpshared.c +0 -119
  219. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setrobust.c +0 -119
  220. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_settype.c +0 -143
  221. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_num_processors_np.c +0 -56
  222. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_once.c +0 -79
  223. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_destroy.c +0 -143
  224. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_init.c +0 -109
  225. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_rdlock.c +0 -102
  226. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedrdlock.c +0 -109
  227. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedwrlock.c +0 -139
  228. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_tryrdlock.c +0 -102
  229. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_trywrlock.c +0 -122
  230. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_unlock.c +0 -93
  231. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_wrlock.c +0 -133
  232. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_destroy.c +0 -84
  233. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_getpshared.c +0 -97
  234. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_init.c +0 -83
  235. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_setpshared.c +0 -120
  236. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_self.c +0 -141
  237. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcancelstate.c +0 -125
  238. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcanceltype.c +0 -126
  239. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setconcurrency.c +0 -53
  240. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setschedparam.c +0 -123
  241. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setspecific.c +0 -167
  242. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_destroy.c +0 -111
  243. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_init.c +0 -123
  244. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_lock.c +0 -80
  245. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_trylock.c +0 -77
  246. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_unlock.c +0 -71
  247. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_testcancel.c +0 -103
  248. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_timechange_handler_np.c +0 -108
  249. data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_win32_attach_detach_np.c +0 -258
  250. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_MCS_lock.c +0 -278
  251. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_callUserDestroyRoutines.c +0 -232
  252. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_calloc.c +0 -56
  253. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_cond_check_need_init.c +0 -78
  254. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_getprocessors.c +0 -91
  255. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_is_attr.c +0 -47
  256. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_mutex_check_need_init.c +0 -92
  257. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_new.c +0 -94
  258. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processInitialize.c +0 -92
  259. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processTerminate.c +0 -105
  260. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_relmillisecs.c +0 -132
  261. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_reuse.c +0 -151
  262. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_cancelwrwait.c +0 -50
  263. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_check_need_init.c +0 -77
  264. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_semwait.c +0 -135
  265. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_spinlock_check_need_init.c +0 -78
  266. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadDestroy.c +0 -79
  267. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadStart.c +0 -357
  268. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_throw.c +0 -189
  269. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_timespec.c +0 -83
  270. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocCreate.c +0 -118
  271. data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocDestroy.c +0 -114
  272. data/ext/noderb_extension/libuv/deps/pthread-win32/rwlock.c +0 -51
  273. data/ext/noderb_extension/libuv/deps/pthread-win32/sched.c +0 -53
  274. data/ext/noderb_extension/libuv/deps/pthread-win32/sched.h +0 -183
  275. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_max.c +0 -134
  276. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_min.c +0 -135
  277. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_getscheduler.c +0 -71
  278. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_setscheduler.c +0 -83
  279. data/ext/noderb_extension/libuv/deps/pthread-win32/sched_yield.c +0 -71
  280. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_close.c +0 -58
  281. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_destroy.c +0 -144
  282. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_getvalue.c +0 -110
  283. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_init.c +0 -169
  284. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_open.c +0 -58
  285. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post.c +0 -128
  286. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post_multiple.c +0 -142
  287. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_timedwait.c +0 -238
  288. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_trywait.c +0 -117
  289. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_unlink.c +0 -58
  290. data/ext/noderb_extension/libuv/deps/pthread-win32/sem_wait.c +0 -187
  291. data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.c +0 -69
  292. data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.h +0 -169
  293. data/ext/noderb_extension/libuv/deps/pthread-win32/signal.c +0 -179
  294. data/ext/noderb_extension/libuv/deps/pthread-win32/spin.c +0 -46
  295. data/ext/noderb_extension/libuv/deps/pthread-win32/sync.c +0 -43
  296. data/ext/noderb_extension/libuv/deps/pthread-win32/tsd.c +0 -44
  297. data/ext/noderb_extension/libuv/deps/pthread-win32/version.rc +0 -388
  298. data/ext/noderb_extension/libuv/deps/pthread-win32/w32_CancelableWait.c +0 -161
  299. data/ext/noderb_extension/libuv/doc/iocp-links.html +0 -574
  300. data/ext/noderb_extension/libuv/src/uv-unix.c +0 -2421
  301. data/ext/noderb_extension/libuv/src/win/ntdll.h +0 -130
  302. /data/ext/noderb_extension/libuv/include/{ev.h → uv-private/ev.h} +0 -0
  303. /data/ext/noderb_extension/libuv/include/{ngx-queue.h → uv-private/ngx-queue.h} +0 -0
  304. /data/ext/noderb_extension/libuv/include/{tree.h → uv-private/tree.h} +0 -0
  305. /data/ext/noderb_extension/libuv/src/{uv-cygwin.c → unix/cygwin.c} +0 -0
  306. /data/ext/noderb_extension/libuv/src/{uv-darwin.c → unix/darwin.c} +0 -0
  307. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/Changes +0 -0
  308. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/LICENSE +0 -0
  309. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/Makefile.am +0 -0
  310. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/aclocal.m4 +0 -0
  311. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/autogen.sh +0 -0
  312. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config.h.in +0 -0
  313. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config_cygwin.h +0 -0
  314. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config_freebsd.h +0 -0
  315. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/config_sunos.h +0 -0
  316. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/configure.ac +0 -0
  317. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/demo.c +0 -0
  318. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/ecb.h +0 -0
  319. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/eio.3 +0 -0
  320. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/eio.pod +0 -0
  321. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/libeio.m4 +0 -0
  322. /data/ext/noderb_extension/libuv/src/{eio → unix/eio}/xthread.h +0 -0
  323. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/Changes +0 -0
  324. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/LICENSE +0 -0
  325. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/Makefile.am +0 -0
  326. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/Makefile.in +0 -0
  327. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/README +0 -0
  328. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/aclocal.m4 +0 -0
  329. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/autogen.sh +0 -0
  330. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config.guess +0 -0
  331. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config.h.in +0 -0
  332. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config.sub +0 -0
  333. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config_cygwin.h +0 -0
  334. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config_darwin.h +0 -0
  335. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config_freebsd.h +0 -0
  336. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/config_sunos.h +0 -0
  337. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/configure +0 -0
  338. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/configure.ac +0 -0
  339. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/depcomp +0 -0
  340. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev++.h +0 -0
  341. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev.3 +0 -0
  342. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev.c +0 -0
  343. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev.pod +0 -0
  344. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_epoll.c +0 -0
  345. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_kqueue.c +0 -0
  346. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_poll.c +0 -0
  347. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_port.c +0 -0
  348. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_select.c +0 -0
  349. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_vars.h +0 -0
  350. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_win32.c +0 -0
  351. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ev_wrap.h +0 -0
  352. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/event.c +0 -0
  353. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/event.h +0 -0
  354. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/install-sh +0 -0
  355. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/libev.m4 +0 -0
  356. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/ltmain.sh +0 -0
  357. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/missing +0 -0
  358. /data/ext/noderb_extension/libuv/src/{ev → unix/ev}/mkinstalldirs +0 -0
  359. /data/ext/noderb_extension/libuv/src/{uv-freebsd.c → unix/freebsd.c} +0 -0
  360. /data/ext/noderb_extension/libuv/src/{uv-linux.c → unix/linux.c} +0 -0
  361. /data/ext/noderb_extension/libuv/src/{uv-sunos.c → unix/sunos.c} +0 -0
@@ -1,2421 +0,0 @@
1
- /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
- * Permission is hereby granted, free of charge, to any person obtaining a copy
3
- * of this software and associated documentation files (the "Software"), to
4
- * deal in the Software without restriction, including without limitation the
5
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6
- * sell copies of the Software, and to permit persons to whom the Software is
7
- * furnished to do so, subject to the following conditions:
8
- *
9
- * The above copyright notice and this permission notice shall be included in
10
- * all copies or substantial portions of the Software.
11
- *
12
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18
- * IN THE SOFTWARE.
19
- */
20
-
21
- #ifndef _GNU_SOURCE
22
- #define _GNU_SOURCE /* O_CLOEXEC, accept4(), etc. */
23
- #endif
24
-
25
- #include "uv.h"
26
- #include "uv-common.h"
27
- #include "uv-eio.h"
28
-
29
- #include <stddef.h> /* NULL */
30
- #include <stdio.h> /* printf */
31
- #include <stdlib.h>
32
- #include <string.h> /* strerror */
33
- #include <errno.h>
34
- #include <assert.h>
35
- #include <unistd.h>
36
- #include <sys/types.h>
37
- #include <sys/stat.h>
38
- #include <fcntl.h>
39
- #include <sys/socket.h>
40
- #include <sys/un.h>
41
- #include <netinet/in.h>
42
- #include <arpa/inet.h>
43
- #include <limits.h> /* PATH_MAX */
44
- #include <sys/uio.h> /* writev */
45
- #include <poll.h>
46
-
47
- #ifdef __linux__
48
- #include <linux/version.h>
49
- /* pipe2() requires linux >= 2.6.27 and glibc >= 2.9 */
50
- #define HAVE_PIPE2 \
51
- defined(LINUX_VERSION_CODE) && defined(__GLIBC_PREREQ) && \
52
- LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) && __GLIBC_PREREQ(2, 9))
53
- #endif
54
-
55
- /* XXX disabling HAVE_PIPE2 for now can't compile on 2.6.18 */
56
- #undef HAVE_PIPE2
57
-
58
- #ifdef __sun
59
- # include <sys/types.h>
60
- # include <sys/wait.h>
61
- #endif
62
-
63
- #if defined(__APPLE__)
64
- #include <mach-o/dyld.h> /* _NSGetExecutablePath */
65
- #endif
66
-
67
- #if defined(__FreeBSD__)
68
- #include <sys/sysctl.h>
69
- #include <sys/wait.h>
70
- #endif
71
-
72
-
73
- # ifdef __APPLE__
74
- # include <crt_externs.h>
75
- # define environ (*_NSGetEnviron())
76
- # else
77
- extern char **environ;
78
- # endif
79
-
80
- static uv_err_t last_err;
81
-
82
- struct uv_ares_data_s {
83
- ares_channel channel;
84
- /*
85
- * While the channel is active this timer is called once per second to be sure
86
- * that we're always calling ares_process. See the warning above the
87
- * definition of ares_timeout().
88
- */
89
- ev_timer timer;
90
- };
91
-
92
- static struct uv_ares_data_s ares_data;
93
-
94
- void uv__req_init(uv_req_t*);
95
- void uv__next(EV_P_ ev_idle* watcher, int revents);
96
- static int uv__stream_open(uv_stream_t*, int fd, int flags);
97
- static void uv__finish_close(uv_handle_t* handle);
98
- static uv_err_t uv_err_new(uv_handle_t* handle, int sys_error);
99
-
100
- static int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
101
- static int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
102
- static int uv_pipe_cleanup(uv_pipe_t* handle);
103
- static uv_write_t* uv__write(uv_stream_t* stream);
104
- static void uv__read(uv_stream_t* stream);
105
- static void uv__stream_connect(uv_stream_t*);
106
- static void uv__stream_io(EV_P_ ev_io* watcher, int revents);
107
- static void uv__pipe_accept(EV_P_ ev_io* watcher, int revents);
108
-
109
- #ifndef __GNUC__
110
- #define __attribute__(a)
111
- #endif
112
-
113
- /* Unused on systems that support O_CLOEXEC, SOCK_CLOEXEC, etc. */
114
- static int uv__cloexec(int fd, int set) __attribute__((unused));
115
- static int uv__nonblock(int fd, int set) __attribute__((unused));
116
-
117
- static int uv__socket(int domain, int type, int protocol);
118
- static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t len);
119
- static int uv__close(int fd);
120
-
121
- size_t uv__strlcpy(char* dst, const char* src, size_t size);
122
-
123
-
124
- /* flags */
125
- enum {
126
- UV_CLOSING = 0x00000001, /* uv_close() called but not finished. */
127
- UV_CLOSED = 0x00000002, /* close(2) finished. */
128
- UV_READING = 0x00000004, /* uv_read_start() called. */
129
- UV_SHUTTING = 0x00000008, /* uv_shutdown() called but not complete. */
130
- UV_SHUT = 0x00000010, /* Write side closed. */
131
- UV_READABLE = 0x00000020, /* The stream is readable */
132
- UV_WRITABLE = 0x00000040 /* The stream is writable */
133
- };
134
-
135
-
136
- /* TODO Share this code with Windows. */
137
- /* TODO Expose callback to user to handle fatal error like V8 does. */
138
- static void uv_fatal_error(const int errorno, const char* syscall) {
139
- char* buf = NULL;
140
- const char* errmsg;
141
-
142
- if (buf) {
143
- errmsg = buf;
144
- } else {
145
- errmsg = "Unknown error";
146
- }
147
-
148
- if (syscall) {
149
- fprintf(stderr, "\nlibuv fatal error. %s: (%d) %s\n", syscall, errorno,
150
- errmsg);
151
- } else {
152
- fprintf(stderr, "\nlibuv fatal error. (%d) %s\n", errorno, errmsg);
153
- }
154
-
155
- abort();
156
- }
157
-
158
-
159
- uv_err_t uv_last_error() {
160
- return last_err;
161
- }
162
-
163
-
164
- char* uv_strerror(uv_err_t err) {
165
- return strerror(err.sys_errno_);
166
- }
167
-
168
-
169
- static uv_err_code uv_translate_sys_error(int sys_errno) {
170
- switch (sys_errno) {
171
- case 0: return UV_OK;
172
- case EACCES: return UV_EACCESS;
173
- case EBADF: return UV_EBADF;
174
- case EPIPE: return UV_EPIPE;
175
- case EAGAIN: return UV_EAGAIN;
176
- case ECONNRESET: return UV_ECONNRESET;
177
- case EFAULT: return UV_EFAULT;
178
- case EMFILE: return UV_EMFILE;
179
- case EINVAL: return UV_EINVAL;
180
- case ECONNREFUSED: return UV_ECONNREFUSED;
181
- case EADDRINUSE: return UV_EADDRINUSE;
182
- case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
183
- default: return UV_UNKNOWN;
184
- }
185
- }
186
-
187
-
188
- static uv_err_t uv_err_new_artificial(uv_handle_t* handle, int code) {
189
- uv_err_t err;
190
- err.sys_errno_ = 0;
191
- err.code = code;
192
- last_err = err;
193
- return err;
194
- }
195
-
196
-
197
- static uv_err_t uv_err_new(uv_handle_t* handle, int sys_error) {
198
- uv_err_t err;
199
- err.sys_errno_ = sys_error;
200
- err.code = uv_translate_sys_error(sys_error);
201
- last_err = err;
202
- return err;
203
- }
204
-
205
-
206
- void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
207
- uv_async_t* async;
208
- uv_timer_t* timer;
209
- uv_stream_t* stream;
210
- uv_process_t* process;
211
-
212
- handle->close_cb = close_cb;
213
-
214
- switch (handle->type) {
215
- case UV_NAMED_PIPE:
216
- uv_pipe_cleanup((uv_pipe_t*)handle);
217
- /* Fall through. */
218
-
219
- case UV_TCP:
220
- stream = (uv_stream_t*)handle;
221
-
222
- uv_read_stop(stream);
223
- ev_io_stop(EV_DEFAULT_ &stream->write_watcher);
224
-
225
- uv__close(stream->fd);
226
- stream->fd = -1;
227
-
228
- if (stream->accepted_fd >= 0) {
229
- uv__close(stream->accepted_fd);
230
- stream->accepted_fd = -1;
231
- }
232
- break;
233
-
234
- case UV_PREPARE:
235
- uv_prepare_stop((uv_prepare_t*) handle);
236
- break;
237
-
238
- case UV_CHECK:
239
- uv_check_stop((uv_check_t*) handle);
240
- break;
241
-
242
- case UV_IDLE:
243
- uv_idle_stop((uv_idle_t*) handle);
244
- break;
245
-
246
- case UV_ASYNC:
247
- async = (uv_async_t*)handle;
248
- ev_async_stop(EV_DEFAULT_ &async->async_watcher);
249
- ev_ref(EV_DEFAULT_UC);
250
- break;
251
-
252
- case UV_TIMER:
253
- timer = (uv_timer_t*)handle;
254
- if (ev_is_active(&timer->timer_watcher)) {
255
- ev_ref(EV_DEFAULT_UC);
256
- }
257
- ev_timer_stop(EV_DEFAULT_ &timer->timer_watcher);
258
- break;
259
-
260
- case UV_PROCESS:
261
- process = (uv_process_t*)handle;
262
- ev_child_stop(EV_DEFAULT_UC_ &process->child_watcher);
263
- break;
264
-
265
- default:
266
- assert(0);
267
- }
268
-
269
- handle->flags |= UV_CLOSING;
270
-
271
- /* This is used to call the on_close callback in the next loop. */
272
- ev_idle_start(EV_DEFAULT_ &handle->next_watcher);
273
- ev_feed_event(EV_DEFAULT_ &handle->next_watcher, EV_IDLE);
274
- assert(ev_is_pending(&handle->next_watcher));
275
- }
276
-
277
-
278
- void uv_init() {
279
- /* Initialize the default ev loop. */
280
- #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
281
- ev_default_loop(EVBACKEND_KQUEUE);
282
- #else
283
- ev_default_loop(EVFLAG_AUTO);
284
- #endif
285
- }
286
-
287
-
288
- int uv_run() {
289
- ev_run(EV_DEFAULT_ 0);
290
- return 0;
291
- }
292
-
293
-
294
- static void uv__handle_init(uv_handle_t* handle, uv_handle_type type) {
295
- uv_counters()->handle_init++;
296
-
297
- handle->type = type;
298
- handle->flags = 0;
299
-
300
- ev_init(&handle->next_watcher, uv__next);
301
- handle->next_watcher.data = handle;
302
-
303
- /* Ref the loop until this handle is closed. See uv__finish_close. */
304
- ev_ref(EV_DEFAULT_UC);
305
- }
306
-
307
-
308
- int uv_tcp_init(uv_tcp_t* tcp) {
309
- uv__handle_init((uv_handle_t*)tcp, UV_TCP);
310
- uv_counters()->tcp_init++;
311
-
312
- tcp->alloc_cb = NULL;
313
- tcp->connect_req = NULL;
314
- tcp->accepted_fd = -1;
315
- tcp->fd = -1;
316
- tcp->delayed_error = 0;
317
- ngx_queue_init(&tcp->write_queue);
318
- ngx_queue_init(&tcp->write_completed_queue);
319
- tcp->write_queue_size = 0;
320
-
321
- ev_init(&tcp->read_watcher, uv__stream_io);
322
- tcp->read_watcher.data = tcp;
323
-
324
- ev_init(&tcp->write_watcher, uv__stream_io);
325
- tcp->write_watcher.data = tcp;
326
-
327
- assert(ngx_queue_empty(&tcp->write_queue));
328
- assert(ngx_queue_empty(&tcp->write_completed_queue));
329
- assert(tcp->write_queue_size == 0);
330
-
331
- return 0;
332
- }
333
-
334
-
335
- static int uv__bind(uv_tcp_t* tcp, int domain, struct sockaddr* addr,
336
- int addrsize) {
337
- int saved_errno;
338
- int status;
339
-
340
- saved_errno = errno;
341
- status = -1;
342
-
343
- if (tcp->fd < 0) {
344
- if ((tcp->fd = uv__socket(domain, SOCK_STREAM, 0)) == -1) {
345
- uv_err_new((uv_handle_t*)tcp, errno);
346
- goto out;
347
- }
348
-
349
- if (uv__stream_open((uv_stream_t*)tcp, tcp->fd, UV_READABLE | UV_WRITABLE)) {
350
- uv__close(tcp->fd);
351
- tcp->fd = -1;
352
- status = -2;
353
- goto out;
354
- }
355
- }
356
-
357
- assert(tcp->fd >= 0);
358
-
359
- tcp->delayed_error = 0;
360
- if (bind(tcp->fd, addr, addrsize) == -1) {
361
- if (errno == EADDRINUSE) {
362
- tcp->delayed_error = errno;
363
- } else {
364
- uv_err_new((uv_handle_t*)tcp, errno);
365
- goto out;
366
- }
367
- }
368
- status = 0;
369
-
370
- out:
371
- errno = saved_errno;
372
- return status;
373
- }
374
-
375
-
376
- int uv_tcp_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
377
- if (addr.sin_family != AF_INET) {
378
- uv_err_new((uv_handle_t*)tcp, EFAULT);
379
- return -1;
380
- }
381
-
382
- return uv__bind(tcp, AF_INET, (struct sockaddr*)&addr,
383
- sizeof(struct sockaddr_in));
384
- }
385
-
386
-
387
- int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
388
- if (addr.sin6_family != AF_INET6) {
389
- uv_err_new((uv_handle_t*)tcp, EFAULT);
390
- return -1;
391
- }
392
-
393
- return uv__bind(tcp, AF_INET6, (struct sockaddr*)&addr,
394
- sizeof(struct sockaddr_in6));
395
- }
396
-
397
-
398
- static int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
399
- socklen_t yes;
400
-
401
- assert(fd >= 0);
402
- stream->fd = fd;
403
-
404
- ((uv_handle_t*)stream)->flags |= flags;
405
-
406
- /* Reuse the port address if applicable. */
407
- yes = 1;
408
- if (stream->type == UV_TCP
409
- && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
410
- uv_err_new((uv_handle_t*)stream, errno);
411
- return -1;
412
- }
413
-
414
- /* Associate the fd with each ev_io watcher. */
415
- ev_io_set(&stream->read_watcher, fd, EV_READ);
416
- ev_io_set(&stream->write_watcher, fd, EV_WRITE);
417
-
418
- /* These should have been set up by uv_tcp_init or uv_pipe_init. */
419
- assert(stream->read_watcher.cb == uv__stream_io);
420
- assert(stream->write_watcher.cb == uv__stream_io);
421
-
422
- return 0;
423
- }
424
-
425
-
426
- void uv__server_io(EV_P_ ev_io* watcher, int revents) {
427
- int fd;
428
- struct sockaddr_storage addr;
429
- uv_stream_t* stream = watcher->data;
430
-
431
- assert(watcher == &stream->read_watcher ||
432
- watcher == &stream->write_watcher);
433
- assert(revents == EV_READ);
434
-
435
- assert(!(stream->flags & UV_CLOSING));
436
-
437
- if (stream->accepted_fd >= 0) {
438
- ev_io_stop(EV_DEFAULT_ &stream->read_watcher);
439
- return;
440
- }
441
-
442
- /* connection_cb can close the server socket while we're
443
- * in the loop so check it on each iteration.
444
- */
445
- while (stream->fd != -1) {
446
- assert(stream->accepted_fd < 0);
447
- fd = uv__accept(stream->fd, (struct sockaddr*)&addr, sizeof addr);
448
-
449
- if (fd < 0) {
450
- if (errno == EAGAIN) {
451
- /* No problem. */
452
- return;
453
- } else if (errno == EMFILE) {
454
- /* TODO special trick. unlock reserved socket, accept, close. */
455
- return;
456
- } else {
457
- uv_err_new((uv_handle_t*)stream, errno);
458
- stream->connection_cb((uv_stream_t*)stream, -1);
459
- }
460
- } else {
461
- stream->accepted_fd = fd;
462
- stream->connection_cb((uv_stream_t*)stream, 0);
463
- if (stream->accepted_fd >= 0) {
464
- /* The user hasn't yet accepted called uv_accept() */
465
- ev_io_stop(EV_DEFAULT_ &stream->read_watcher);
466
- return;
467
- }
468
- }
469
- }
470
- }
471
-
472
-
473
- int uv_accept(uv_stream_t* server, uv_stream_t* client) {
474
- uv_stream_t* streamServer;
475
- uv_stream_t* streamClient;
476
- int saved_errno;
477
- int status;
478
-
479
- saved_errno = errno;
480
- status = -1;
481
-
482
- streamServer = (uv_stream_t*)server;
483
- streamClient = (uv_stream_t*)client;
484
-
485
- if (streamServer->accepted_fd < 0) {
486
- uv_err_new((uv_handle_t*)server, EAGAIN);
487
- goto out;
488
- }
489
-
490
- if (uv__stream_open(streamClient, streamServer->accepted_fd,
491
- UV_READABLE | UV_WRITABLE)) {
492
- /* TODO handle error */
493
- streamServer->accepted_fd = -1;
494
- uv__close(streamServer->accepted_fd);
495
- goto out;
496
- }
497
-
498
- ev_io_start(EV_DEFAULT_ &streamServer->read_watcher);
499
- streamServer->accepted_fd = -1;
500
- status = 0;
501
-
502
- out:
503
- errno = saved_errno;
504
- return status;
505
- }
506
-
507
-
508
- int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
509
- switch (stream->type) {
510
- case UV_TCP:
511
- return uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
512
- case UV_NAMED_PIPE:
513
- return uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
514
- default:
515
- assert(0);
516
- return -1;
517
- }
518
- }
519
-
520
-
521
- static int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
522
- int r;
523
-
524
- if (tcp->delayed_error) {
525
- uv_err_new((uv_handle_t*)tcp, tcp->delayed_error);
526
- return -1;
527
- }
528
-
529
- if (tcp->fd < 0) {
530
- if ((tcp->fd = uv__socket(AF_INET, SOCK_STREAM, 0)) == -1) {
531
- uv_err_new((uv_handle_t*)tcp, errno);
532
- return -1;
533
- }
534
-
535
- if (uv__stream_open((uv_stream_t*)tcp, tcp->fd, UV_READABLE)) {
536
- uv__close(tcp->fd);
537
- tcp->fd = -1;
538
- return -1;
539
- }
540
- }
541
-
542
- assert(tcp->fd >= 0);
543
-
544
- r = listen(tcp->fd, backlog);
545
- if (r < 0) {
546
- uv_err_new((uv_handle_t*)tcp, errno);
547
- return -1;
548
- }
549
-
550
- tcp->connection_cb = cb;
551
-
552
- /* Start listening for connections. */
553
- ev_io_set(&tcp->read_watcher, tcp->fd, EV_READ);
554
- ev_set_cb(&tcp->read_watcher, uv__server_io);
555
- ev_io_start(EV_DEFAULT_ &tcp->read_watcher);
556
-
557
- return 0;
558
- }
559
-
560
-
561
- void uv__finish_close(uv_handle_t* handle) {
562
- assert(handle->flags & UV_CLOSING);
563
- assert(!(handle->flags & UV_CLOSED));
564
- handle->flags |= UV_CLOSED;
565
-
566
- switch (handle->type) {
567
- case UV_PREPARE:
568
- assert(!ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher));
569
- break;
570
-
571
- case UV_CHECK:
572
- assert(!ev_is_active(&((uv_check_t*)handle)->check_watcher));
573
- break;
574
-
575
- case UV_IDLE:
576
- assert(!ev_is_active(&((uv_idle_t*)handle)->idle_watcher));
577
- break;
578
-
579
- case UV_ASYNC:
580
- assert(!ev_is_active(&((uv_async_t*)handle)->async_watcher));
581
- break;
582
-
583
- case UV_TIMER:
584
- assert(!ev_is_active(&((uv_timer_t*)handle)->timer_watcher));
585
- break;
586
-
587
- case UV_NAMED_PIPE:
588
- case UV_TCP:
589
- assert(!ev_is_active(&((uv_stream_t*)handle)->read_watcher));
590
- assert(!ev_is_active(&((uv_stream_t*)handle)->write_watcher));
591
- break;
592
-
593
- case UV_PROCESS:
594
- assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
595
- break;
596
-
597
- default:
598
- assert(0);
599
- break;
600
- }
601
-
602
- ev_idle_stop(EV_DEFAULT_ &handle->next_watcher);
603
-
604
- if (handle->close_cb) {
605
- handle->close_cb(handle);
606
- }
607
-
608
- ev_unref(EV_DEFAULT_UC);
609
- }
610
-
611
-
612
- uv_write_t* uv_write_queue_head(uv_stream_t* stream) {
613
- ngx_queue_t* q;
614
- uv_write_t* req;
615
-
616
- if (ngx_queue_empty(&stream->write_queue)) {
617
- return NULL;
618
- }
619
-
620
- q = ngx_queue_head(&stream->write_queue);
621
- if (!q) {
622
- return NULL;
623
- }
624
-
625
- req = ngx_queue_data(q, struct uv_write_s, queue);
626
- assert(req);
627
-
628
- return req;
629
- }
630
-
631
-
632
- void uv__next(EV_P_ ev_idle* watcher, int revents) {
633
- uv_handle_t* handle = watcher->data;
634
- assert(watcher == &handle->next_watcher);
635
- assert(revents == EV_IDLE);
636
-
637
- /* For now this function is only to handle the closing event, but we might
638
- * put more stuff here later.
639
- */
640
- assert(handle->flags & UV_CLOSING);
641
- uv__finish_close(handle);
642
- }
643
-
644
-
645
- static void uv__drain(uv_stream_t* stream) {
646
- uv_shutdown_t* req;
647
-
648
- assert(!uv_write_queue_head(stream));
649
- assert(stream->write_queue_size == 0);
650
-
651
- ev_io_stop(EV_DEFAULT_ &stream->write_watcher);
652
-
653
- /* Shutdown? */
654
- if ((stream->flags & UV_SHUTTING) &&
655
- !(stream->flags & UV_CLOSING) &&
656
- !(stream->flags & UV_SHUT)) {
657
- assert(stream->shutdown_req);
658
-
659
- req = stream->shutdown_req;
660
-
661
- if (shutdown(stream->fd, SHUT_WR)) {
662
- /* Error. Report it. User should call uv_close(). */
663
- uv_err_new((uv_handle_t*)stream, errno);
664
- if (req->cb) {
665
- req->cb(req, -1);
666
- }
667
- } else {
668
- uv_err_new((uv_handle_t*)stream, 0);
669
- ((uv_handle_t*) stream)->flags |= UV_SHUT;
670
- if (req->cb) {
671
- req->cb(req, 0);
672
- }
673
- }
674
- }
675
- }
676
-
677
-
678
- /* On success returns NULL. On error returns a pointer to the write request
679
- * which had the error.
680
- */
681
- static uv_write_t* uv__write(uv_stream_t* stream) {
682
- uv_write_t* req;
683
- struct iovec* iov;
684
- int iovcnt;
685
- ssize_t n;
686
-
687
- assert(stream->fd >= 0);
688
-
689
- /* TODO: should probably while(1) here until EAGAIN */
690
-
691
- /* Get the request at the head of the queue. */
692
- req = uv_write_queue_head(stream);
693
- if (!req) {
694
- assert(stream->write_queue_size == 0);
695
- return NULL;
696
- }
697
-
698
- assert(req->handle == stream);
699
-
700
- /* Cast to iovec. We had to have our own uv_buf_t instead of iovec
701
- * because Windows's WSABUF is not an iovec.
702
- */
703
- assert(sizeof(uv_buf_t) == sizeof(struct iovec));
704
- iov = (struct iovec*) &(req->bufs[req->write_index]);
705
- iovcnt = req->bufcnt - req->write_index;
706
-
707
- /* Now do the actual writev. Note that we've been updating the pointers
708
- * inside the iov each time we write. So there is no need to offset it.
709
- */
710
-
711
- do {
712
- if (iovcnt == 1) {
713
- n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
714
- } else {
715
- n = writev(stream->fd, iov, iovcnt);
716
- }
717
- }
718
- while (n == -1 && errno == EINTR);
719
-
720
- if (n < 0) {
721
- if (errno != EAGAIN) {
722
- /* Error */
723
- uv_err_new((uv_handle_t*)stream, errno);
724
- return req;
725
- }
726
- } else {
727
- /* Successful write */
728
-
729
- /* Update the counters. */
730
- while (n >= 0) {
731
- uv_buf_t* buf = &(req->bufs[req->write_index]);
732
- size_t len = buf->len;
733
-
734
- assert(req->write_index < req->bufcnt);
735
-
736
- if ((size_t)n < len) {
737
- buf->base += n;
738
- buf->len -= n;
739
- stream->write_queue_size -= n;
740
- n = 0;
741
-
742
- /* There is more to write. Break and ensure the watcher is pending. */
743
- break;
744
-
745
- } else {
746
- /* Finished writing the buf at index req->write_index. */
747
- req->write_index++;
748
-
749
- assert((size_t)n >= len);
750
- n -= len;
751
-
752
- assert(stream->write_queue_size >= len);
753
- stream->write_queue_size -= len;
754
-
755
- if (req->write_index == req->bufcnt) {
756
- /* Then we're done! */
757
- assert(n == 0);
758
-
759
- /* Pop the req off tcp->write_queue. */
760
- ngx_queue_remove(&req->queue);
761
- if (req->bufs != req->bufsml) {
762
- free(req->bufs);
763
- }
764
- req->bufs = NULL;
765
-
766
- /* Add it to the write_completed_queue where it will have its
767
- * callback called in the near future.
768
- * TODO: start trying to write the next request.
769
- */
770
- ngx_queue_insert_tail(&stream->write_completed_queue, &req->queue);
771
- ev_feed_event(EV_DEFAULT_ &stream->write_watcher, EV_WRITE);
772
- return NULL;
773
- }
774
- }
775
- }
776
- }
777
-
778
- /* Either we've counted n down to zero or we've got EAGAIN. */
779
- assert(n == 0 || n == -1);
780
-
781
- /* We're not done. */
782
- ev_io_start(EV_DEFAULT_ &stream->write_watcher);
783
-
784
- return NULL;
785
- }
786
-
787
-
788
- static void uv__write_callbacks(uv_stream_t* stream) {
789
- int callbacks_made = 0;
790
- ngx_queue_t* q;
791
- uv_write_t* req;
792
-
793
- while (!ngx_queue_empty(&stream->write_completed_queue)) {
794
- /* Pop a req off write_completed_queue. */
795
- q = ngx_queue_head(&stream->write_completed_queue);
796
- assert(q);
797
- req = ngx_queue_data(q, struct uv_write_s, queue);
798
- ngx_queue_remove(q);
799
-
800
- /* NOTE: call callback AFTER freeing the request data. */
801
- if (req->cb) {
802
- req->cb(req, 0);
803
- }
804
-
805
- callbacks_made++;
806
- }
807
-
808
- assert(ngx_queue_empty(&stream->write_completed_queue));
809
-
810
- /* Write queue drained. */
811
- if (!uv_write_queue_head(stream)) {
812
- uv__drain(stream);
813
- }
814
- }
815
-
816
-
817
- static void uv__read(uv_stream_t* stream) {
818
- uv_buf_t buf;
819
- struct iovec* iov;
820
- ssize_t nread;
821
-
822
- /* XXX: Maybe instead of having UV_READING we just test if
823
- * tcp->read_cb is NULL or not?
824
- */
825
- while (stream->read_cb && ((uv_handle_t*)stream)->flags & UV_READING) {
826
- assert(stream->alloc_cb);
827
- buf = stream->alloc_cb(stream, 64 * 1024);
828
-
829
- assert(buf.len > 0);
830
- assert(buf.base);
831
-
832
- iov = (struct iovec*) &buf;
833
-
834
- do {
835
- nread = read(stream->fd, buf.base, buf.len);
836
- }
837
- while (nread == -1 && errno == EINTR);
838
-
839
- if (nread < 0) {
840
- /* Error */
841
- if (errno == EAGAIN) {
842
- /* Wait for the next one. */
843
- if (((uv_handle_t*)stream)->flags & UV_READING) {
844
- ev_io_start(EV_DEFAULT_UC_ &stream->read_watcher);
845
- }
846
- uv_err_new((uv_handle_t*)stream, EAGAIN);
847
- stream->read_cb(stream, 0, buf);
848
- return;
849
- } else {
850
- /* Error. User should call uv_close(). */
851
- uv_err_new((uv_handle_t*)stream, errno);
852
- stream->read_cb(stream, -1, buf);
853
- assert(!ev_is_active(&stream->read_watcher));
854
- return;
855
- }
856
- } else if (nread == 0) {
857
- /* EOF */
858
- uv_err_new_artificial((uv_handle_t*)stream, UV_EOF);
859
- ev_io_stop(EV_DEFAULT_UC_ &stream->read_watcher);
860
- stream->read_cb(stream, -1, buf);
861
- return;
862
- } else {
863
- /* Successful read */
864
- stream->read_cb(stream, nread, buf);
865
- }
866
- }
867
- }
868
-
869
-
870
- int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
871
- assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) &&
872
- "uv_shutdown (unix) only supports uv_handle_t right now");
873
- assert(stream->fd >= 0);
874
-
875
- if (!(stream->flags & UV_WRITABLE) ||
876
- stream->flags & UV_SHUT ||
877
- stream->flags & UV_CLOSED ||
878
- stream->flags & UV_CLOSING) {
879
- uv_err_new((uv_handle_t*)stream, EINVAL);
880
- return -1;
881
- }
882
-
883
- /* Initialize request */
884
- uv__req_init((uv_req_t*)req);
885
- req->handle = stream;
886
- req->cb = cb;
887
-
888
- stream->shutdown_req = req;
889
- req->type = UV_SHUTDOWN;
890
-
891
- ((uv_handle_t*)stream)->flags |= UV_SHUTTING;
892
-
893
-
894
- ev_io_start(EV_DEFAULT_UC_ &stream->write_watcher);
895
-
896
- return 0;
897
- }
898
-
899
-
900
- static void uv__stream_io(EV_P_ ev_io* watcher, int revents) {
901
- uv_stream_t* stream = watcher->data;
902
-
903
- assert(stream->type == UV_TCP ||
904
- stream->type == UV_NAMED_PIPE);
905
- assert(watcher == &stream->read_watcher ||
906
- watcher == &stream->write_watcher);
907
- assert(!(stream->flags & UV_CLOSING));
908
-
909
- if (stream->connect_req) {
910
- uv__stream_connect(stream);
911
- } else {
912
- assert(revents & (EV_READ | EV_WRITE));
913
- assert(stream->fd >= 0);
914
-
915
- if (revents & EV_READ) {
916
- uv__read((uv_stream_t*)stream);
917
- }
918
-
919
- if (revents & EV_WRITE) {
920
- uv_write_t* req = uv__write(stream);
921
- if (req) {
922
- /* Error. Notify the user. */
923
- if (req->cb) {
924
- req->cb(req, -1);
925
- }
926
- } else {
927
- uv__write_callbacks(stream);
928
- }
929
- }
930
- }
931
- }
932
-
933
-
934
- /**
935
- * We get called here from directly following a call to connect(2).
936
- * In order to determine if we've errored out or succeeded must call
937
- * getsockopt.
938
- */
939
- static void uv__stream_connect(uv_stream_t* stream) {
940
- int error;
941
- uv_connect_t* req = stream->connect_req;
942
- socklen_t errorsize = sizeof(int);
943
-
944
- assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);
945
- assert(req);
946
-
947
- if (stream->delayed_error) {
948
- /* To smooth over the differences between unixes errors that
949
- * were reported synchronously on the first connect can be delayed
950
- * until the next tick--which is now.
951
- */
952
- error = stream->delayed_error;
953
- stream->delayed_error = 0;
954
- } else {
955
- /* Normal situation: we need to get the socket error from the kernel. */
956
- assert(stream->fd >= 0);
957
- getsockopt(stream->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
958
- }
959
-
960
- if (!error) {
961
- ev_io_start(EV_DEFAULT_ &stream->read_watcher);
962
-
963
- /* Successful connection */
964
- stream->connect_req = NULL;
965
- if (req->cb) {
966
- req->cb(req, 0);
967
- }
968
-
969
- } else if (error == EINPROGRESS) {
970
- /* Still connecting. */
971
- return;
972
- } else {
973
- /* Error */
974
- uv_err_new((uv_handle_t*)stream, error);
975
-
976
- stream->connect_req = NULL;
977
- if (req->cb) {
978
- req->cb(req, -1);
979
- }
980
- }
981
- }
982
-
983
-
984
- static int uv__connect(uv_connect_t* req,
985
- uv_stream_t* stream,
986
- struct sockaddr* addr,
987
- socklen_t addrlen,
988
- uv_connect_cb cb) {
989
-
990
- int sockfd;
991
- int r;
992
-
993
- if (stream->fd <= 0) {
994
- if ((sockfd = uv__socket(addr->sa_family, SOCK_STREAM, 0)) == -1) {
995
- uv_err_new((uv_handle_t*)stream, errno);
996
- return -1;
997
- }
998
-
999
- if (uv__stream_open(stream, sockfd, UV_READABLE | UV_WRITABLE)) {
1000
- uv__close(sockfd);
1001
- return -2;
1002
- }
1003
- }
1004
-
1005
- uv__req_init((uv_req_t*)req);
1006
- req->cb = cb;
1007
- req->handle = stream;
1008
- req->type = UV_CONNECT;
1009
- ngx_queue_init(&req->queue);
1010
-
1011
- if (stream->connect_req) {
1012
- uv_err_new((uv_handle_t*)stream, EALREADY);
1013
- return -1;
1014
- }
1015
-
1016
- if (stream->type != UV_TCP) {
1017
- uv_err_new((uv_handle_t*)stream, ENOTSOCK);
1018
- return -1;
1019
- }
1020
-
1021
- stream->connect_req = req;
1022
-
1023
- do {
1024
- r = connect(stream->fd, addr, addrlen);
1025
- }
1026
- while (r == -1 && errno == EINTR);
1027
-
1028
- stream->delayed_error = 0;
1029
-
1030
- if (r != 0 && errno != EINPROGRESS) {
1031
- switch (errno) {
1032
- /* If we get a ECONNREFUSED wait until the next tick to report the
1033
- * error. Solaris wants to report immediately--other unixes want to
1034
- * wait.
1035
- */
1036
- case ECONNREFUSED:
1037
- stream->delayed_error = errno;
1038
- break;
1039
-
1040
- default:
1041
- uv_err_new((uv_handle_t*)stream, errno);
1042
- return -1;
1043
- }
1044
- }
1045
-
1046
- assert(stream->write_watcher.data == stream);
1047
- ev_io_start(EV_DEFAULT_ &stream->write_watcher);
1048
-
1049
- if (stream->delayed_error) {
1050
- ev_feed_event(EV_DEFAULT_ &stream->write_watcher, EV_WRITE);
1051
- }
1052
-
1053
- return 0;
1054
- }
1055
-
1056
-
1057
- int uv_tcp_connect(uv_connect_t* req,
1058
- uv_tcp_t* handle,
1059
- struct sockaddr_in address,
1060
- uv_connect_cb cb) {
1061
- int saved_errno;
1062
- int status;
1063
-
1064
- saved_errno = errno;
1065
- status = -1;
1066
-
1067
- if (handle->type != UV_TCP) {
1068
- uv_err_new((uv_handle_t*)handle, EINVAL);
1069
- goto out;
1070
- }
1071
-
1072
- if (address.sin_family != AF_INET) {
1073
- uv_err_new((uv_handle_t*)handle, EINVAL);
1074
- goto out;
1075
- }
1076
-
1077
- status = uv__connect(req,
1078
- (uv_stream_t*)handle,
1079
- (struct sockaddr*)&address,
1080
- sizeof address,
1081
- cb);
1082
-
1083
- out:
1084
- errno = saved_errno;
1085
- return status;
1086
- }
1087
-
1088
-
1089
- int uv_tcp_connect6(uv_connect_t* req,
1090
- uv_tcp_t* handle,
1091
- struct sockaddr_in6 address,
1092
- uv_connect_cb cb) {
1093
- int saved_errno;
1094
- int status;
1095
-
1096
- saved_errno = errno;
1097
- status = -1;
1098
-
1099
- if (handle->type != UV_TCP) {
1100
- uv_err_new((uv_handle_t*)handle, EINVAL);
1101
- goto out;
1102
- }
1103
-
1104
- if (address.sin6_family != AF_INET6) {
1105
- uv_err_new((uv_handle_t*)handle, EINVAL);
1106
- goto out;
1107
- }
1108
-
1109
- status = uv__connect(req,
1110
- (uv_stream_t*)handle,
1111
- (struct sockaddr*)&address,
1112
- sizeof address,
1113
- cb);
1114
-
1115
- out:
1116
- errno = saved_errno;
1117
- return status;
1118
- }
1119
-
1120
-
1121
- int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) {
1122
- socklen_t socklen;
1123
- int saved_errno;
1124
-
1125
- /* Don't clobber errno. */
1126
- saved_errno = errno;
1127
-
1128
- /* sizeof(socklen_t) != sizeof(int) on some systems. */
1129
- socklen = (socklen_t)*namelen;
1130
-
1131
- if (getsockname(handle->fd, name, &socklen) == -1) {
1132
- uv_err_new((uv_handle_t*)handle, errno);
1133
- } else {
1134
- *namelen = (int)socklen;
1135
- }
1136
-
1137
- errno = saved_errno;
1138
- return 0;
1139
- }
1140
-
1141
-
1142
- static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
1143
- size_t total = 0;
1144
- int i;
1145
-
1146
- for (i = 0; i < bufcnt; i++) {
1147
- total += bufs[i].len;
1148
- }
1149
-
1150
- return total;
1151
- }
1152
-
1153
-
1154
- /* The buffers to be written must remain valid until the callback is called.
1155
- * This is not required for the uv_buf_t array.
1156
- */
1157
- int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
1158
- uv_write_cb cb) {
1159
- uv_stream_t* stream;
1160
- int empty_queue;
1161
-
1162
- stream = (uv_stream_t*)handle;
1163
-
1164
- /* Initialize the req */
1165
- uv__req_init((uv_req_t*) req);
1166
- req->cb = cb;
1167
- req->handle = handle;
1168
- ngx_queue_init(&req->queue);
1169
-
1170
- assert((handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
1171
- && "uv_write (unix) does not yet support other types of streams");
1172
-
1173
- empty_queue = (stream->write_queue_size == 0);
1174
-
1175
- if (stream->fd < 0) {
1176
- uv_err_new((uv_handle_t*)stream, EBADF);
1177
- return -1;
1178
- }
1179
-
1180
- ngx_queue_init(&req->queue);
1181
- req->type = UV_WRITE;
1182
-
1183
-
1184
- if (bufcnt < UV_REQ_BUFSML_SIZE) {
1185
- req->bufs = req->bufsml;
1186
- }
1187
- else {
1188
- req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
1189
- }
1190
-
1191
- memcpy(req->bufs, bufs, bufcnt * sizeof(uv_buf_t));
1192
- req->bufcnt = bufcnt;
1193
-
1194
- /*
1195
- * fprintf(stderr, "cnt: %d bufs: %p bufsml: %p\n", bufcnt, req->bufs, req->bufsml);
1196
- */
1197
-
1198
- req->write_index = 0;
1199
- stream->write_queue_size += uv__buf_count(bufs, bufcnt);
1200
-
1201
- /* Append the request to write_queue. */
1202
- ngx_queue_insert_tail(&stream->write_queue, &req->queue);
1203
-
1204
- assert(!ngx_queue_empty(&stream->write_queue));
1205
- assert(stream->write_watcher.cb == uv__stream_io);
1206
- assert(stream->write_watcher.data == stream);
1207
- assert(stream->write_watcher.fd == stream->fd);
1208
-
1209
- /* If the queue was empty when this function began, we should attempt to
1210
- * do the write immediately. Otherwise start the write_watcher and wait
1211
- * for the fd to become writable.
1212
- */
1213
- if (empty_queue) {
1214
- if (uv__write(stream)) {
1215
- /* Error. uv_last_error has been set. */
1216
- return -1;
1217
- }
1218
- }
1219
-
1220
- /* If the queue is now empty - we've flushed the request already. That
1221
- * means we need to make the callback. The callback can only be done on a
1222
- * fresh stack so we feed the event loop in order to service it.
1223
- */
1224
- if (ngx_queue_empty(&stream->write_queue)) {
1225
- ev_feed_event(EV_DEFAULT_ &stream->write_watcher, EV_WRITE);
1226
- } else {
1227
- /* Otherwise there is data to write - so we should wait for the file
1228
- * descriptor to become writable.
1229
- */
1230
- ev_io_start(EV_DEFAULT_ &stream->write_watcher);
1231
- }
1232
-
1233
- return 0;
1234
- }
1235
-
1236
-
1237
- void uv_ref() {
1238
- ev_ref(EV_DEFAULT_UC);
1239
- }
1240
-
1241
-
1242
- void uv_unref() {
1243
- ev_unref(EV_DEFAULT_UC);
1244
- }
1245
-
1246
-
1247
- void uv_update_time() {
1248
- ev_now_update(EV_DEFAULT_UC);
1249
- }
1250
-
1251
-
1252
- int64_t uv_now() {
1253
- return (int64_t)(ev_now(EV_DEFAULT_UC) * 1000);
1254
- }
1255
-
1256
-
1257
- int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
1258
- assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);
1259
-
1260
- /* The UV_READING flag is irrelevant of the state of the tcp - it just
1261
- * expresses the desired state of the user.
1262
- */
1263
- ((uv_handle_t*)stream)->flags |= UV_READING;
1264
-
1265
- /* TODO: try to do the read inline? */
1266
- /* TODO: keep track of tcp state. If we've gotten a EOF then we should
1267
- * not start the IO watcher.
1268
- */
1269
- assert(stream->fd >= 0);
1270
- assert(alloc_cb);
1271
-
1272
- stream->read_cb = read_cb;
1273
- stream->alloc_cb = alloc_cb;
1274
-
1275
- /* These should have been set by uv_tcp_init. */
1276
- assert(stream->read_watcher.cb == uv__stream_io);
1277
-
1278
- ev_io_start(EV_DEFAULT_UC_ &stream->read_watcher);
1279
- return 0;
1280
- }
1281
-
1282
-
1283
- int uv_read_stop(uv_stream_t* stream) {
1284
- uv_tcp_t* tcp = (uv_tcp_t*)stream;
1285
-
1286
- ((uv_handle_t*)tcp)->flags &= ~UV_READING;
1287
-
1288
- ev_io_stop(EV_DEFAULT_UC_ &tcp->read_watcher);
1289
- tcp->read_cb = NULL;
1290
- tcp->alloc_cb = NULL;
1291
- return 0;
1292
- }
1293
-
1294
-
1295
- void uv__req_init(uv_req_t* req) {
1296
- uv_counters()->req_init++;
1297
- req->type = UV_UNKNOWN_REQ;
1298
- req->data = NULL;
1299
- }
1300
-
1301
-
1302
- static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
1303
- uv_prepare_t* prepare = w->data;
1304
-
1305
- if (prepare->prepare_cb) {
1306
- prepare->prepare_cb(prepare, 0);
1307
- }
1308
- }
1309
-
1310
-
1311
- int uv_prepare_init(uv_prepare_t* prepare) {
1312
- uv__handle_init((uv_handle_t*)prepare, UV_PREPARE);
1313
- uv_counters()->prepare_init++;
1314
-
1315
- ev_prepare_init(&prepare->prepare_watcher, uv__prepare);
1316
- prepare->prepare_watcher.data = prepare;
1317
-
1318
- prepare->prepare_cb = NULL;
1319
-
1320
- return 0;
1321
- }
1322
-
1323
-
1324
- int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
1325
- int was_active = ev_is_active(&prepare->prepare_watcher);
1326
-
1327
- prepare->prepare_cb = cb;
1328
-
1329
- ev_prepare_start(EV_DEFAULT_UC_ &prepare->prepare_watcher);
1330
-
1331
- if (!was_active) {
1332
- ev_unref(EV_DEFAULT_UC);
1333
- }
1334
-
1335
- return 0;
1336
- }
1337
-
1338
-
1339
- int uv_prepare_stop(uv_prepare_t* prepare) {
1340
- int was_active = ev_is_active(&prepare->prepare_watcher);
1341
-
1342
- ev_prepare_stop(EV_DEFAULT_UC_ &prepare->prepare_watcher);
1343
-
1344
- if (was_active) {
1345
- ev_ref(EV_DEFAULT_UC);
1346
- }
1347
- return 0;
1348
- }
1349
-
1350
-
1351
-
1352
- static void uv__check(EV_P_ ev_check* w, int revents) {
1353
- uv_check_t* check = w->data;
1354
-
1355
- if (check->check_cb) {
1356
- check->check_cb(check, 0);
1357
- }
1358
- }
1359
-
1360
-
1361
- int uv_check_init(uv_check_t* check) {
1362
- uv__handle_init((uv_handle_t*)check, UV_CHECK);
1363
- uv_counters()->check_init++;
1364
-
1365
- ev_check_init(&check->check_watcher, uv__check);
1366
- check->check_watcher.data = check;
1367
-
1368
- check->check_cb = NULL;
1369
-
1370
- return 0;
1371
- }
1372
-
1373
-
1374
- int uv_check_start(uv_check_t* check, uv_check_cb cb) {
1375
- int was_active = ev_is_active(&check->check_watcher);
1376
-
1377
- check->check_cb = cb;
1378
-
1379
- ev_check_start(EV_DEFAULT_UC_ &check->check_watcher);
1380
-
1381
- if (!was_active) {
1382
- ev_unref(EV_DEFAULT_UC);
1383
- }
1384
-
1385
- return 0;
1386
- }
1387
-
1388
-
1389
- int uv_check_stop(uv_check_t* check) {
1390
- int was_active = ev_is_active(&check->check_watcher);
1391
-
1392
- ev_check_stop(EV_DEFAULT_UC_ &check->check_watcher);
1393
-
1394
- if (was_active) {
1395
- ev_ref(EV_DEFAULT_UC);
1396
- }
1397
-
1398
- return 0;
1399
- }
1400
-
1401
-
1402
- static void uv__idle(EV_P_ ev_idle* w, int revents) {
1403
- uv_idle_t* idle = (uv_idle_t*)(w->data);
1404
-
1405
- if (idle->idle_cb) {
1406
- idle->idle_cb(idle, 0);
1407
- }
1408
- }
1409
-
1410
-
1411
-
1412
- int uv_idle_init(uv_idle_t* idle) {
1413
- uv__handle_init((uv_handle_t*)idle, UV_IDLE);
1414
- uv_counters()->idle_init++;
1415
-
1416
- ev_idle_init(&idle->idle_watcher, uv__idle);
1417
- idle->idle_watcher.data = idle;
1418
-
1419
- idle->idle_cb = NULL;
1420
-
1421
- return 0;
1422
- }
1423
-
1424
-
1425
- int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
1426
- int was_active = ev_is_active(&idle->idle_watcher);
1427
-
1428
- idle->idle_cb = cb;
1429
- ev_idle_start(EV_DEFAULT_UC_ &idle->idle_watcher);
1430
-
1431
- if (!was_active) {
1432
- ev_unref(EV_DEFAULT_UC);
1433
- }
1434
-
1435
- return 0;
1436
- }
1437
-
1438
-
1439
- int uv_idle_stop(uv_idle_t* idle) {
1440
- int was_active = ev_is_active(&idle->idle_watcher);
1441
-
1442
- ev_idle_stop(EV_DEFAULT_UC_ &idle->idle_watcher);
1443
-
1444
- if (was_active) {
1445
- ev_ref(EV_DEFAULT_UC);
1446
- }
1447
-
1448
- return 0;
1449
- }
1450
-
1451
-
1452
- int uv_is_active(uv_handle_t* handle) {
1453
- switch (handle->type) {
1454
- case UV_TIMER:
1455
- return ev_is_active(&((uv_timer_t*)handle)->timer_watcher);
1456
-
1457
- case UV_PREPARE:
1458
- return ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher);
1459
-
1460
- case UV_CHECK:
1461
- return ev_is_active(&((uv_check_t*)handle)->check_watcher);
1462
-
1463
- case UV_IDLE:
1464
- return ev_is_active(&((uv_idle_t*)handle)->idle_watcher);
1465
-
1466
- default:
1467
- return 1;
1468
- }
1469
- }
1470
-
1471
-
1472
- static void uv__async(EV_P_ ev_async* w, int revents) {
1473
- uv_async_t* async = w->data;
1474
-
1475
- if (async->async_cb) {
1476
- async->async_cb(async, 0);
1477
- }
1478
- }
1479
-
1480
-
1481
- int uv_async_init(uv_async_t* async, uv_async_cb async_cb) {
1482
- uv__handle_init((uv_handle_t*)async, UV_ASYNC);
1483
- uv_counters()->async_init++;
1484
-
1485
- ev_async_init(&async->async_watcher, uv__async);
1486
- async->async_watcher.data = async;
1487
-
1488
- async->async_cb = async_cb;
1489
-
1490
- /* Note: This does not have symmetry with the other libev wrappers. */
1491
- ev_async_start(EV_DEFAULT_UC_ &async->async_watcher);
1492
- ev_unref(EV_DEFAULT_UC);
1493
-
1494
- return 0;
1495
- }
1496
-
1497
-
1498
- int uv_async_send(uv_async_t* async) {
1499
- ev_async_send(EV_DEFAULT_UC_ &async->async_watcher);
1500
- return 0;
1501
- }
1502
-
1503
-
1504
- static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
1505
- uv_timer_t* timer = w->data;
1506
-
1507
- if (!ev_is_active(w)) {
1508
- ev_ref(EV_DEFAULT_UC);
1509
- }
1510
-
1511
- if (timer->timer_cb) {
1512
- timer->timer_cb(timer, 0);
1513
- }
1514
- }
1515
-
1516
-
1517
- int uv_timer_init(uv_timer_t* timer) {
1518
- uv__handle_init((uv_handle_t*)timer, UV_TIMER);
1519
- uv_counters()->timer_init++;
1520
-
1521
- ev_init(&timer->timer_watcher, uv__timer_cb);
1522
- timer->timer_watcher.data = timer;
1523
-
1524
- return 0;
1525
- }
1526
-
1527
-
1528
- int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
1529
- int64_t repeat) {
1530
- if (ev_is_active(&timer->timer_watcher)) {
1531
- return -1;
1532
- }
1533
-
1534
- timer->timer_cb = cb;
1535
- ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
1536
- ev_timer_start(EV_DEFAULT_UC_ &timer->timer_watcher);
1537
- ev_unref(EV_DEFAULT_UC);
1538
- return 0;
1539
- }
1540
-
1541
-
1542
- int uv_timer_stop(uv_timer_t* timer) {
1543
- if (ev_is_active(&timer->timer_watcher)) {
1544
- ev_ref(EV_DEFAULT_UC);
1545
- }
1546
-
1547
- ev_timer_stop(EV_DEFAULT_UC_ &timer->timer_watcher);
1548
- return 0;
1549
- }
1550
-
1551
-
1552
- int uv_timer_again(uv_timer_t* timer) {
1553
- if (!ev_is_active(&timer->timer_watcher)) {
1554
- uv_err_new((uv_handle_t*)timer, EINVAL);
1555
- return -1;
1556
- }
1557
-
1558
- ev_timer_again(EV_DEFAULT_UC_ &timer->timer_watcher);
1559
- return 0;
1560
- }
1561
-
1562
- void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) {
1563
- assert(timer->type == UV_TIMER);
1564
- timer->timer_watcher.repeat = repeat / 1000.0;
1565
- }
1566
-
1567
- int64_t uv_timer_get_repeat(uv_timer_t* timer) {
1568
- assert(timer->type == UV_TIMER);
1569
- return (int64_t)(1000 * timer->timer_watcher.repeat);
1570
- }
1571
-
1572
-
1573
- /*
1574
- * This is called once per second by ares_data.timer. It is used to
1575
- * constantly callback into c-ares for possibly processing timeouts.
1576
- */
1577
- static void uv__ares_timeout(EV_P_ struct ev_timer* watcher, int revents) {
1578
- assert(watcher == &ares_data.timer);
1579
- assert(revents == EV_TIMER);
1580
- assert(!uv_ares_handles_empty());
1581
- ares_process_fd(ares_data.channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
1582
- }
1583
-
1584
-
1585
- static void uv__ares_io(EV_P_ struct ev_io* watcher, int revents) {
1586
- /* Reset the idle timer */
1587
- ev_timer_again(EV_A_ &ares_data.timer);
1588
-
1589
- /* Process DNS responses */
1590
- ares_process_fd(ares_data.channel,
1591
- revents & EV_READ ? watcher->fd : ARES_SOCKET_BAD,
1592
- revents & EV_WRITE ? watcher->fd : ARES_SOCKET_BAD);
1593
- }
1594
-
1595
-
1596
- /* Allocates and returns a new uv_ares_task_t */
1597
- static uv_ares_task_t* uv__ares_task_create(int fd) {
1598
- uv_ares_task_t* h = malloc(sizeof(uv_ares_task_t));
1599
-
1600
- if (h == NULL) {
1601
- uv_fatal_error(ENOMEM, "malloc");
1602
- }
1603
-
1604
- h->sock = fd;
1605
-
1606
- ev_io_init(&h->read_watcher, uv__ares_io, fd, EV_READ);
1607
- ev_io_init(&h->write_watcher, uv__ares_io, fd, EV_WRITE);
1608
-
1609
- h->read_watcher.data = h;
1610
- h->write_watcher.data = h;
1611
-
1612
- return h;
1613
- }
1614
-
1615
-
1616
- /* Callback from ares when socket operation is started */
1617
- static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
1618
- int read, int write) {
1619
- uv_ares_task_t* h = uv_find_ares_handle(sock);
1620
-
1621
- if (read || write) {
1622
- if (!h) {
1623
- /* New socket */
1624
-
1625
- /* If this is the first socket then start the timer. */
1626
- if (!ev_is_active(&ares_data.timer)) {
1627
- assert(uv_ares_handles_empty());
1628
- ev_timer_again(EV_DEFAULT_UC_ &ares_data.timer);
1629
- }
1630
-
1631
- h = uv__ares_task_create(sock);
1632
- uv_add_ares_handle(h);
1633
- }
1634
-
1635
- if (read) {
1636
- ev_io_start(EV_DEFAULT_UC_ &h->read_watcher);
1637
- } else {
1638
- ev_io_stop(EV_DEFAULT_UC_ &h->read_watcher);
1639
- }
1640
-
1641
- if (write) {
1642
- ev_io_start(EV_DEFAULT_UC_ &h->write_watcher);
1643
- } else {
1644
- ev_io_stop(EV_DEFAULT_UC_ &h->write_watcher);
1645
- }
1646
-
1647
- } else {
1648
- /*
1649
- * read == 0 and write == 0 this is c-ares's way of notifying us that
1650
- * the socket is now closed. We must free the data associated with
1651
- * socket.
1652
- */
1653
- assert(h && "When an ares socket is closed we should have a handle for it");
1654
-
1655
- ev_io_stop(EV_DEFAULT_UC_ &h->read_watcher);
1656
- ev_io_stop(EV_DEFAULT_UC_ &h->write_watcher);
1657
-
1658
- uv_remove_ares_handle(h);
1659
- free(h);
1660
-
1661
- if (uv_ares_handles_empty()) {
1662
- ev_timer_stop(EV_DEFAULT_UC_ &ares_data.timer);
1663
- }
1664
- }
1665
- }
1666
-
1667
-
1668
- /* c-ares integration initialize and terminate */
1669
- /* TODO: share this with windows? */
1670
- int uv_ares_init_options(ares_channel *channelptr,
1671
- struct ares_options *options,
1672
- int optmask) {
1673
- int rc;
1674
-
1675
- /* only allow single init at a time */
1676
- if (ares_data.channel != NULL) {
1677
- uv_err_new_artificial(NULL, UV_EALREADY);
1678
- return -1;
1679
- }
1680
-
1681
- /* set our callback as an option */
1682
- options->sock_state_cb = uv__ares_sockstate_cb;
1683
- options->sock_state_cb_data = &ares_data;
1684
- optmask |= ARES_OPT_SOCK_STATE_CB;
1685
-
1686
- /* We do the call to ares_init_option for caller. */
1687
- rc = ares_init_options(channelptr, options, optmask);
1688
-
1689
- /* if success, save channel */
1690
- if (rc == ARES_SUCCESS) {
1691
- ares_data.channel = *channelptr;
1692
- }
1693
-
1694
- /*
1695
- * Initialize the timeout timer. The timer won't be started until the
1696
- * first socket is opened.
1697
- */
1698
- ev_init(&ares_data.timer, uv__ares_timeout);
1699
- ares_data.timer.repeat = 1.0;
1700
-
1701
- return rc;
1702
- }
1703
-
1704
-
1705
- /* TODO share this with windows? */
1706
- void uv_ares_destroy(ares_channel channel) {
1707
- /* only allow destroy if did init */
1708
- if (ares_data.channel != NULL) {
1709
- ev_timer_stop(EV_DEFAULT_UC_ &ares_data.timer);
1710
- ares_destroy(channel);
1711
- ares_data.channel = NULL;
1712
- }
1713
- }
1714
-
1715
-
1716
- static int uv_getaddrinfo_done(eio_req* req) {
1717
- uv_getaddrinfo_t* handle = req->data;
1718
-
1719
- uv_unref();
1720
-
1721
- free(handle->hints);
1722
- free(handle->service);
1723
- free(handle->hostname);
1724
-
1725
- if (handle->retcode != 0) {
1726
- /* TODO how to display gai error strings? */
1727
- uv_err_new(NULL, handle->retcode);
1728
- }
1729
-
1730
- handle->cb(handle, handle->retcode, handle->res);
1731
-
1732
- freeaddrinfo(handle->res);
1733
- handle->res = NULL;
1734
-
1735
- return 0;
1736
- }
1737
-
1738
-
1739
- static void getaddrinfo_thread_proc(eio_req *req) {
1740
- uv_getaddrinfo_t* handle = req->data;
1741
-
1742
- handle->retcode = getaddrinfo(handle->hostname,
1743
- handle->service,
1744
- handle->hints,
1745
- &handle->res);
1746
- }
1747
-
1748
-
1749
- /* stub implementation of uv_getaddrinfo */
1750
- int uv_getaddrinfo(uv_getaddrinfo_t* handle,
1751
- uv_getaddrinfo_cb cb,
1752
- const char* hostname,
1753
- const char* service,
1754
- const struct addrinfo* hints) {
1755
- eio_req* req;
1756
- uv_eio_init();
1757
-
1758
- if (handle == NULL || cb == NULL ||
1759
- (hostname == NULL && service == NULL)) {
1760
- uv_err_new_artificial(NULL, UV_EINVAL);
1761
- return -1;
1762
- }
1763
-
1764
- memset(handle, 0, sizeof(uv_getaddrinfo_t));
1765
-
1766
- /* TODO don't alloc so much. */
1767
-
1768
- if (hints) {
1769
- handle->hints = malloc(sizeof(struct addrinfo));
1770
- memcpy(&handle->hints, hints, sizeof(struct addrinfo));
1771
- }
1772
-
1773
- /* TODO security! check lengths, check return values. */
1774
-
1775
- handle->cb = cb;
1776
- handle->hostname = hostname ? strdup(hostname) : NULL;
1777
- handle->service = service ? strdup(service) : NULL;
1778
-
1779
- /* TODO check handle->hostname == NULL */
1780
- /* TODO check handle->service == NULL */
1781
-
1782
- uv_ref();
1783
-
1784
- req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
1785
- uv_getaddrinfo_done, handle);
1786
- assert(req);
1787
- assert(req->data == handle);
1788
-
1789
- return 0;
1790
- }
1791
-
1792
-
1793
- int uv_pipe_init(uv_pipe_t* handle) {
1794
- memset(handle, 0, sizeof *handle);
1795
-
1796
- uv__handle_init((uv_handle_t*)handle, UV_NAMED_PIPE);
1797
- uv_counters()->pipe_init++;
1798
-
1799
- handle->type = UV_NAMED_PIPE;
1800
- handle->pipe_fname = NULL; /* Only set by listener. */
1801
-
1802
- ev_init(&handle->write_watcher, uv__stream_io);
1803
- ev_init(&handle->read_watcher, uv__stream_io);
1804
- handle->write_watcher.data = handle;
1805
- handle->read_watcher.data = handle;
1806
- handle->accepted_fd = -1;
1807
- handle->fd = -1;
1808
-
1809
- ngx_queue_init(&handle->write_completed_queue);
1810
- ngx_queue_init(&handle->write_queue);
1811
-
1812
- return 0;
1813
- }
1814
-
1815
-
1816
- int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
1817
- struct sockaddr_un sun;
1818
- const char* pipe_fname;
1819
- int saved_errno;
1820
- int locked;
1821
- int sockfd;
1822
- int status;
1823
- int bound;
1824
-
1825
- saved_errno = errno;
1826
- pipe_fname = NULL;
1827
- sockfd = -1;
1828
- status = -1;
1829
- bound = 0;
1830
-
1831
- /* Already bound? */
1832
- if (handle->fd >= 0) {
1833
- uv_err_new_artificial((uv_handle_t*)handle, UV_EINVAL);
1834
- goto out;
1835
- }
1836
-
1837
- /* Make a copy of the file name, it outlives this function's scope. */
1838
- if ((pipe_fname = strdup(name)) == NULL) {
1839
- uv_err_new((uv_handle_t*)handle, ENOMEM);
1840
- goto out;
1841
- }
1842
-
1843
- /* We've got a copy, don't touch the original any more. */
1844
- name = NULL;
1845
-
1846
- if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
1847
- uv_err_new((uv_handle_t*)handle, errno);
1848
- goto out;
1849
- }
1850
-
1851
- memset(&sun, 0, sizeof sun);
1852
- uv__strlcpy(sun.sun_path, pipe_fname, sizeof(sun.sun_path));
1853
- sun.sun_family = AF_UNIX;
1854
-
1855
- if (bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
1856
- /* On EADDRINUSE:
1857
- *
1858
- * We hold the file lock so there is no other process listening
1859
- * on the socket. Ergo, it's stale - remove it.
1860
- *
1861
- * This assumes that the other process uses locking too
1862
- * but that's a good enough assumption for now.
1863
- */
1864
- if (errno != EADDRINUSE
1865
- || unlink(pipe_fname) == -1
1866
- || bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
1867
- /* Convert ENOENT to EACCES for compatibility with Windows. */
1868
- uv_err_new((uv_handle_t*)handle, (errno == ENOENT) ? EACCES : errno);
1869
- goto out;
1870
- }
1871
- }
1872
- bound = 1;
1873
-
1874
- /* Success. */
1875
- handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
1876
- handle->fd = sockfd;
1877
- status = 0;
1878
-
1879
- out:
1880
- /* Clean up on error. */
1881
- if (status) {
1882
- if (bound) {
1883
- /* unlink() before close() to avoid races. */
1884
- assert(pipe_fname != NULL);
1885
- unlink(pipe_fname);
1886
- }
1887
- uv__close(sockfd);
1888
-
1889
- free((void*)pipe_fname);
1890
- }
1891
-
1892
- errno = saved_errno;
1893
- return status;
1894
- }
1895
-
1896
-
1897
- static int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
1898
- int saved_errno;
1899
- int status;
1900
-
1901
- saved_errno = errno;
1902
- status = -1;
1903
-
1904
- if (handle->fd == -1) {
1905
- uv_err_new_artificial((uv_handle_t*)handle, UV_EINVAL);
1906
- goto out;
1907
- }
1908
- assert(handle->fd >= 0);
1909
-
1910
- if ((status = listen(handle->fd, backlog)) == -1) {
1911
- uv_err_new((uv_handle_t*)handle, errno);
1912
- } else {
1913
- handle->connection_cb = cb;
1914
- ev_io_init(&handle->read_watcher, uv__pipe_accept, handle->fd, EV_READ);
1915
- ev_io_start(EV_DEFAULT_ &handle->read_watcher);
1916
- }
1917
-
1918
- out:
1919
- errno = saved_errno;
1920
- return status;
1921
- }
1922
-
1923
-
1924
- static int uv_pipe_cleanup(uv_pipe_t* handle) {
1925
- int saved_errno;
1926
- int status;
1927
-
1928
- saved_errno = errno;
1929
- status = -1;
1930
-
1931
- if (handle->pipe_fname) {
1932
- /*
1933
- * Unlink the file system entity before closing the file descriptor.
1934
- * Doing it the other way around introduces a race where our process
1935
- * unlinks a socket with the same name that's just been created by
1936
- * another thread or process.
1937
- *
1938
- * This is less of an issue now that we attach a file lock
1939
- * to the socket but it's still a best practice.
1940
- */
1941
- unlink(handle->pipe_fname);
1942
- free((void*)handle->pipe_fname);
1943
- }
1944
-
1945
- errno = saved_errno;
1946
- return status;
1947
- }
1948
-
1949
-
1950
- int uv_pipe_connect(uv_connect_t* req,
1951
- uv_pipe_t* handle,
1952
- const char* name,
1953
- uv_connect_cb cb) {
1954
- struct sockaddr_un sun;
1955
- int saved_errno;
1956
- int sockfd;
1957
- int status;
1958
- int r;
1959
-
1960
- saved_errno = errno;
1961
- sockfd = -1;
1962
- status = -1;
1963
-
1964
- if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
1965
- uv_err_new((uv_handle_t*)handle, errno);
1966
- goto out;
1967
- }
1968
-
1969
- memset(&sun, 0, sizeof sun);
1970
- uv__strlcpy(sun.sun_path, name, sizeof(sun.sun_path));
1971
- sun.sun_family = AF_UNIX;
1972
-
1973
- /* We don't check for EINPROGRESS. Think about it: the socket
1974
- * is either there or not.
1975
- */
1976
- do {
1977
- r = connect(sockfd, (struct sockaddr*)&sun, sizeof sun);
1978
- }
1979
- while (r == -1 && errno == EINTR);
1980
-
1981
- if (r == -1) {
1982
- uv_err_new((uv_handle_t*)handle, errno);
1983
- uv__close(sockfd);
1984
- goto out;
1985
- }
1986
-
1987
- uv__stream_open((uv_stream_t*)handle, sockfd, UV_READABLE | UV_WRITABLE);
1988
-
1989
- ev_io_start(EV_DEFAULT_ &handle->read_watcher);
1990
- ev_io_start(EV_DEFAULT_ &handle->write_watcher);
1991
-
1992
- status = 0;
1993
-
1994
- out:
1995
- handle->delayed_error = status; /* Passed to callback. */
1996
- handle->connect_req = req;
1997
- req->handle = (uv_stream_t*)handle;
1998
- req->type = UV_CONNECT;
1999
- req->cb = cb;
2000
- ngx_queue_init(&req->queue);
2001
-
2002
- /* Run callback on next tick. */
2003
- ev_feed_event(EV_DEFAULT_ &handle->read_watcher, EV_CUSTOM);
2004
- assert(ev_is_pending(&handle->read_watcher));
2005
-
2006
- /* Mimic the Windows pipe implementation, always
2007
- * return 0 and let the callback handle errors.
2008
- */
2009
- errno = saved_errno;
2010
- return 0;
2011
- }
2012
-
2013
-
2014
- /* TODO merge with uv__server_io()? */
2015
- static void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
2016
- struct sockaddr_un sun;
2017
- uv_pipe_t* pipe;
2018
- int saved_errno;
2019
- int sockfd;
2020
-
2021
- saved_errno = errno;
2022
- pipe = watcher->data;
2023
-
2024
- assert(pipe->type == UV_NAMED_PIPE);
2025
- assert(pipe->pipe_fname != NULL);
2026
-
2027
- sockfd = uv__accept(pipe->fd, (struct sockaddr *)&sun, sizeof sun);
2028
- if (sockfd == -1) {
2029
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
2030
- assert(0 && "EAGAIN on uv__accept(pipefd)");
2031
- } else {
2032
- uv_err_new((uv_handle_t*)pipe, errno);
2033
- }
2034
- } else {
2035
- pipe->accepted_fd = sockfd;
2036
- pipe->connection_cb((uv_stream_t*)pipe, 0);
2037
- if (pipe->accepted_fd == sockfd) {
2038
- /* The user hasn't yet accepted called uv_accept() */
2039
- ev_io_stop(EV_DEFAULT_ &pipe->read_watcher);
2040
- }
2041
- }
2042
-
2043
- errno = saved_errno;
2044
- }
2045
-
2046
-
2047
- /* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
2048
- static int uv__socket(int domain, int type, int protocol) {
2049
- #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2050
- return socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
2051
- #else
2052
- int sockfd;
2053
-
2054
- if ((sockfd = socket(domain, type, protocol)) == -1) {
2055
- return -1;
2056
- }
2057
-
2058
- if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) {
2059
- uv__close(sockfd);
2060
- return -1;
2061
- }
2062
-
2063
- return sockfd;
2064
- #endif
2065
- }
2066
-
2067
-
2068
- static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
2069
- int peerfd;
2070
-
2071
- assert(sockfd >= 0);
2072
-
2073
- do {
2074
- #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2075
- peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
2076
- #else
2077
- if ((peerfd = accept(sockfd, saddr, &slen)) != -1) {
2078
- if (uv__cloexec(peerfd, 1) == -1 || uv__nonblock(peerfd, 1) == -1) {
2079
- uv__close(peerfd);
2080
- return -1;
2081
- }
2082
- }
2083
- #endif
2084
- }
2085
- while (peerfd == -1 && errno == EINTR);
2086
-
2087
- return peerfd;
2088
- }
2089
-
2090
-
2091
- static int uv__close(int fd) {
2092
- int status;
2093
-
2094
- /*
2095
- * Retry on EINTR. You may think this is academic but on linux
2096
- * and probably other Unices too, close(2) is interruptible.
2097
- * Failing to handle EINTR is a common source of fd leaks.
2098
- */
2099
- do {
2100
- status = close(fd);
2101
- }
2102
- while (status == -1 && errno == EINTR);
2103
-
2104
- return status;
2105
- }
2106
-
2107
-
2108
- static int uv__nonblock(int fd, int set) {
2109
- int flags;
2110
-
2111
- if ((flags = fcntl(fd, F_GETFL)) == -1) {
2112
- return -1;
2113
- }
2114
-
2115
- if (set) {
2116
- flags |= O_NONBLOCK;
2117
- } else {
2118
- flags &= ~O_NONBLOCK;
2119
- }
2120
-
2121
- if (fcntl(fd, F_SETFL, flags) == -1) {
2122
- return -1;
2123
- }
2124
-
2125
- return 0;
2126
- }
2127
-
2128
-
2129
- static int uv__cloexec(int fd, int set) {
2130
- int flags;
2131
-
2132
- if ((flags = fcntl(fd, F_GETFD)) == -1) {
2133
- return -1;
2134
- }
2135
-
2136
- if (set) {
2137
- flags |= FD_CLOEXEC;
2138
- } else {
2139
- flags &= ~FD_CLOEXEC;
2140
- }
2141
-
2142
- if (fcntl(fd, F_SETFD, flags) == -1) {
2143
- return -1;
2144
- }
2145
-
2146
- return 0;
2147
- }
2148
-
2149
-
2150
- /* TODO move to uv-common.c? */
2151
- size_t uv__strlcpy(char* dst, const char* src, size_t size) {
2152
- const char *org;
2153
-
2154
- if (size == 0) {
2155
- return 0;
2156
- }
2157
-
2158
- org = src;
2159
- while (size > 1) {
2160
- if ((*dst++ = *src++) == '\0') {
2161
- return org - src;
2162
- }
2163
- }
2164
- *dst = '\0';
2165
-
2166
- return src - org;
2167
- }
2168
-
2169
-
2170
- uv_stream_t* uv_std_handle(uv_std_type type) {
2171
- assert(0 && "implement me");
2172
- return NULL;
2173
- }
2174
-
2175
-
2176
- static void uv__chld(EV_P_ ev_child* watcher, int revents) {
2177
- int status = watcher->rstatus;
2178
- int exit_status = 0;
2179
- int term_signal = 0;
2180
- uv_process_t *process = watcher->data;
2181
-
2182
- assert(&process->child_watcher == watcher);
2183
- assert(revents & EV_CHILD);
2184
-
2185
- ev_child_stop(EV_A_ &process->child_watcher);
2186
-
2187
- if (WIFEXITED(status)) {
2188
- exit_status = WEXITSTATUS(status);
2189
- }
2190
-
2191
- if (WIFSIGNALED(status)) {
2192
- term_signal = WTERMSIG(status);
2193
- }
2194
-
2195
- if (process->exit_cb) {
2196
- process->exit_cb(process, exit_status, term_signal);
2197
- }
2198
- }
2199
-
2200
- #ifndef SPAWN_WAIT_EXEC
2201
- # define SPAWN_WAIT_EXEC 1
2202
- #endif
2203
-
2204
- int uv_spawn(uv_process_t* process, uv_process_options_t options) {
2205
- /*
2206
- * Save environ in the case that we get it clobbered
2207
- * by the child process.
2208
- */
2209
- char** save_our_env = environ;
2210
- int stdin_pipe[2] = { -1, -1 };
2211
- int stdout_pipe[2] = { -1, -1 };
2212
- int stderr_pipe[2] = { -1, -1 };
2213
- #if SPAWN_WAIT_EXEC
2214
- int signal_pipe[2] = { -1, -1 };
2215
- struct pollfd pfd;
2216
- #endif
2217
- int status;
2218
- pid_t pid;
2219
-
2220
- uv__handle_init((uv_handle_t*)process, UV_PROCESS);
2221
- uv_counters()->process_init++;
2222
-
2223
- process->exit_cb = options.exit_cb;
2224
-
2225
- if (options.stdin_stream) {
2226
- if (options.stdin_stream->type != UV_NAMED_PIPE) {
2227
- errno = EINVAL;
2228
- goto error;
2229
- }
2230
-
2231
- if (pipe(stdin_pipe) < 0) {
2232
- goto error;
2233
- }
2234
- uv__cloexec(stdin_pipe[0], 1);
2235
- uv__cloexec(stdin_pipe[1], 1);
2236
- }
2237
-
2238
- if (options.stdout_stream) {
2239
- if (options.stdout_stream->type != UV_NAMED_PIPE) {
2240
- errno = EINVAL;
2241
- goto error;
2242
- }
2243
-
2244
- if (pipe(stdout_pipe) < 0) {
2245
- goto error;
2246
- }
2247
- uv__cloexec(stdout_pipe[0], 1);
2248
- uv__cloexec(stdout_pipe[1], 1);
2249
- }
2250
-
2251
- if (options.stderr_stream) {
2252
- if (options.stderr_stream->type != UV_NAMED_PIPE) {
2253
- errno = EINVAL;
2254
- goto error;
2255
- }
2256
-
2257
- if (pipe(stderr_pipe) < 0) {
2258
- goto error;
2259
- }
2260
- uv__cloexec(stderr_pipe[0], 1);
2261
- uv__cloexec(stderr_pipe[1], 1);
2262
- }
2263
-
2264
- /* This pipe is used by the parent to wait until
2265
- * the child has called `execve()`. We need this
2266
- * to avoid the following race condition:
2267
- *
2268
- * if ((pid = fork()) > 0) {
2269
- * kill(pid, SIGTERM);
2270
- * }
2271
- * else if (pid == 0) {
2272
- * execve("/bin/cat", argp, envp);
2273
- * }
2274
- *
2275
- * The parent sends a signal immediately after forking.
2276
- * Since the child may not have called `execve()` yet,
2277
- * there is no telling what process receives the signal,
2278
- * our fork or /bin/cat.
2279
- *
2280
- * To avoid ambiguity, we create a pipe with both ends
2281
- * marked close-on-exec. Then, after the call to `fork()`,
2282
- * the parent polls the read end until it sees POLLHUP.
2283
- */
2284
- #if SPAWN_WAIT_EXEC
2285
- # ifdef HAVE_PIPE2
2286
- if (pipe2(signal_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
2287
- goto error;
2288
- }
2289
- # else
2290
- if (pipe(signal_pipe) < 0) {
2291
- goto error;
2292
- }
2293
- uv__cloexec(signal_pipe[0], 1);
2294
- uv__cloexec(signal_pipe[1], 1);
2295
- uv__nonblock(signal_pipe[0], 1);
2296
- uv__nonblock(signal_pipe[1], 1);
2297
- # endif
2298
- #endif
2299
-
2300
- pid = fork();
2301
-
2302
- if (pid == -1) {
2303
- #if SPAWN_WAIT_EXEC
2304
- uv__close(signal_pipe[0]);
2305
- uv__close(signal_pipe[1]);
2306
- #endif
2307
- environ = save_our_env;
2308
- goto error;
2309
- }
2310
-
2311
- if (pid == 0) {
2312
- if (stdin_pipe[0] >= 0) {
2313
- uv__close(stdin_pipe[1]);
2314
- dup2(stdin_pipe[0], STDIN_FILENO);
2315
- }
2316
-
2317
- if (stdout_pipe[1] >= 0) {
2318
- uv__close(stdout_pipe[0]);
2319
- dup2(stdout_pipe[1], STDOUT_FILENO);
2320
- }
2321
-
2322
- if (stderr_pipe[1] >= 0) {
2323
- uv__close(stderr_pipe[0]);
2324
- dup2(stderr_pipe[1], STDERR_FILENO);
2325
- }
2326
-
2327
- if (options.cwd && chdir(options.cwd)) {
2328
- perror("chdir()");
2329
- _exit(127);
2330
- }
2331
-
2332
- environ = options.env;
2333
-
2334
- execvp(options.file, options.args);
2335
- perror("execvp()");
2336
- _exit(127);
2337
- /* Execution never reaches here. */
2338
- }
2339
-
2340
- /* Parent. */
2341
-
2342
- /* Restore environment. */
2343
- environ = save_our_env;
2344
-
2345
- #if SPAWN_WAIT_EXEC
2346
- /* POLLHUP signals child has exited or execve()'d. */
2347
- uv__close(signal_pipe[1]);
2348
- do {
2349
- pfd.fd = signal_pipe[0];
2350
- pfd.events = POLLIN|POLLHUP;
2351
- pfd.revents = 0;
2352
- errno = 0, status = poll(&pfd, 1, -1);
2353
- }
2354
- while (status == -1 && (errno == EINTR || errno == ENOMEM));
2355
-
2356
- uv__close(signal_pipe[0]);
2357
- uv__close(signal_pipe[1]);
2358
-
2359
- assert((status == 1)
2360
- && "poll() on pipe read end failed");
2361
- assert((pfd.revents & POLLHUP) == POLLHUP
2362
- && "no POLLHUP on pipe read end");
2363
- #endif
2364
-
2365
- process->pid = pid;
2366
-
2367
- ev_child_init(&process->child_watcher, uv__chld, pid, 0);
2368
- ev_child_start(EV_DEFAULT_UC_ &process->child_watcher);
2369
- process->child_watcher.data = process;
2370
-
2371
- if (stdin_pipe[1] >= 0) {
2372
- assert(options.stdin_stream);
2373
- assert(stdin_pipe[0] >= 0);
2374
- uv__close(stdin_pipe[0]);
2375
- uv__nonblock(stdin_pipe[1], 1);
2376
- uv__stream_open((uv_stream_t*)options.stdin_stream, stdin_pipe[1],
2377
- UV_WRITABLE);
2378
- }
2379
-
2380
- if (stdout_pipe[0] >= 0) {
2381
- assert(options.stdout_stream);
2382
- assert(stdout_pipe[1] >= 0);
2383
- uv__close(stdout_pipe[1]);
2384
- uv__nonblock(stdout_pipe[0], 1);
2385
- uv__stream_open((uv_stream_t*)options.stdout_stream, stdout_pipe[0],
2386
- UV_READABLE);
2387
- }
2388
-
2389
- if (stderr_pipe[0] >= 0) {
2390
- assert(options.stderr_stream);
2391
- assert(stderr_pipe[1] >= 0);
2392
- uv__close(stderr_pipe[1]);
2393
- uv__nonblock(stderr_pipe[0], 1);
2394
- uv__stream_open((uv_stream_t*)options.stderr_stream, stderr_pipe[0],
2395
- UV_READABLE);
2396
- }
2397
-
2398
- return 0;
2399
-
2400
- error:
2401
- uv_err_new((uv_handle_t*)process, errno);
2402
- uv__close(stdin_pipe[0]);
2403
- uv__close(stdin_pipe[1]);
2404
- uv__close(stdout_pipe[0]);
2405
- uv__close(stdout_pipe[1]);
2406
- uv__close(stderr_pipe[0]);
2407
- uv__close(stderr_pipe[1]);
2408
- return -1;
2409
- }
2410
-
2411
-
2412
- int uv_process_kill(uv_process_t* process, int signum) {
2413
- int r = kill(process->pid, signum);
2414
-
2415
- if (r) {
2416
- uv_err_new((uv_handle_t*)process, errno);
2417
- return -1;
2418
- } else {
2419
- return 0;
2420
- }
2421
- }