passenger 3.0.4 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (571) hide show
  1. data/NEWS +27 -0
  2. data/build/common_library.rb +4 -0
  3. data/doc/ApplicationPool algorithm.txt +1 -1
  4. data/doc/cxxapi/AbstractSpawnManager_8h_source.html +141 -0
  5. data/doc/cxxapi/Account_8h_source.html +206 -0
  6. data/doc/cxxapi/AccountsDatabase_8h_source.html +161 -0
  7. data/doc/cxxapi/AgentBase_8h_source.html +70 -0
  8. data/doc/cxxapi/AgentsStarter_8h_source.html +112 -0
  9. data/doc/cxxapi/BCrypt_8h_source.html +104 -0
  10. data/doc/cxxapi/Blowfish_8h_source.html +134 -0
  11. data/doc/cxxapi/Bucket_8h_source.html +118 -0
  12. data/doc/cxxapi/Constants_8h_source.html +79 -0
  13. data/doc/cxxapi/ContentHandler_8h_source.html +95 -0
  14. data/doc/cxxapi/DirectoryMapper_8h_source.html +311 -0
  15. data/doc/cxxapi/EventedClient_8h_source.html +733 -0
  16. data/doc/cxxapi/EventedMessageServer_8h_source.html +358 -0
  17. data/doc/cxxapi/EventedServer_8h_source.html +326 -0
  18. data/doc/cxxapi/Exceptions_8h_source.html +393 -0
  19. data/doc/cxxapi/FileDescriptor_8h_source.html +324 -0
  20. data/doc/cxxapi/Hooks_8h_source.html +76 -0
  21. data/doc/cxxapi/HttpStatusExtractor_8h_source.html +382 -0
  22. data/doc/cxxapi/IniFile_8h_source.html +527 -0
  23. data/doc/cxxapi/Logging_8h_source.html +796 -0
  24. data/doc/cxxapi/MessageChannel_8h_source.html +776 -0
  25. data/doc/cxxapi/MessageClient_8h_source.html +328 -0
  26. data/doc/cxxapi/MessageReadersWriters_8h_source.html +539 -0
  27. data/doc/cxxapi/MessageServer_8h_source.html +612 -0
  28. data/doc/cxxapi/PoolOptions_8h_source.html +549 -0
  29. data/doc/cxxapi/Process_8h_source.html +286 -0
  30. data/doc/cxxapi/RandomGenerator_8h_source.html +191 -0
  31. data/doc/cxxapi/ResourceLocator_8h_source.html +166 -0
  32. data/doc/cxxapi/SafeLibev_8h_source.html +180 -0
  33. data/doc/cxxapi/ScgiRequestParser_8h_source.html +406 -0
  34. data/doc/cxxapi/ServerInstanceDir_8h_source.html +378 -0
  35. data/doc/cxxapi/Session_8h_source.html +501 -0
  36. data/doc/cxxapi/SpawnManager_8h_source.html +647 -0
  37. data/doc/cxxapi/StaticContentHandler_8h_source.html +68 -0
  38. data/doc/cxxapi/StaticString_8h_source.html +329 -0
  39. data/doc/cxxapi/StringListCreator_8h_source.html +114 -0
  40. data/doc/cxxapi/Utils_8h_source.html +459 -0
  41. data/doc/cxxapi/annotated.html +87 -0
  42. data/doc/cxxapi/apache2_2Configuration_8h_source.html +82 -0
  43. data/doc/cxxapi/classAgentWatcher-members.html +54 -0
  44. data/doc/cxxapi/classAgentWatcher.html +419 -0
  45. data/doc/cxxapi/classClient-members.html +38 -0
  46. data/doc/cxxapi/classClient.html +123 -0
  47. data/doc/cxxapi/classHooks-members.html +40 -0
  48. data/doc/cxxapi/classHooks.html +153 -0
  49. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager-members.html +40 -0
  50. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager.html +187 -0
  51. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.map +3 -0
  52. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.md5 +1 -0
  53. data/doc/cxxapi/classPassenger_1_1AbstractSpawnManager__inherit__graph.png +0 -0
  54. data/doc/cxxapi/classPassenger_1_1ArgumentException-members.html +36 -0
  55. data/doc/cxxapi/classPassenger_1_1ArgumentException.html +56 -0
  56. data/doc/cxxapi/classPassenger_1_1ArrayMessage-members.html +37 -0
  57. data/doc/cxxapi/classPassenger_1_1ArrayMessage.html +113 -0
  58. data/doc/cxxapi/classPassenger_1_1BufferedUpload-members.html +38 -0
  59. data/doc/cxxapi/classPassenger_1_1BufferedUpload.html +112 -0
  60. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +36 -0
  61. data/doc/cxxapi/classPassenger_1_1BusyException.html +54 -0
  62. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +36 -0
  63. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +51 -0
  64. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +41 -0
  65. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +223 -0
  66. data/doc/cxxapi/classPassenger_1_1EOFException-members.html +36 -0
  67. data/doc/cxxapi/classPassenger_1_1EOFException.html +61 -0
  68. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.map +3 -0
  69. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.md5 +1 -0
  70. data/doc/cxxapi/classPassenger_1_1EOFException__inherit__graph.png +0 -0
  71. data/doc/cxxapi/classPassenger_1_1EventFd-members.html +36 -0
  72. data/doc/cxxapi/classPassenger_1_1EventFd.html +52 -0
  73. data/doc/cxxapi/classPassenger_1_1EventedClient-members.html +59 -0
  74. data/doc/cxxapi/classPassenger_1_1EventedClient.html +531 -0
  75. data/doc/cxxapi/classPassenger_1_1EventedMessageServer-members.html +37 -0
  76. data/doc/cxxapi/classPassenger_1_1EventedMessageServer.html +59 -0
  77. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.map +3 -0
  78. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.md5 +1 -0
  79. data/doc/cxxapi/classPassenger_1_1EventedMessageServer__inherit__graph.png +0 -0
  80. data/doc/cxxapi/classPassenger_1_1EventedServer-members.html +37 -0
  81. data/doc/cxxapi/classPassenger_1_1EventedServer.html +93 -0
  82. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.map +3 -0
  83. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.md5 +1 -0
  84. data/doc/cxxapi/classPassenger_1_1EventedServer__inherit__graph.png +0 -0
  85. data/doc/cxxapi/classPassenger_1_1FileDescriptor-members.html +41 -0
  86. data/doc/cxxapi/classPassenger_1_1FileDescriptor.html +178 -0
  87. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair-members.html +36 -0
  88. data/doc/cxxapi/classPassenger_1_1FileDescriptorPair.html +52 -0
  89. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +36 -0
  90. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +58 -0
  91. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.map +3 -0
  92. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.md5 +1 -0
  93. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  94. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +41 -0
  95. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +66 -0
  96. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.map +3 -0
  97. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.md5 +1 -0
  98. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  99. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor-members.html +39 -0
  100. data/doc/cxxapi/classPassenger_1_1HttpStatusExtractor.html +128 -0
  101. data/doc/cxxapi/classPassenger_1_1IOException-members.html +36 -0
  102. data/doc/cxxapi/classPassenger_1_1IOException.html +61 -0
  103. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.map +4 -0
  104. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.md5 +1 -0
  105. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  106. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +57 -0
  107. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +839 -0
  108. data/doc/cxxapi/classPassenger_1_1MessageServer-members.html +49 -0
  109. data/doc/cxxapi/classPassenger_1_1MessageServer.html +407 -0
  110. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext-members.html +36 -0
  111. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext.html +58 -0
  112. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.map +3 -0
  113. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.md5 +1 -0
  114. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1ClientContext__inherit__graph.png +0 -0
  115. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext-members.html +41 -0
  116. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext.html +165 -0
  117. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.map +3 -0
  118. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.md5 +1 -0
  119. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1CommonClientContext__inherit__graph.png +0 -0
  120. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler-members.html +39 -0
  121. data/doc/cxxapi/classPassenger_1_1MessageServer_1_1Handler.html +173 -0
  122. data/doc/cxxapi/classPassenger_1_1Process-members.html +44 -0
  123. data/doc/cxxapi/classPassenger_1_1Process.html +290 -0
  124. data/doc/cxxapi/classPassenger_1_1RandomGenerator-members.html +37 -0
  125. data/doc/cxxapi/classPassenger_1_1RandomGenerator.html +79 -0
  126. data/doc/cxxapi/classPassenger_1_1ResourceLocator-members.html +36 -0
  127. data/doc/cxxapi/classPassenger_1_1ResourceLocator.html +51 -0
  128. data/doc/cxxapi/classPassenger_1_1RuntimeException-members.html +36 -0
  129. data/doc/cxxapi/classPassenger_1_1RuntimeException.html +54 -0
  130. data/doc/cxxapi/classPassenger_1_1SafeLibev-members.html +36 -0
  131. data/doc/cxxapi/classPassenger_1_1SafeLibev.html +51 -0
  132. data/doc/cxxapi/classPassenger_1_1ScalarMessage-members.html +37 -0
  133. data/doc/cxxapi/classPassenger_1_1ScalarMessage.html +76 -0
  134. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser-members.html +50 -0
  135. data/doc/cxxapi/classPassenger_1_1ScgiRequestParser.html +285 -0
  136. data/doc/cxxapi/classPassenger_1_1SecurityException-members.html +36 -0
  137. data/doc/cxxapi/classPassenger_1_1SecurityException.html +56 -0
  138. data/doc/cxxapi/classPassenger_1_1Session-members.html +53 -0
  139. data/doc/cxxapi/classPassenger_1_1Session.html +556 -0
  140. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.map +3 -0
  141. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.md5 +1 -0
  142. data/doc/cxxapi/classPassenger_1_1Session__inherit__graph.png +0 -0
  143. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +39 -0
  144. data/doc/cxxapi/classPassenger_1_1SpawnException.html +101 -0
  145. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +42 -0
  146. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +292 -0
  147. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.map +3 -0
  148. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.md5 +1 -0
  149. data/doc/cxxapi/classPassenger_1_1SpawnManager__inherit__graph.png +0 -0
  150. data/doc/cxxapi/classPassenger_1_1StandardSession-members.html +54 -0
  151. data/doc/cxxapi/classPassenger_1_1StandardSession.html +394 -0
  152. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.map +3 -0
  153. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.md5 +1 -0
  154. data/doc/cxxapi/classPassenger_1_1StandardSession__inherit__graph.png +0 -0
  155. data/doc/cxxapi/classPassenger_1_1StaticString-members.html +36 -0
  156. data/doc/cxxapi/classPassenger_1_1StaticString.html +56 -0
  157. data/doc/cxxapi/classPassenger_1_1SyntaxError-members.html +36 -0
  158. data/doc/cxxapi/classPassenger_1_1SyntaxError.html +54 -0
  159. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +40 -0
  160. data/doc/cxxapi/classPassenger_1_1SystemException.html +155 -0
  161. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.map +4 -0
  162. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.md5 +1 -0
  163. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  164. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException-members.html +40 -0
  165. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException.html +61 -0
  166. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.map +3 -0
  167. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.md5 +1 -0
  168. data/doc/cxxapi/classPassenger_1_1TimeRetrievalException__inherit__graph.png +0 -0
  169. data/doc/cxxapi/classPassenger_1_1TimeoutException-members.html +36 -0
  170. data/doc/cxxapi/classPassenger_1_1TimeoutException.html +54 -0
  171. data/doc/cxxapi/classPassenger_1_1Uint16Message-members.html +36 -0
  172. data/doc/cxxapi/classPassenger_1_1Uint16Message.html +51 -0
  173. data/doc/cxxapi/classPassenger_1_1Uint32Message-members.html +36 -0
  174. data/doc/cxxapi/classPassenger_1_1Uint32Message.html +51 -0
  175. data/doc/cxxapi/classServer-members.html +36 -0
  176. data/doc/cxxapi/classServer.html +49 -0
  177. data/doc/cxxapi/classServerInstanceDirToucher-members.html +36 -0
  178. data/doc/cxxapi/classServerInstanceDirToucher.html +47 -0
  179. data/doc/cxxapi/classes.html +52 -0
  180. data/doc/cxxapi/definitions_8h_source.html +36 -0
  181. data/doc/cxxapi/doxygen.css +532 -0
  182. data/doc/cxxapi/doxygen.png +0 -0
  183. data/doc/cxxapi/files.html +76 -0
  184. data/doc/cxxapi/ftv2blank.png +0 -0
  185. data/doc/cxxapi/ftv2doc.png +0 -0
  186. data/doc/cxxapi/ftv2folderclosed.png +0 -0
  187. data/doc/cxxapi/ftv2folderopen.png +0 -0
  188. data/doc/cxxapi/ftv2lastnode.png +0 -0
  189. data/doc/cxxapi/ftv2link.png +0 -0
  190. data/doc/cxxapi/ftv2mlastnode.png +0 -0
  191. data/doc/cxxapi/ftv2mnode.png +0 -0
  192. data/doc/cxxapi/ftv2node.png +0 -0
  193. data/doc/cxxapi/ftv2plastnode.png +0 -0
  194. data/doc/cxxapi/ftv2pnode.png +0 -0
  195. data/doc/cxxapi/ftv2vertline.png +0 -0
  196. data/doc/cxxapi/functions.html +103 -0
  197. data/doc/cxxapi/functions_0x62.html +82 -0
  198. data/doc/cxxapi/functions_0x63.html +102 -0
  199. data/doc/cxxapi/functions_0x64.html +102 -0
  200. data/doc/cxxapi/functions_0x65.html +88 -0
  201. data/doc/cxxapi/functions_0x66.html +100 -0
  202. data/doc/cxxapi/functions_0x67.html +167 -0
  203. data/doc/cxxapi/functions_0x68.html +88 -0
  204. data/doc/cxxapi/functions_0x69.html +96 -0
  205. data/doc/cxxapi/functions_0x6b.html +80 -0
  206. data/doc/cxxapi/functions_0x6c.html +88 -0
  207. data/doc/cxxapi/functions_0x6d.html +88 -0
  208. data/doc/cxxapi/functions_0x6e.html +86 -0
  209. data/doc/cxxapi/functions_0x6f.html +94 -0
  210. data/doc/cxxapi/functions_0x70.html +94 -0
  211. data/doc/cxxapi/functions_0x72.html +110 -0
  212. data/doc/cxxapi/functions_0x73.html +171 -0
  213. data/doc/cxxapi/functions_0x74.html +85 -0
  214. data/doc/cxxapi/functions_0x75.html +85 -0
  215. data/doc/cxxapi/functions_0x77.html +92 -0
  216. data/doc/cxxapi/functions_0x7e.html +79 -0
  217. data/doc/cxxapi/functions_enum.html +49 -0
  218. data/doc/cxxapi/functions_eval.html +67 -0
  219. data/doc/cxxapi/functions_func.html +531 -0
  220. data/doc/cxxapi/functions_vars.html +278 -0
  221. data/doc/cxxapi/graph_legend.dot +22 -0
  222. data/doc/cxxapi/graph_legend.html +92 -0
  223. data/doc/cxxapi/graph_legend.png +0 -0
  224. data/doc/cxxapi/group__Core.html +46 -0
  225. data/doc/cxxapi/group__Core.map +3 -0
  226. data/doc/cxxapi/group__Core.png +0 -0
  227. data/doc/cxxapi/group__Exceptions.html +53 -0
  228. data/doc/cxxapi/group__Hooks.html +42 -0
  229. data/doc/cxxapi/group__Hooks.map +3 -0
  230. data/doc/cxxapi/group__Hooks.png +0 -0
  231. data/doc/cxxapi/group__Support.html +538 -0
  232. data/doc/cxxapi/hierarchy.html +101 -0
  233. data/doc/cxxapi/index.html +16 -0
  234. data/doc/cxxapi/inherit__graph__0.map +3 -0
  235. data/doc/cxxapi/inherit__graph__0.md5 +1 -0
  236. data/doc/cxxapi/inherit__graph__0.png +0 -0
  237. data/doc/cxxapi/inherit__graph__1.map +3 -0
  238. data/doc/cxxapi/inherit__graph__1.md5 +1 -0
  239. data/doc/cxxapi/inherit__graph__1.png +0 -0
  240. data/doc/cxxapi/inherit__graph__10.map +3 -0
  241. data/doc/cxxapi/inherit__graph__10.md5 +1 -0
  242. data/doc/cxxapi/inherit__graph__10.png +0 -0
  243. data/doc/cxxapi/inherit__graph__11.map +4 -0
  244. data/doc/cxxapi/inherit__graph__11.md5 +1 -0
  245. data/doc/cxxapi/inherit__graph__11.png +0 -0
  246. data/doc/cxxapi/inherit__graph__12.map +3 -0
  247. data/doc/cxxapi/inherit__graph__12.md5 +1 -0
  248. data/doc/cxxapi/inherit__graph__12.png +0 -0
  249. data/doc/cxxapi/inherit__graph__13.map +3 -0
  250. data/doc/cxxapi/inherit__graph__13.md5 +1 -0
  251. data/doc/cxxapi/inherit__graph__13.png +0 -0
  252. data/doc/cxxapi/inherit__graph__14.map +3 -0
  253. data/doc/cxxapi/inherit__graph__14.md5 +1 -0
  254. data/doc/cxxapi/inherit__graph__14.png +0 -0
  255. data/doc/cxxapi/inherit__graph__15.map +3 -0
  256. data/doc/cxxapi/inherit__graph__15.md5 +1 -0
  257. data/doc/cxxapi/inherit__graph__15.png +0 -0
  258. data/doc/cxxapi/inherit__graph__16.map +5 -0
  259. data/doc/cxxapi/inherit__graph__16.md5 +1 -0
  260. data/doc/cxxapi/inherit__graph__16.png +0 -0
  261. data/doc/cxxapi/inherit__graph__17.map +3 -0
  262. data/doc/cxxapi/inherit__graph__17.md5 +1 -0
  263. data/doc/cxxapi/inherit__graph__17.png +0 -0
  264. data/doc/cxxapi/inherit__graph__18.map +3 -0
  265. data/doc/cxxapi/inherit__graph__18.md5 +1 -0
  266. data/doc/cxxapi/inherit__graph__18.png +0 -0
  267. data/doc/cxxapi/inherit__graph__19.map +4 -0
  268. data/doc/cxxapi/inherit__graph__19.md5 +1 -0
  269. data/doc/cxxapi/inherit__graph__19.png +0 -0
  270. data/doc/cxxapi/inherit__graph__2.map +3 -0
  271. data/doc/cxxapi/inherit__graph__2.md5 +1 -0
  272. data/doc/cxxapi/inherit__graph__2.png +0 -0
  273. data/doc/cxxapi/inherit__graph__20.map +3 -0
  274. data/doc/cxxapi/inherit__graph__20.md5 +1 -0
  275. data/doc/cxxapi/inherit__graph__20.png +0 -0
  276. data/doc/cxxapi/inherit__graph__21.map +3 -0
  277. data/doc/cxxapi/inherit__graph__21.md5 +1 -0
  278. data/doc/cxxapi/inherit__graph__21.png +0 -0
  279. data/doc/cxxapi/inherit__graph__22.map +3 -0
  280. data/doc/cxxapi/inherit__graph__22.md5 +1 -0
  281. data/doc/cxxapi/inherit__graph__22.png +0 -0
  282. data/doc/cxxapi/inherit__graph__23.map +3 -0
  283. data/doc/cxxapi/inherit__graph__23.md5 +1 -0
  284. data/doc/cxxapi/inherit__graph__23.png +0 -0
  285. data/doc/cxxapi/inherit__graph__24.map +3 -0
  286. data/doc/cxxapi/inherit__graph__24.md5 +1 -0
  287. data/doc/cxxapi/inherit__graph__24.png +0 -0
  288. data/doc/cxxapi/inherit__graph__25.map +3 -0
  289. data/doc/cxxapi/inherit__graph__25.md5 +1 -0
  290. data/doc/cxxapi/inherit__graph__25.png +0 -0
  291. data/doc/cxxapi/inherit__graph__26.map +3 -0
  292. data/doc/cxxapi/inherit__graph__26.md5 +1 -0
  293. data/doc/cxxapi/inherit__graph__26.png +0 -0
  294. data/doc/cxxapi/inherit__graph__27.map +3 -0
  295. data/doc/cxxapi/inherit__graph__27.md5 +1 -0
  296. data/doc/cxxapi/inherit__graph__27.png +0 -0
  297. data/doc/cxxapi/inherit__graph__28.map +3 -0
  298. data/doc/cxxapi/inherit__graph__28.md5 +1 -0
  299. data/doc/cxxapi/inherit__graph__28.png +0 -0
  300. data/doc/cxxapi/inherit__graph__29.map +3 -0
  301. data/doc/cxxapi/inherit__graph__29.md5 +1 -0
  302. data/doc/cxxapi/inherit__graph__29.png +0 -0
  303. data/doc/cxxapi/inherit__graph__3.map +4 -0
  304. data/doc/cxxapi/inherit__graph__3.md5 +1 -0
  305. data/doc/cxxapi/inherit__graph__3.png +0 -0
  306. data/doc/cxxapi/inherit__graph__30.map +3 -0
  307. data/doc/cxxapi/inherit__graph__30.md5 +1 -0
  308. data/doc/cxxapi/inherit__graph__30.png +0 -0
  309. data/doc/cxxapi/inherit__graph__31.map +4 -0
  310. data/doc/cxxapi/inherit__graph__31.md5 +1 -0
  311. data/doc/cxxapi/inherit__graph__31.png +0 -0
  312. data/doc/cxxapi/inherit__graph__32.map +3 -0
  313. data/doc/cxxapi/inherit__graph__32.md5 +1 -0
  314. data/doc/cxxapi/inherit__graph__32.png +0 -0
  315. data/doc/cxxapi/inherit__graph__33.map +3 -0
  316. data/doc/cxxapi/inherit__graph__33.md5 +1 -0
  317. data/doc/cxxapi/inherit__graph__33.png +0 -0
  318. data/doc/cxxapi/inherit__graph__34.map +3 -0
  319. data/doc/cxxapi/inherit__graph__34.md5 +1 -0
  320. data/doc/cxxapi/inherit__graph__34.png +0 -0
  321. data/doc/cxxapi/inherit__graph__35.map +3 -0
  322. data/doc/cxxapi/inherit__graph__35.md5 +1 -0
  323. data/doc/cxxapi/inherit__graph__35.png +0 -0
  324. data/doc/cxxapi/inherit__graph__36.map +5 -0
  325. data/doc/cxxapi/inherit__graph__36.md5 +1 -0
  326. data/doc/cxxapi/inherit__graph__36.png +0 -0
  327. data/doc/cxxapi/inherit__graph__37.map +3 -0
  328. data/doc/cxxapi/inherit__graph__37.md5 +1 -0
  329. data/doc/cxxapi/inherit__graph__37.png +0 -0
  330. data/doc/cxxapi/inherit__graph__38.map +3 -0
  331. data/doc/cxxapi/inherit__graph__38.md5 +1 -0
  332. data/doc/cxxapi/inherit__graph__38.png +0 -0
  333. data/doc/cxxapi/inherit__graph__39.map +3 -0
  334. data/doc/cxxapi/inherit__graph__39.md5 +1 -0
  335. data/doc/cxxapi/inherit__graph__39.png +0 -0
  336. data/doc/cxxapi/inherit__graph__4.map +3 -0
  337. data/doc/cxxapi/inherit__graph__4.md5 +1 -0
  338. data/doc/cxxapi/inherit__graph__4.png +0 -0
  339. data/doc/cxxapi/inherit__graph__40.map +3 -0
  340. data/doc/cxxapi/inherit__graph__40.md5 +1 -0
  341. data/doc/cxxapi/inherit__graph__40.png +0 -0
  342. data/doc/cxxapi/inherit__graph__41.map +3 -0
  343. data/doc/cxxapi/inherit__graph__41.md5 +1 -0
  344. data/doc/cxxapi/inherit__graph__41.png +0 -0
  345. data/doc/cxxapi/inherit__graph__5.map +3 -0
  346. data/doc/cxxapi/inherit__graph__5.md5 +1 -0
  347. data/doc/cxxapi/inherit__graph__5.png +0 -0
  348. data/doc/cxxapi/inherit__graph__6.map +3 -0
  349. data/doc/cxxapi/inherit__graph__6.md5 +1 -0
  350. data/doc/cxxapi/inherit__graph__6.png +0 -0
  351. data/doc/cxxapi/inherit__graph__7.map +3 -0
  352. data/doc/cxxapi/inherit__graph__7.md5 +1 -0
  353. data/doc/cxxapi/inherit__graph__7.png +0 -0
  354. data/doc/cxxapi/inherit__graph__8.map +3 -0
  355. data/doc/cxxapi/inherit__graph__8.md5 +1 -0
  356. data/doc/cxxapi/inherit__graph__8.png +0 -0
  357. data/doc/cxxapi/inherit__graph__9.map +3 -0
  358. data/doc/cxxapi/inherit__graph__9.md5 +1 -0
  359. data/doc/cxxapi/inherit__graph__9.png +0 -0
  360. data/doc/cxxapi/inherits.html +165 -0
  361. data/doc/cxxapi/main.html +28 -0
  362. data/doc/cxxapi/modules.html +36 -0
  363. data/doc/cxxapi/namespacePassenger.html +553 -0
  364. data/doc/cxxapi/namespacemembers.html +135 -0
  365. data/doc/cxxapi/namespacemembers_enum.html +48 -0
  366. data/doc/cxxapi/namespacemembers_eval.html +57 -0
  367. data/doc/cxxapi/namespacemembers_func.html +111 -0
  368. data/doc/cxxapi/namespacemembers_type.html +54 -0
  369. data/doc/cxxapi/namespaces.html +37 -0
  370. data/doc/cxxapi/nginx_2Configuration_8h_source.html +126 -0
  371. data/doc/cxxapi/ngx__http__passenger__module_8h_source.html +94 -0
  372. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard-members.html +36 -0
  373. data/doc/cxxapi/structPassenger_1_1MessageServer_1_1DisconnectEventBroadcastGuard.html +51 -0
  374. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +67 -0
  375. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +647 -0
  376. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash-members.html +36 -0
  377. data/doc/cxxapi/structPassenger_1_1StaticString_1_1Hash.html +51 -0
  378. data/doc/cxxapi/tab_b.gif +0 -0
  379. data/doc/cxxapi/tab_l.gif +0 -0
  380. data/doc/cxxapi/tab_r.gif +0 -0
  381. data/doc/cxxapi/tabs.css +105 -0
  382. data/doc/cxxapi/tree.html +249 -0
  383. data/doc/rdoc/classes/ConditionVariable.html +215 -0
  384. data/doc/rdoc/classes/Exception.html +120 -0
  385. data/doc/rdoc/classes/GC.html +113 -0
  386. data/doc/rdoc/classes/IO.html +221 -0
  387. data/doc/rdoc/classes/PhusionPassenger.html +397 -0
  388. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +180 -0
  389. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +647 -0
  390. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +654 -0
  391. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/InvalidPassword.html +92 -0
  392. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +97 -0
  393. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +96 -0
  394. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +97 -0
  395. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +96 -0
  396. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +619 -0
  397. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +142 -0
  398. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats.html +368 -0
  399. data/doc/rdoc/classes/PhusionPassenger/AdminTools/MemoryStats/Process.html +231 -0
  400. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance.html +588 -0
  401. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/CorruptedDirectoryError.html +92 -0
  402. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/GenerationsAbsentError.html +92 -0
  403. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Group.html +147 -0
  404. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Process.html +279 -0
  405. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/RoleDeniedError.html +92 -0
  406. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/StaleDirectoryError.html +92 -0
  407. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/Stats.html +123 -0
  408. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ServerInstance/UnsupportedGenerationStructureVersionError.html +92 -0
  409. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger.html +368 -0
  410. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/Lock.html +194 -0
  411. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/Log.html +299 -0
  412. data/doc/rdoc/classes/PhusionPassenger/AnalyticsLogger/SharedData.html +206 -0
  413. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +155 -0
  414. data/doc/rdoc/classes/PhusionPassenger/AppProcess.html +367 -0
  415. data/doc/rdoc/classes/PhusionPassenger/ClassicRails.html +95 -0
  416. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner.html +351 -0
  417. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/ApplicationSpawner/Error.html +98 -0
  418. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/CGIFixed.html +200 -0
  419. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner.html +410 -0
  420. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/FrameworkSpawner/Error.html +98 -0
  421. data/doc/rdoc/classes/PhusionPassenger/ClassicRails/RequestHandler.html +156 -0
  422. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions.html +115 -0
  423. data/doc/rdoc/classes/PhusionPassenger/ClassicRailsExtensions/AnalyticsLogging.html +202 -0
  424. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +172 -0
  425. data/doc/rdoc/classes/PhusionPassenger/DebugLogging.html +273 -0
  426. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +145 -0
  427. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +162 -0
  428. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +141 -0
  429. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  430. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +673 -0
  431. data/doc/rdoc/classes/PhusionPassenger/MessageChannel/InvalidHashError.html +92 -0
  432. data/doc/rdoc/classes/PhusionPassenger/MessageClient.html +415 -0
  433. data/doc/rdoc/classes/PhusionPassenger/NativeSupportLoader.html +134 -0
  434. data/doc/rdoc/classes/PhusionPassenger/Packaging.html +129 -0
  435. data/doc/rdoc/classes/PhusionPassenger/PlatformInfo.html +1972 -0
  436. data/doc/rdoc/classes/PhusionPassenger/Plugin.html +237 -0
  437. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  438. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +312 -0
  439. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner/Error.html +98 -0
  440. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +218 -0
  441. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions.html +114 -0
  442. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging.html +259 -0
  443. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ACExtension.html +139 -0
  444. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ASBenchmarkableExtension.html +118 -0
  445. data/doc/rdoc/classes/PhusionPassenger/Rails3Extensions/AnalyticsLogging/ExceptionLogger.html +135 -0
  446. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +378 -0
  447. data/doc/rdoc/classes/PhusionPassenger/Standalone.html +111 -0
  448. data/doc/rdoc/classes/PhusionPassenger/Standalone/AppFinder.html +252 -0
  449. data/doc/rdoc/classes/PhusionPassenger/Standalone/Command.html +161 -0
  450. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile.html +368 -0
  451. data/doc/rdoc/classes/PhusionPassenger/Standalone/ConfigFile/DisallowedContextError.html +132 -0
  452. data/doc/rdoc/classes/PhusionPassenger/Standalone/HelpCommand.html +151 -0
  453. data/doc/rdoc/classes/PhusionPassenger/Standalone/Main.html +189 -0
  454. data/doc/rdoc/classes/PhusionPassenger/Standalone/PackageRuntimeCommand.html +177 -0
  455. data/doc/rdoc/classes/PhusionPassenger/Standalone/RuntimeInstaller.html +341 -0
  456. data/doc/rdoc/classes/PhusionPassenger/Standalone/StartCommand.html +203 -0
  457. data/doc/rdoc/classes/PhusionPassenger/Standalone/StatusCommand.html +156 -0
  458. data/doc/rdoc/classes/PhusionPassenger/Standalone/StopCommand.html +168 -0
  459. data/doc/rdoc/classes/PhusionPassenger/Standalone/Utils.html +86 -0
  460. data/doc/rdoc/classes/PhusionPassenger/Standalone/VersionCommand.html +135 -0
  461. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +125 -0
  462. data/doc/rdoc/classes/PhusionPassenger/Utils.html +1543 -0
  463. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher.html +204 -0
  464. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/DirInfo.html +171 -0
  465. data/doc/rdoc/classes/PhusionPassenger/Utils/FileSystemWatcher/FileInfo.html +140 -0
  466. data/doc/rdoc/classes/PhusionPassenger/Utils/HostsFileParser.html +260 -0
  467. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +194 -0
  468. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput.html +265 -0
  469. data/doc/rdoc/classes/PhusionPassenger/Utils/RewindableInput/Tempfile.html +120 -0
  470. data/doc/rdoc/classes/PhusionPassenger/Utils/UnseekableSocket.html +561 -0
  471. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +140 -0
  472. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  473. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +182 -0
  474. data/doc/rdoc/classes/Process.html +115 -0
  475. data/doc/rdoc/classes/Signal.html +139 -0
  476. data/doc/rdoc/created.rid +1 -0
  477. data/doc/rdoc/files/DEVELOPERS_TXT.html +280 -0
  478. data/doc/rdoc/files/README.html +157 -0
  479. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +130 -0
  480. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +135 -0
  481. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +126 -0
  482. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +128 -0
  483. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/memory_stats_rb.html +126 -0
  484. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/server_instance_rb.html +132 -0
  485. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +122 -0
  486. data/doc/rdoc/files/lib/phusion_passenger/analytics_logger_rb.html +129 -0
  487. data/doc/rdoc/files/lib/phusion_passenger/app_process_rb.html +127 -0
  488. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/application_spawner_rb.html +141 -0
  489. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/cgi_fixed_rb.html +126 -0
  490. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/framework_spawner_rb.html +146 -0
  491. data/doc/rdoc/files/lib/phusion_passenger/classic_rails/request_handler_rb.html +125 -0
  492. data/doc/rdoc/files/lib/phusion_passenger/classic_rails_extensions/init_rb.html +132 -0
  493. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +126 -0
  494. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +122 -0
  495. data/doc/rdoc/files/lib/phusion_passenger/debug_logging_rb.html +122 -0
  496. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +147 -0
  497. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +122 -0
  498. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +127 -0
  499. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +120 -0
  500. data/doc/rdoc/files/lib/phusion_passenger/message_client_rb.html +127 -0
  501. data/doc/rdoc/files/lib/phusion_passenger/native_support_rb.html +132 -0
  502. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +122 -0
  503. data/doc/rdoc/files/lib/phusion_passenger/platform_info/apache_rb.html +127 -0
  504. data/doc/rdoc/files/lib/phusion_passenger/platform_info/binary_compatibility_rb.html +129 -0
  505. data/doc/rdoc/files/lib/phusion_passenger/platform_info/compiler_rb.html +127 -0
  506. data/doc/rdoc/files/lib/phusion_passenger/platform_info/curl_rb.html +126 -0
  507. data/doc/rdoc/files/lib/phusion_passenger/platform_info/documentation_tools_rb.html +126 -0
  508. data/doc/rdoc/files/lib/phusion_passenger/platform_info/linux_rb.html +126 -0
  509. data/doc/rdoc/files/lib/phusion_passenger/platform_info/operating_system_rb.html +127 -0
  510. data/doc/rdoc/files/lib/phusion_passenger/platform_info/ruby_rb.html +128 -0
  511. data/doc/rdoc/files/lib/phusion_passenger/platform_info/zlib_rb.html +126 -0
  512. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +122 -0
  513. data/doc/rdoc/files/lib/phusion_passenger/plugin_rb.html +127 -0
  514. data/doc/rdoc/files/lib/phusion_passenger/public_api_rb.html +127 -0
  515. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +137 -0
  516. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +125 -0
  517. data/doc/rdoc/files/lib/phusion_passenger/rails3_extensions/init_rb.html +127 -0
  518. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +122 -0
  519. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +160 -0
  520. data/doc/rdoc/files/lib/phusion_passenger/standalone/app_finder_rb.html +127 -0
  521. data/doc/rdoc/files/lib/phusion_passenger/standalone/command_rb.html +136 -0
  522. data/doc/rdoc/files/lib/phusion_passenger/standalone/config_file_rb.html +126 -0
  523. data/doc/rdoc/files/lib/phusion_passenger/standalone/help_command_rb.html +126 -0
  524. data/doc/rdoc/files/lib/phusion_passenger/standalone/main_rb.html +126 -0
  525. data/doc/rdoc/files/lib/phusion_passenger/standalone/package_runtime_command_rb.html +127 -0
  526. data/doc/rdoc/files/lib/phusion_passenger/standalone/runtime_installer_rb.html +133 -0
  527. data/doc/rdoc/files/lib/phusion_passenger/standalone/start_command_rb.html +136 -0
  528. data/doc/rdoc/files/lib/phusion_passenger/standalone/status_command_rb.html +126 -0
  529. data/doc/rdoc/files/lib/phusion_passenger/standalone/stop_command_rb.html +126 -0
  530. data/doc/rdoc/files/lib/phusion_passenger/standalone/utils_rb.html +126 -0
  531. data/doc/rdoc/files/lib/phusion_passenger/standalone/version_command_rb.html +127 -0
  532. data/doc/rdoc/files/lib/phusion_passenger/utils/file_system_watcher_rb.html +126 -0
  533. data/doc/rdoc/files/lib/phusion_passenger/utils/hosts_file_parser_rb.html +120 -0
  534. data/doc/rdoc/files/lib/phusion_passenger/utils/rewindable_input_rb.html +100 -0
  535. data/doc/rdoc/files/lib/phusion_passenger/utils/tmpdir_rb.html +122 -0
  536. data/doc/rdoc/files/lib/phusion_passenger/utils/unseekable_socket_rb.html +126 -0
  537. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +179 -0
  538. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +132 -0
  539. data/doc/rdoc/fr_class_index.html +139 -0
  540. data/doc/rdoc/fr_file_index.html +108 -0
  541. data/doc/rdoc/fr_method_index.html +439 -0
  542. data/doc/rdoc/index.html +26 -0
  543. data/doc/rdoc/rdoc-style.css +187 -0
  544. data/ext/apache2/Configuration.cpp +6 -6
  545. data/ext/apache2/Configuration.hpp +3 -3
  546. data/ext/apache2/HelperAgent.cpp +1 -1
  547. data/ext/apache2/Hooks.cpp +3 -3
  548. data/ext/common/ApplicationPool/Pool.h +1 -1
  549. data/ext/common/ApplicationPool/Server.h +5 -2
  550. data/ext/common/Constants.h +1 -1
  551. data/ext/common/LoggingAgent/FilterSupport.cpp +66 -0
  552. data/ext/common/LoggingAgent/FilterSupport.h +262 -73
  553. data/ext/common/LoggingAgent/RemoteSender.h +13 -4
  554. data/ext/common/Utils/CachedFileStat.cpp +6 -12
  555. data/ext/common/Utils/CachedFileStat.h +4 -4
  556. data/ext/common/libboost_oxt/aggregate.cpp +10 -0
  557. data/ext/common/libpassenger_common/aggregate.cpp +16 -0
  558. data/ext/nginx/Configuration.c +77 -4
  559. data/ext/nginx/Configuration.h +2 -1
  560. data/ext/nginx/ContentHandler.c +32 -4
  561. data/ext/nginx/HelperAgent.cpp +5 -4
  562. data/ext/nginx/ngx_http_passenger_module.c +6 -6
  563. data/ext/nginx/ngx_http_passenger_module.h +5 -5
  564. data/lib/phusion_passenger.rb +1 -1
  565. data/lib/phusion_passenger/abstract_request_handler.rb +4 -1
  566. data/lib/phusion_passenger/classic_rails_extensions/analytics_logging/ac_base_extension.rb +3 -1
  567. data/lib/phusion_passenger/standalone/runtime_installer.rb +1 -1
  568. data/lib/phusion_passenger/standalone/start_command.rb +6 -0
  569. data/lib/phusion_passenger/templates/standalone/config.erb +1 -1
  570. data/test/cxx/FilterSupportTest.cpp +135 -5
  571. metadata +547 -4
@@ -0,0 +1,733 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
5
+ <title>Passenger: EventedClient.h Source File</title>
6
+ <link href="tabs.css" rel="stylesheet" type="text/css"/>
7
+ <link href="doxygen.css" rel="stylesheet" type="text/css"/>
8
+ </head>
9
+ <body>
10
+ <!-- Generated by Doxygen 1.6.2 -->
11
+ <div class="navigation" id="top">
12
+ <div class="tabs">
13
+ <ul>
14
+ <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
15
+ <li><a href="modules.html"><span>Modules</span></a></li>
16
+ <li><a href="namespaces.html"><span>Namespaces</span></a></li>
17
+ <li><a href="annotated.html"><span>Classes</span></a></li>
18
+ <li class="current"><a href="files.html"><span>Files</span></a></li>
19
+ </ul>
20
+ </div>
21
+ <div class="tabs">
22
+ <ul>
23
+ <li><a href="files.html"><span>File&nbsp;List</span></a></li>
24
+ </ul>
25
+ </div>
26
+ <h1>EventedClient.h</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
27
+ <a name="l00002"></a>00002 <span class="comment"> * Phusion Passenger - http://www.modrails.com/</span>
28
+ <a name="l00003"></a>00003 <span class="comment"> * Copyright (c) 2010 Phusion</span>
29
+ <a name="l00004"></a>00004 <span class="comment"> *</span>
30
+ <a name="l00005"></a>00005 <span class="comment"> * &quot;Phusion Passenger&quot; is a trademark of Hongli Lai &amp; Ninh Bui.</span>
31
+ <a name="l00006"></a>00006 <span class="comment"> *</span>
32
+ <a name="l00007"></a>00007 <span class="comment"> * Permission is hereby granted, free of charge, to any person obtaining a copy</span>
33
+ <a name="l00008"></a>00008 <span class="comment"> * of this software and associated documentation files (the &quot;Software&quot;), to deal</span>
34
+ <a name="l00009"></a>00009 <span class="comment"> * in the Software without restriction, including without limitation the rights</span>
35
+ <a name="l00010"></a>00010 <span class="comment"> * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span>
36
+ <a name="l00011"></a>00011 <span class="comment"> * copies of the Software, and to permit persons to whom the Software is</span>
37
+ <a name="l00012"></a>00012 <span class="comment"> * furnished to do so, subject to the following conditions:</span>
38
+ <a name="l00013"></a>00013 <span class="comment"> *</span>
39
+ <a name="l00014"></a>00014 <span class="comment"> * The above copyright notice and this permission notice shall be included in</span>
40
+ <a name="l00015"></a>00015 <span class="comment"> * all copies or substantial portions of the Software.</span>
41
+ <a name="l00016"></a>00016 <span class="comment"> *</span>
42
+ <a name="l00017"></a>00017 <span class="comment"> * THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span>
43
+ <a name="l00018"></a>00018 <span class="comment"> * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span>
44
+ <a name="l00019"></a>00019 <span class="comment"> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span>
45
+ <a name="l00020"></a>00020 <span class="comment"> * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span>
46
+ <a name="l00021"></a>00021 <span class="comment"> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span>
47
+ <a name="l00022"></a>00022 <span class="comment"> * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN</span>
48
+ <a name="l00023"></a>00023 <span class="comment"> * THE SOFTWARE.</span>
49
+ <a name="l00024"></a>00024 <span class="comment"> */</span>
50
+ <a name="l00025"></a>00025 <span class="preprocessor">#ifndef _PASSENGER_EVENTED_CLIENT_H_</span>
51
+ <a name="l00026"></a>00026 <span class="preprocessor"></span><span class="preprocessor">#define _PASSENGER_EVENTED_CLIENT_H_</span>
52
+ <a name="l00027"></a>00027 <span class="preprocessor"></span>
53
+ <a name="l00028"></a>00028 <span class="preprocessor">#include &lt;ev++.h&gt;</span>
54
+ <a name="l00029"></a>00029 <span class="preprocessor">#include &lt;string&gt;</span>
55
+ <a name="l00030"></a>00030 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
56
+ <a name="l00031"></a>00031 <span class="preprocessor">#include &lt;cstdlib&gt;</span>
57
+ <a name="l00032"></a>00032 <span class="preprocessor">#include &lt;cerrno&gt;</span>
58
+ <a name="l00033"></a>00033 <span class="preprocessor">#include &lt;cassert&gt;</span>
59
+ <a name="l00034"></a>00034
60
+ <a name="l00035"></a>00035 <span class="preprocessor">#include &lt;boost/function.hpp&gt;</span>
61
+ <a name="l00036"></a>00036 <span class="preprocessor">#include &lt;oxt/system_calls.hpp&gt;</span>
62
+ <a name="l00037"></a>00037 <span class="preprocessor">#include &lt;oxt/thread.hpp&gt;</span>
63
+ <a name="l00038"></a>00038
64
+ <a name="l00039"></a>00039 <span class="preprocessor">#include &quot;FileDescriptor.h&quot;</span>
65
+ <a name="l00040"></a>00040 <span class="preprocessor">#include &quot;Utils/IOUtils.h&quot;</span>
66
+ <a name="l00041"></a>00041
67
+ <a name="l00042"></a>00042 <span class="keyword">namespace </span>Passenger {
68
+ <a name="l00043"></a>00043
69
+ <a name="l00044"></a>00044 <span class="keyword">using namespace </span>std;
70
+ <a name="l00045"></a>00045 <span class="keyword">using namespace </span>boost;
71
+ <a name="l00046"></a>00046 <span class="keyword">using namespace </span>oxt;
72
+ <a name="l00047"></a>00047
73
+ <a name="l00048"></a>00048 <span class="comment"></span>
74
+ <a name="l00049"></a>00049 <span class="comment">/**</span>
75
+ <a name="l00050"></a>00050 <span class="comment"> * A utility class for making I/O handling in non-blocking libev evented servers</span>
76
+ <a name="l00051"></a>00051 <span class="comment"> * much easier.</span>
77
+ <a name="l00052"></a>00052 <span class="comment"> * - An EventedClient is associated with a reference counted file descriptor.</span>
78
+ <a name="l00053"></a>00053 <span class="comment"> * - It contains connection state information (i.e. whether the connection is</span>
79
+ <a name="l00054"></a>00054 <span class="comment"> * established or closed). Callbacks are provided for watching connection</span>
80
+ <a name="l00055"></a>00055 <span class="comment"> * state changes (e.g. &lt;tt&gt;onDisconnect&lt;/tt&gt;).</span>
81
+ <a name="l00056"></a>00056 <span class="comment"> * - It provides reference counting features for simpler memory management</span>
82
+ <a name="l00057"></a>00057 <span class="comment"> * (&lt;tt&gt;ref()&lt;/tt&gt; and &lt;tt&gt;unref()&lt;/tt&gt;).</span>
83
+ <a name="l00058"></a>00058 <span class="comment"> * - It installs input and output readiness watchers that are unregistered</span>
84
+ <a name="l00059"></a>00059 <span class="comment"> * when the EventedClient is destroyed. One can hook into input readiness</span>
85
+ <a name="l00060"></a>00060 <span class="comment"> * watcher with the &lt;tt&gt;onReadable&lt;/tt&gt; callback.</span>
86
+ <a name="l00061"></a>00061 <span class="comment"> * - Makes zero-copy writes easy. The &lt;tt&gt;write()&lt;/tt&gt; method accepts an array</span>
87
+ <a name="l00062"></a>00062 <span class="comment"> * of buffers. Whenever possible, all of these buffers are written out in</span>
88
+ <a name="l00063"></a>00063 <span class="comment"> * the given order, using a single system call, without copying them into a</span>
89
+ <a name="l00064"></a>00064 <span class="comment"> * single temporary buffer.</span>
90
+ <a name="l00065"></a>00065 <span class="comment"> * - Makes non-blocking writes easy. Normally a write() system call on a</span>
91
+ <a name="l00066"></a>00066 <span class="comment"> * non-blocking socket can fail with EAGAIN if the socket send buffer is</span>
92
+ <a name="l00067"></a>00067 <span class="comment"> * full. EventedClient schedules the data to be sent later when the socket is</span>
93
+ <a name="l00068"></a>00068 <span class="comment"> * writable again. It automatically integrates into the main loop in order</span>
94
+ <a name="l00069"></a>00069 <span class="comment"> * to do this. This allows one to have write operations occur concurrently</span>
95
+ <a name="l00070"></a>00070 <span class="comment"> * with read operations.</span>
96
+ <a name="l00071"></a>00071 <span class="comment"> * In case too many scheduled writes are being piled up, EventedClient</span>
97
+ <a name="l00072"></a>00072 <span class="comment"> * is smart enough to temporarily disable read notifications and wait until</span>
98
+ <a name="l00073"></a>00073 <span class="comment"> * everything is written out before enabling read notifications again.</span>
99
+ <a name="l00074"></a>00074 <span class="comment"> * The definition of &quot;too many&quot; is customizable (&lt;tt&gt;setOutboxLimit()&lt;/tt&gt;).</span>
100
+ <a name="l00075"></a>00075 <span class="comment"> * - EventedClient&#39;s &lt;tt&gt;disconnect&lt;/tt&gt; method respects pending writes. It</span>
101
+ <a name="l00076"></a>00076 <span class="comment"> * will disconnect after all pending outgoing data have been written out.</span>
102
+ <a name="l00077"></a>00077 <span class="comment"> *</span>
103
+ <a name="l00078"></a>00078 <span class="comment"> * &lt;h2&gt;Basic usage&lt;/h2&gt;</span>
104
+ <a name="l00079"></a>00079 <span class="comment"> * Construct an EventedClient with a libev loop and a file descriptor:</span>
105
+ <a name="l00080"></a>00080 <span class="comment"> *</span>
106
+ <a name="l00081"></a>00081 <span class="comment"> * @code</span>
107
+ <a name="l00082"></a>00082 <span class="comment"> * EventedClient *client = new EventedClient(loop, fd);</span>
108
+ <a name="l00083"></a>00083 <span class="comment"> * @endcode</span>
109
+ <a name="l00084"></a>00084 <span class="comment"> *</span>
110
+ <a name="l00085"></a>00085 <span class="comment"> * You are probably interested in read readiness notifications on &lt;tt&gt;fd&lt;/tt&gt;.</span>
111
+ <a name="l00086"></a>00086 <span class="comment"> * However these notifications are disabled by default. You need to set the</span>
112
+ <a name="l00087"></a>00087 <span class="comment"> * &lt;tt&gt;onReadable&lt;/tt&gt; callback (which is called every time the fd is</span>
113
+ <a name="l00088"></a>00088 <span class="comment"> * readable) and enable read notifications.</span>
114
+ <a name="l00089"></a>00089 <span class="comment"> *</span>
115
+ <a name="l00090"></a>00090 <span class="comment"> * @code</span>
116
+ <a name="l00091"></a>00091 <span class="comment"> * void onReadable(EventedClient *client) {</span>
117
+ <a name="l00092"></a>00092 <span class="comment"> * // do whatever you want</span>
118
+ <a name="l00093"></a>00093 <span class="comment"> * }</span>
119
+ <a name="l00094"></a>00094 <span class="comment"> * </span>
120
+ <a name="l00095"></a>00095 <span class="comment"> * ...</span>
121
+ <a name="l00096"></a>00096 <span class="comment"> * client-&gt;onReadable = onReadable;</span>
122
+ <a name="l00097"></a>00097 <span class="comment"> * client-&gt;notifyReads(true);</span>
123
+ <a name="l00098"></a>00098 <span class="comment"> * @endcode</span>
124
+ <a name="l00099"></a>00099 <span class="comment"> *</span>
125
+ <a name="l00100"></a>00100 <span class="comment"> * &lt;h2&gt;Error handling&lt;/h2&gt;</span>
126
+ <a name="l00101"></a>00101 <span class="comment"> * EventedClient never raises exceptions, except when your callbacks do.</span>
127
+ <a name="l00102"></a>00102 <span class="comment"> * It reports errors with the &lt;tt&gt;onSystemError&lt;/tt&gt; callback. That said,</span>
128
+ <a name="l00103"></a>00103 <span class="comment"> * EventedClient is exception-aware and will ensure that its internal</span>
129
+ <a name="l00104"></a>00104 <span class="comment"> * state stays consistent even when your callbacks throw exceptions.</span>
130
+ <a name="l00105"></a>00105 <span class="comment"> */</span>
131
+ <a name="l00106"></a><a class="code" href="classPassenger_1_1EventedClient.html">00106</a> <span class="keyword">class </span><a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a> {
132
+ <a name="l00107"></a>00107 <span class="keyword">public</span>:
133
+ <a name="l00108"></a>00108 <span class="keyword">typedef</span> void (*Callback)(<a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a> *client);
134
+ <a name="l00109"></a>00109 <span class="keyword">typedef</span> void (*SystemErrorCallback)(<a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a> *client, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;message, <span class="keywordtype">int</span> code);
135
+ <a name="l00110"></a>00110
136
+ <a name="l00111"></a>00111 <span class="keyword">private</span>:
137
+ <a name="l00112"></a>00112 <span class="keyword">enum</span> {<span class="comment"></span>
138
+ <a name="l00113"></a>00113 <span class="comment"> /**</span>
139
+ <a name="l00114"></a>00114 <span class="comment"> * This is the initial state for a client. It means we&#39;re</span>
140
+ <a name="l00115"></a>00115 <span class="comment"> * connected to the client, ready to receive data and</span>
141
+ <a name="l00116"></a>00116 <span class="comment"> * there&#39;s no pending outgoing data. In this state we will</span>
142
+ <a name="l00117"></a>00117 <span class="comment"> * only be watching for read events.</span>
143
+ <a name="l00118"></a>00118 <span class="comment"> */</span>
144
+ <a name="l00119"></a>00119 EC_CONNECTED,
145
+ <a name="l00120"></a>00120 <span class="comment"></span>
146
+ <a name="l00121"></a>00121 <span class="comment"> /**</span>
147
+ <a name="l00122"></a>00122 <span class="comment"> * This state is entered from EC_CONNECTED when the write()</span>
148
+ <a name="l00123"></a>00123 <span class="comment"> * method fails to send all data immediately and EventedClient</span>
149
+ <a name="l00124"></a>00124 <span class="comment"> * schedules some data to be sent later, when the socket becomes</span>
150
+ <a name="l00125"></a>00125 <span class="comment"> * readable again. In here we will be watching for read</span>
151
+ <a name="l00126"></a>00126 <span class="comment"> * and write events. Once all data has been sent out the system</span>
152
+ <a name="l00127"></a>00127 <span class="comment"> * will transition back to EC_CONNECTED.</span>
153
+ <a name="l00128"></a>00128 <span class="comment"> */</span>
154
+ <a name="l00129"></a>00129 EC_WRITES_PENDING,
155
+ <a name="l00130"></a>00130 <span class="comment"></span>
156
+ <a name="l00131"></a>00131 <span class="comment"> /**</span>
157
+ <a name="l00132"></a>00132 <span class="comment"> * This state is entered from EC_WRITES_PENDING or from EC_CONNECTED</span>
158
+ <a name="l00133"></a>00133 <span class="comment"> * when the write() method fails to send all data immediately, and</span>
159
+ <a name="l00134"></a>00134 <span class="comment"> * the amount of data to be scheduled to be sent later is larger</span>
160
+ <a name="l00135"></a>00135 <span class="comment"> * than the specified outbox limit. In this state, EventedClient</span>
161
+ <a name="l00136"></a>00136 <span class="comment"> * will not watch for read events and will instead concentrate on</span>
162
+ <a name="l00137"></a>00137 <span class="comment"> * sending out all pending data before watching read events again.</span>
163
+ <a name="l00138"></a>00138 <span class="comment"> * When all pending data has been sent out the system will transition</span>
164
+ <a name="l00139"></a>00139 <span class="comment"> * to EC_CONNECTED.</span>
165
+ <a name="l00140"></a>00140 <span class="comment"> */</span>
166
+ <a name="l00141"></a>00141 EC_TOO_MANY_WRITES_PENDING,
167
+ <a name="l00142"></a>00142 <span class="comment"></span>
168
+ <a name="l00143"></a>00143 <span class="comment"> /**</span>
169
+ <a name="l00144"></a>00144 <span class="comment"> * This state is like EC_CONNECTED, but indicates that the write</span>
170
+ <a name="l00145"></a>00145 <span class="comment"> * side of the connection has been closed. In this state write()</span>
171
+ <a name="l00146"></a>00146 <span class="comment"> * calls won&#39;t have any effect.</span>
172
+ <a name="l00147"></a>00147 <span class="comment"> */</span>
173
+ <a name="l00148"></a>00148 EC_RO_CONNECTED,
174
+ <a name="l00149"></a>00149 <span class="comment"></span>
175
+ <a name="l00150"></a>00150 <span class="comment"> /**</span>
176
+ <a name="l00151"></a>00151 <span class="comment"> * This state is entered from EC_WRITES_PENDING when</span>
177
+ <a name="l00152"></a>00152 <span class="comment"> * closeWrite() has been called. The system will continue</span>
178
+ <a name="l00153"></a>00153 <span class="comment"> * to send out pending data but write() calls won&#39;t append more</span>
179
+ <a name="l00154"></a>00154 <span class="comment"> * data to the outbox. After pending data has been sent out,</span>
180
+ <a name="l00155"></a>00155 <span class="comment"> * the system will transition to EC_RO_CONNECTED.</span>
181
+ <a name="l00156"></a>00156 <span class="comment"> */</span>
182
+ <a name="l00157"></a>00157 EC_RO_CONNECTED_WITH_WRITES_PENDING,
183
+ <a name="l00158"></a>00158 <span class="comment"></span>
184
+ <a name="l00159"></a>00159 <span class="comment"> /**</span>
185
+ <a name="l00160"></a>00160 <span class="comment"> * This state is entered from the EC_WRITES_PENDING,</span>
186
+ <a name="l00161"></a>00161 <span class="comment"> * EC_TOO_MANY_WRITES_PENDING, EC_RO_CONNECTED_WITH_WIRTES_PENDING</span>
187
+ <a name="l00162"></a>00162 <span class="comment"> * or EC_RO_CONNECTED_WITH_TOO_MANY_WRITES_PENDING state when</span>
188
+ <a name="l00163"></a>00163 <span class="comment"> * disconnect() is called.</span>
189
+ <a name="l00164"></a>00164 <span class="comment"> * It means that we want to close the connection as soon as all</span>
190
+ <a name="l00165"></a>00165 <span class="comment"> * pending outgoing data has been sent. As soon as that happens</span>
191
+ <a name="l00166"></a>00166 <span class="comment"> * it&#39;ll transition to EC_DISCONNECTED. In this state no further</span>
192
+ <a name="l00167"></a>00167 <span class="comment"> * I/O should be allowed.</span>
193
+ <a name="l00168"></a>00168 <span class="comment"> */</span>
194
+ <a name="l00169"></a>00169 EC_DISCONNECTING_WITH_WRITES_PENDING,
195
+ <a name="l00170"></a>00170 <span class="comment"></span>
196
+ <a name="l00171"></a>00171 <span class="comment"> /**</span>
197
+ <a name="l00172"></a>00172 <span class="comment"> * Final state. Client connection has been closed. No</span>
198
+ <a name="l00173"></a>00173 <span class="comment"> * I/O with the client is possible.</span>
199
+ <a name="l00174"></a>00174 <span class="comment"> */</span>
200
+ <a name="l00175"></a>00175 EC_DISCONNECTED
201
+ <a name="l00176"></a>00176 } state;
202
+ <a name="l00177"></a>00177 <span class="comment"></span>
203
+ <a name="l00178"></a>00178 <span class="comment"> /** A libev watcher on for watching read events on &lt;tt&gt;fd&lt;/tt&gt;. */</span>
204
+ <a name="l00179"></a>00179 ev::io readWatcher;<span class="comment"></span>
205
+ <a name="l00180"></a>00180 <span class="comment"> /** A libev watcher on for watching write events on &lt;tt&gt;fd&lt;/tt&gt;. */</span>
206
+ <a name="l00181"></a>00181 ev::io writeWatcher;<span class="comment"></span>
207
+ <a name="l00182"></a>00182 <span class="comment"> /** Storage for data that could not be sent out immediately. */</span>
208
+ <a name="l00183"></a>00183 <span class="keywordtype">string</span> outbox;
209
+ <a name="l00184"></a>00184 <span class="keywordtype">int</span> refcount;
210
+ <a name="l00185"></a>00185 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> outboxLimit;
211
+ <a name="l00186"></a>00186 <span class="keywordtype">bool</span> m_notifyReads;
212
+ <a name="l00187"></a>00187
213
+ <a name="l00188"></a>00188 <span class="keywordtype">void</span> _onReadable(ev::io &amp;w, <span class="keywordtype">int</span> revents) {
214
+ <a name="l00189"></a>00189 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a155988f311fba920bef3031f3d9b6f6a" title="Called when the file descriptor becomes readable and read notifications are enabled...">onReadable</a>);
215
+ <a name="l00190"></a>00190 }
216
+ <a name="l00191"></a>00191
217
+ <a name="l00192"></a>00192 <span class="keywordtype">void</span> onWritable(ev::io &amp;w, <span class="keywordtype">int</span> revents) {
218
+ <a name="l00193"></a>00193 assert(state != EC_CONNECTED);
219
+ <a name="l00194"></a>00194 assert(state != EC_RO_CONNECTED);
220
+ <a name="l00195"></a>00195 assert(state != EC_DISCONNECTED);
221
+ <a name="l00196"></a>00196
222
+ <a name="l00197"></a>00197 this_thread::disable_interruption di;
223
+ <a name="l00198"></a>00198 this_thread::disable_syscall_interruption dsi;
224
+ <a name="l00199"></a>00199 <span class="keywordtype">size_t</span> sent = 0;
225
+ <a name="l00200"></a>00200 <span class="keywordtype">bool</span> done = outbox.empty();
226
+ <a name="l00201"></a>00201
227
+ <a name="l00202"></a>00202 <span class="keywordflow">while</span> (!done) {
228
+ <a name="l00203"></a>00203 ssize_t ret = syscalls::write(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>,
229
+ <a name="l00204"></a>00204 outbox.data() + sent,
230
+ <a name="l00205"></a>00205 outbox.size() - sent);
231
+ <a name="l00206"></a>00206 <span class="keywordflow">if</span> (ret == -1) {
232
+ <a name="l00207"></a>00207 <span class="keywordflow">if</span> (errno != EAGAIN) {
233
+ <a name="l00208"></a>00208 <span class="keywordtype">int</span> e = errno;
234
+ <a name="l00209"></a>00209 <span class="keywordflow">if</span> (<a class="code" href="classPassenger_1_1EventedClient.html#afc0934988a978a25538b7d8f2566c90a" title="Controls what to do when a write error is encountered.">writeErrorAction</a> == <a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a627c2190c3a4dc848dc1a332ef9f5105" title="Forcefully disconnect the client.">DISCONNECT_FULL</a>) {
235
+ <a name="l00210"></a>00210 <a class="code" href="classPassenger_1_1EventedClient.html#a5b1a3011165ea9a47f6fe668a5010a20" title="Disconnects the client.">disconnect</a>(<span class="keyword">true</span>);
236
+ <a name="l00211"></a>00211 } <span class="keywordflow">else</span> {
237
+ <a name="l00212"></a>00212 <a class="code" href="classPassenger_1_1EventedClient.html#a9161e34ddc473c00fe4df8fdb1d1baef" title="Close only the writer side of the client connection.">closeWrite</a>();
238
+ <a name="l00213"></a>00213 }
239
+ <a name="l00214"></a>00214 emitSystemErrorEvent(<span class="stringliteral">&quot;Cannot write data to client&quot;</span>, e);
240
+ <a name="l00215"></a>00215 <span class="keywordflow">return</span>;
241
+ <a name="l00216"></a>00216 }
242
+ <a name="l00217"></a>00217 done = <span class="keyword">true</span>;
243
+ <a name="l00218"></a>00218 } <span class="keywordflow">else</span> {
244
+ <a name="l00219"></a>00219 sent += ret;
245
+ <a name="l00220"></a>00220 done = sent == outbox.size();
246
+ <a name="l00221"></a>00221 }
247
+ <a name="l00222"></a>00222 }
248
+ <a name="l00223"></a>00223 <span class="keywordflow">if</span> (sent &gt; 0) {
249
+ <a name="l00224"></a>00224 outbox.erase(0, sent);
250
+ <a name="l00225"></a>00225 }
251
+ <a name="l00226"></a>00226
252
+ <a name="l00227"></a>00227 updateWatcherStates();
253
+ <a name="l00228"></a>00228 <span class="keywordflow">if</span> (outbox.empty()) {
254
+ <a name="l00229"></a>00229 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a22e93ce2be05a4f47dbeba95d79a79b9" title="Called after all pending outgoing data have been written out.">onPendingDataFlushed</a>);
255
+ <a name="l00230"></a>00230 }
256
+ <a name="l00231"></a>00231 }
257
+ <a name="l00232"></a>00232
258
+ <a name="l00233"></a>00233 <span class="keywordtype">bool</span> outboxTooLarge() {
259
+ <a name="l00234"></a>00234 <span class="keywordflow">return</span> outbox.size() &gt; 0 &amp;&amp; outbox.size() &gt;= outboxLimit;
260
+ <a name="l00235"></a>00235 }
261
+ <a name="l00236"></a>00236
262
+ <a name="l00237"></a>00237 <span class="keywordtype">void</span> updateWatcherStates() {
263
+ <a name="l00238"></a>00238 <span class="keywordflow">if</span> (outbox.empty()) {
264
+ <a name="l00239"></a>00239 <span class="keywordflow">switch</span> (state) {
265
+ <a name="l00240"></a>00240 <span class="keywordflow">case</span> EC_CONNECTED:
266
+ <a name="l00241"></a>00241 <span class="keywordflow">case</span> EC_RO_CONNECTED:
267
+ <a name="l00242"></a>00242 watchReadEvents(m_notifyReads);
268
+ <a name="l00243"></a>00243 watchWriteEvents(<span class="keyword">false</span>);
269
+ <a name="l00244"></a>00244 <span class="keywordflow">break</span>;
270
+ <a name="l00245"></a>00245 <span class="keywordflow">case</span> EC_WRITES_PENDING:
271
+ <a name="l00246"></a>00246 <span class="keywordflow">case</span> EC_TOO_MANY_WRITES_PENDING:
272
+ <a name="l00247"></a>00247 state = EC_CONNECTED;
273
+ <a name="l00248"></a>00248 watchReadEvents(m_notifyReads);
274
+ <a name="l00249"></a>00249 watchWriteEvents(<span class="keyword">false</span>);
275
+ <a name="l00250"></a>00250 <span class="keywordflow">break</span>;
276
+ <a name="l00251"></a>00251 <span class="keywordflow">case</span> EC_RO_CONNECTED_WITH_WRITES_PENDING:
277
+ <a name="l00252"></a>00252 state = EC_RO_CONNECTED;
278
+ <a name="l00253"></a>00253 watchReadEvents(m_notifyReads);
279
+ <a name="l00254"></a>00254 watchWriteEvents(<span class="keyword">false</span>);
280
+ <a name="l00255"></a>00255 <span class="keywordflow">break</span>;
281
+ <a name="l00256"></a>00256 <span class="keywordflow">case</span> EC_DISCONNECTING_WITH_WRITES_PENDING:
282
+ <a name="l00257"></a>00257 state = EC_DISCONNECTED;
283
+ <a name="l00258"></a>00258 watchReadEvents(<span class="keyword">false</span>);
284
+ <a name="l00259"></a>00259 watchWriteEvents(<span class="keyword">false</span>);
285
+ <a name="l00260"></a>00260 <span class="keywordflow">try</span> {
286
+ <a name="l00261"></a>00261 <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>.<a class="code" href="classPassenger_1_1FileDescriptor.html#a02062f3cfb689b32781e11114c0abe5b" title="Close the underlying file descriptor.">close</a>();
287
+ <a name="l00262"></a>00262 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
288
+ <a name="l00263"></a>00263 emitSystemErrorEvent(e.<a class="code" href="classPassenger_1_1SystemException.html#a84fa2ab4f5b7b96704734fcdfdaa0269" title="Returns a brief version of the exception message.">brief</a>(), e.<a class="code" href="classPassenger_1_1SystemException.html#aee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
289
+ <a name="l00264"></a>00264 }
290
+ <a name="l00265"></a>00265 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a211210ecd85eb2da47d200215132bb2d" title="Called when the client is disconnected.">onDisconnect</a>);
291
+ <a name="l00266"></a>00266 <span class="keywordflow">break</span>;
292
+ <a name="l00267"></a>00267 <span class="keywordflow">default</span>:
293
+ <a name="l00268"></a>00268 <span class="comment">// Should never be reached.</span>
294
+ <a name="l00269"></a>00269 abort();
295
+ <a name="l00270"></a>00270 }
296
+ <a name="l00271"></a>00271 } <span class="keywordflow">else</span> {
297
+ <a name="l00272"></a>00272 <span class="keywordflow">switch</span> (state) {
298
+ <a name="l00273"></a>00273 <span class="keywordflow">case</span> EC_CONNECTED:
299
+ <a name="l00274"></a>00274 <span class="keywordflow">if</span> (outboxTooLarge()) {
300
+ <a name="l00275"></a>00275 <span class="comment">// If we have way too much stuff in the outbox then</span>
301
+ <a name="l00276"></a>00276 <span class="comment">// suspend reading until we&#39;ve sent out the entire outbox.</span>
302
+ <a name="l00277"></a>00277 state = EC_TOO_MANY_WRITES_PENDING;
303
+ <a name="l00278"></a>00278 watchReadEvents(<span class="keyword">false</span>);
304
+ <a name="l00279"></a>00279 watchWriteEvents(<span class="keyword">true</span>);
305
+ <a name="l00280"></a>00280 } <span class="keywordflow">else</span> {
306
+ <a name="l00281"></a>00281 state = EC_WRITES_PENDING;
307
+ <a name="l00282"></a>00282 watchReadEvents(m_notifyReads);
308
+ <a name="l00283"></a>00283 watchWriteEvents(<span class="keyword">true</span>);
309
+ <a name="l00284"></a>00284 }
310
+ <a name="l00285"></a>00285 <span class="keywordflow">break</span>;
311
+ <a name="l00286"></a>00286 <span class="keywordflow">case</span> EC_RO_CONNECTED:
312
+ <a name="l00287"></a>00287 fprintf(stderr, <span class="stringliteral">&quot;BUG: when outbox is non-empty the state should never be EC_RO_CONNECTED!\n&quot;</span>);
313
+ <a name="l00288"></a>00288 abort();
314
+ <a name="l00289"></a>00289 <span class="keywordflow">break</span>;
315
+ <a name="l00290"></a>00290 <span class="keywordflow">case</span> EC_WRITES_PENDING:
316
+ <a name="l00291"></a>00291 <span class="keywordflow">case</span> EC_RO_CONNECTED_WITH_WRITES_PENDING:
317
+ <a name="l00292"></a>00292 watchReadEvents(m_notifyReads);
318
+ <a name="l00293"></a>00293 watchWriteEvents(<span class="keyword">true</span>);
319
+ <a name="l00294"></a>00294 <span class="keywordflow">break</span>;
320
+ <a name="l00295"></a>00295 <span class="keywordflow">case</span> EC_TOO_MANY_WRITES_PENDING:
321
+ <a name="l00296"></a>00296 <span class="keywordflow">case</span> EC_DISCONNECTING_WITH_WRITES_PENDING:
322
+ <a name="l00297"></a>00297 watchReadEvents(<span class="keyword">false</span>);
323
+ <a name="l00298"></a>00298 watchWriteEvents(<span class="keyword">true</span>);
324
+ <a name="l00299"></a>00299 <span class="keywordflow">break</span>;
325
+ <a name="l00300"></a>00300 <span class="keywordflow">default</span>:
326
+ <a name="l00301"></a>00301 <span class="comment">// Should never be reached.</span>
327
+ <a name="l00302"></a>00302 abort();
328
+ <a name="l00303"></a>00303 }
329
+ <a name="l00304"></a>00304 }
330
+ <a name="l00305"></a>00305 }
331
+ <a name="l00306"></a>00306
332
+ <a name="l00307"></a>00307 <span class="keywordtype">void</span> watchReadEvents(<span class="keywordtype">bool</span> enable = <span class="keyword">true</span>) {
333
+ <a name="l00308"></a>00308 <span class="keywordflow">if</span> (readWatcher.is_active() &amp;&amp; !enable) {
334
+ <a name="l00309"></a>00309 readWatcher.stop();
335
+ <a name="l00310"></a>00310 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!readWatcher.is_active() &amp;&amp; enable) {
336
+ <a name="l00311"></a>00311 readWatcher.start();
337
+ <a name="l00312"></a>00312 }
338
+ <a name="l00313"></a>00313 }
339
+ <a name="l00314"></a>00314
340
+ <a name="l00315"></a>00315 <span class="keywordtype">void</span> watchWriteEvents(<span class="keywordtype">bool</span> enable = <span class="keyword">true</span>) {
341
+ <a name="l00316"></a>00316 <span class="keywordflow">if</span> (writeWatcher.is_active() &amp;&amp; !enable) {
342
+ <a name="l00317"></a>00317 writeWatcher.stop();
343
+ <a name="l00318"></a>00318 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!writeWatcher.is_active() &amp;&amp; enable) {
344
+ <a name="l00319"></a>00319 writeWatcher.start();
345
+ <a name="l00320"></a>00320 }
346
+ <a name="l00321"></a>00321 }
347
+ <a name="l00322"></a>00322
348
+ <a name="l00323"></a>00323 <span class="keywordtype">void</span> emitEvent(Callback callback) {
349
+ <a name="l00324"></a>00324 <span class="keywordflow">if</span> (callback != NULL) {
350
+ <a name="l00325"></a>00325 callback(<span class="keyword">this</span>);
351
+ <a name="l00326"></a>00326 }
352
+ <a name="l00327"></a>00327 }
353
+ <a name="l00328"></a>00328
354
+ <a name="l00329"></a>00329 <span class="keywordtype">void</span> emitSystemErrorEvent(<span class="keyword">const</span> <span class="keywordtype">string</span> &amp;message, <span class="keywordtype">int</span> code) {
355
+ <a name="l00330"></a>00330 <span class="keywordflow">if</span> (<a class="code" href="classPassenger_1_1EventedClient.html#a9522b2c5a42d75a93ed865e74510818f" title="System call errors are reported with this callback.">onSystemError</a> != NULL) {
356
+ <a name="l00331"></a>00331 <a class="code" href="classPassenger_1_1EventedClient.html#a9522b2c5a42d75a93ed865e74510818f" title="System call errors are reported with this callback.">onSystemError</a>(<span class="keyword">this</span>, message, code);
357
+ <a name="l00332"></a>00332 }
358
+ <a name="l00333"></a>00333 }
359
+ <a name="l00334"></a>00334
360
+ <a name="l00335"></a>00335 <span class="keyword">public</span>:<span class="comment"></span>
361
+ <a name="l00336"></a>00336 <span class="comment"> /** The client&#39;s file descriptor. Could be -1: see &lt;tt&gt;ioAllowed()&lt;/tt&gt;. */</span>
362
+ <a name="l00337"></a><a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491">00337</a> <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>;
363
+ <a name="l00338"></a>00338 <span class="comment"></span>
364
+ <a name="l00339"></a>00339 <span class="comment"> /** Controls what to do when a write error is encountered. */</span>
365
+ <a name="l00340"></a>00340 <span class="keyword">enum</span> {<span class="comment"></span>
366
+ <a name="l00341"></a>00341 <span class="comment"> /** Forcefully disconnect the client. */</span>
367
+ <a name="l00342"></a><a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a627c2190c3a4dc848dc1a332ef9f5105">00342</a> <a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a627c2190c3a4dc848dc1a332ef9f5105" title="Forcefully disconnect the client.">DISCONNECT_FULL</a>,<span class="comment"></span>
368
+ <a name="l00343"></a>00343 <span class="comment"> /** Close the writer side of the connection, but continue allowing reading. */</span>
369
+ <a name="l00344"></a><a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a232760bee5b535fd40e609ff8c088693">00344</a> <a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a232760bee5b535fd40e609ff8c088693" title="Close the writer side of the connection, but continue allowing reading.">DISCONNECT_WRITE</a>
370
+ <a name="l00345"></a>00345 } <a class="code" href="classPassenger_1_1EventedClient.html#afc0934988a978a25538b7d8f2566c90a" title="Controls what to do when a write error is encountered.">writeErrorAction</a>;
371
+ <a name="l00346"></a>00346 <span class="comment"></span>
372
+ <a name="l00347"></a>00347 <span class="comment"> /**</span>
373
+ <a name="l00348"></a>00348 <span class="comment"> * Called when the file descriptor becomes readable and read notifications</span>
374
+ <a name="l00349"></a>00349 <span class="comment"> * are enabled (see &lt;tt&gt;notifyRead()&lt;/tt&gt;). When there&#39;s too much pending</span>
375
+ <a name="l00350"></a>00350 <span class="comment"> * outgoing data, readability notifications are temporarily disabled; see</span>
376
+ <a name="l00351"></a>00351 <span class="comment"> * &lt;tt&gt;write()&lt;/tt&gt; for details.</span>
377
+ <a name="l00352"></a>00352 <span class="comment"> */</span>
378
+ <a name="l00353"></a><a class="code" href="classPassenger_1_1EventedClient.html#a155988f311fba920bef3031f3d9b6f6a">00353</a> Callback <a class="code" href="classPassenger_1_1EventedClient.html#a155988f311fba920bef3031f3d9b6f6a" title="Called when the file descriptor becomes readable and read notifications are enabled...">onReadable</a>;
379
+ <a name="l00354"></a>00354 <span class="comment"></span>
380
+ <a name="l00355"></a>00355 <span class="comment"> /**</span>
381
+ <a name="l00356"></a>00356 <span class="comment"> * Called when the client is disconnected. This happens either immediately</span>
382
+ <a name="l00357"></a>00357 <span class="comment"> * when &lt;tt&gt;disconnect()&lt;/tt&gt; is called, or a short amount of time later.</span>
383
+ <a name="l00358"></a>00358 <span class="comment"> * See the documentation for that function for details.</span>
384
+ <a name="l00359"></a>00359 <span class="comment"> *</span>
385
+ <a name="l00360"></a>00360 <span class="comment"> * Please note that destroying an EventedClient object does *not* cause</span>
386
+ <a name="l00361"></a>00361 <span class="comment"> * this callback to be called.</span>
387
+ <a name="l00362"></a>00362 <span class="comment"> */</span>
388
+ <a name="l00363"></a><a class="code" href="classPassenger_1_1EventedClient.html#a211210ecd85eb2da47d200215132bb2d">00363</a> Callback <a class="code" href="classPassenger_1_1EventedClient.html#a211210ecd85eb2da47d200215132bb2d" title="Called when the client is disconnected.">onDisconnect</a>;
389
+ <a name="l00364"></a>00364 <span class="comment"></span>
390
+ <a name="l00365"></a>00365 <span class="comment"> /**</span>
391
+ <a name="l00366"></a>00366 <span class="comment"> * Called when &lt;tt&gt;detach()&lt;/tt&gt; is called for the first time.</span>
392
+ <a name="l00367"></a>00367 <span class="comment"> */</span>
393
+ <a name="l00368"></a><a class="code" href="classPassenger_1_1EventedClient.html#a742805d40508b0af89eb2ed2c1e50060">00368</a> Callback <a class="code" href="classPassenger_1_1EventedClient.html#a742805d40508b0af89eb2ed2c1e50060" title="Called when detach() is called for the first time.">onDetach</a>;
394
+ <a name="l00369"></a>00369 <span class="comment"></span>
395
+ <a name="l00370"></a>00370 <span class="comment"> /**</span>
396
+ <a name="l00371"></a>00371 <span class="comment"> * Called after all pending outgoing data have been written out.</span>
397
+ <a name="l00372"></a>00372 <span class="comment"> * If &lt;tt&gt;write()&lt;/tt&gt; can be completed immediately without scheduling</span>
398
+ <a name="l00373"></a>00373 <span class="comment"> * data for later, then &lt;tt&gt;write()&lt;/tt&gt; will call this callback</span>
399
+ <a name="l00374"></a>00374 <span class="comment"> * immediately after writing.</span>
400
+ <a name="l00375"></a>00375 <span class="comment"> */</span>
401
+ <a name="l00376"></a><a class="code" href="classPassenger_1_1EventedClient.html#a22e93ce2be05a4f47dbeba95d79a79b9">00376</a> Callback <a class="code" href="classPassenger_1_1EventedClient.html#a22e93ce2be05a4f47dbeba95d79a79b9" title="Called after all pending outgoing data have been written out.">onPendingDataFlushed</a>;
402
+ <a name="l00377"></a>00377 <span class="comment"></span>
403
+ <a name="l00378"></a>00378 <span class="comment"> /**</span>
404
+ <a name="l00379"></a>00379 <span class="comment"> * System call errors are reported with this callback.</span>
405
+ <a name="l00380"></a>00380 <span class="comment"> */</span>
406
+ <a name="l00381"></a><a class="code" href="classPassenger_1_1EventedClient.html#a9522b2c5a42d75a93ed865e74510818f">00381</a> SystemErrorCallback <a class="code" href="classPassenger_1_1EventedClient.html#a9522b2c5a42d75a93ed865e74510818f" title="System call errors are reported with this callback.">onSystemError</a>;
407
+ <a name="l00382"></a>00382 <span class="comment"></span>
408
+ <a name="l00383"></a>00383 <span class="comment"> /**</span>
409
+ <a name="l00384"></a>00384 <span class="comment"> * EventedClient doesn&#39;t do anything with this. Set it to whatever you want.</span>
410
+ <a name="l00385"></a>00385 <span class="comment"> */</span>
411
+ <a name="l00386"></a><a class="code" href="classPassenger_1_1EventedClient.html#a793c843b7ba01cc1bb2c568c6539b9e0">00386</a> <span class="keywordtype">void</span> *<a class="code" href="classPassenger_1_1EventedClient.html#a793c843b7ba01cc1bb2c568c6539b9e0" title="EventedClient doesn&amp;#39;t do anything with this.">userData</a>;
412
+ <a name="l00387"></a>00387 <span class="comment"></span>
413
+ <a name="l00388"></a>00388 <span class="comment"> /**</span>
414
+ <a name="l00389"></a>00389 <span class="comment"> * Creates a new EventedClient with the given libev loop and file descriptor.</span>
415
+ <a name="l00390"></a>00390 <span class="comment"> * The initial reference count is 1.</span>
416
+ <a name="l00391"></a>00391 <span class="comment"> */</span>
417
+ <a name="l00392"></a><a class="code" href="classPassenger_1_1EventedClient.html#ac3c45bfa7ac30b6d59ef08dc296f3c4e">00392</a> <a class="code" href="classPassenger_1_1EventedClient.html#ac3c45bfa7ac30b6d59ef08dc296f3c4e" title="Creates a new EventedClient with the given libev loop and file descriptor.">EventedClient</a>(<span class="keyword">struct</span> ev_loop *loop, <span class="keyword">const</span> <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> &amp;_fd)
418
+ <a name="l00393"></a>00393 : readWatcher(loop),
419
+ <a name="l00394"></a>00394 writeWatcher(loop),
420
+ <a name="l00395"></a>00395 <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>(_fd)
421
+ <a name="l00396"></a>00396 {
422
+ <a name="l00397"></a>00397 state = EC_CONNECTED;
423
+ <a name="l00398"></a>00398 refcount = 1;
424
+ <a name="l00399"></a>00399 m_notifyReads = <span class="keyword">false</span>;
425
+ <a name="l00400"></a>00400 outboxLimit = 1024 * 32;
426
+ <a name="l00401"></a>00401 <a class="code" href="classPassenger_1_1EventedClient.html#afc0934988a978a25538b7d8f2566c90a" title="Controls what to do when a write error is encountered.">writeErrorAction</a> = <a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a627c2190c3a4dc848dc1a332ef9f5105" title="Forcefully disconnect the client.">DISCONNECT_FULL</a>;
427
+ <a name="l00402"></a>00402 <a class="code" href="classPassenger_1_1EventedClient.html#a155988f311fba920bef3031f3d9b6f6a" title="Called when the file descriptor becomes readable and read notifications are enabled...">onReadable</a> = NULL;
428
+ <a name="l00403"></a>00403 <a class="code" href="classPassenger_1_1EventedClient.html#a211210ecd85eb2da47d200215132bb2d" title="Called when the client is disconnected.">onDisconnect</a> = NULL;
429
+ <a name="l00404"></a>00404 <a class="code" href="classPassenger_1_1EventedClient.html#a742805d40508b0af89eb2ed2c1e50060" title="Called when detach() is called for the first time.">onDetach</a> = NULL;
430
+ <a name="l00405"></a>00405 <a class="code" href="classPassenger_1_1EventedClient.html#a22e93ce2be05a4f47dbeba95d79a79b9" title="Called after all pending outgoing data have been written out.">onPendingDataFlushed</a> = NULL;
431
+ <a name="l00406"></a>00406 <a class="code" href="classPassenger_1_1EventedClient.html#a9522b2c5a42d75a93ed865e74510818f" title="System call errors are reported with this callback.">onSystemError</a> = NULL;
432
+ <a name="l00407"></a>00407 <a class="code" href="classPassenger_1_1EventedClient.html#a793c843b7ba01cc1bb2c568c6539b9e0" title="EventedClient doesn&amp;#39;t do anything with this.">userData</a> = NULL;
433
+ <a name="l00408"></a>00408 readWatcher.set(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>, ev::READ);
434
+ <a name="l00409"></a>00409 readWatcher.set&lt;<a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a>, &amp;EventedClient::_onReadable&gt;(<span class="keyword">this</span>);
435
+ <a name="l00410"></a>00410 writeWatcher.set&lt;<a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a>, &amp;EventedClient::onWritable&gt;(<span class="keyword">this</span>);
436
+ <a name="l00411"></a>00411 writeWatcher.set(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>, ev::WRITE);
437
+ <a name="l00412"></a>00412 }
438
+ <a name="l00413"></a>00413
439
+ <a name="l00414"></a>00414 <span class="keyword">virtual</span> ~<a class="code" href="classPassenger_1_1EventedClient.html" title="A utility class for making I/O handling in non-blocking libev evented servers much...">EventedClient</a>() {
440
+ <a name="l00415"></a>00415 <span class="comment">// Unregister file descriptor from the event loop poller before</span>
441
+ <a name="l00416"></a>00416 <span class="comment">// closing the file descriptor.</span>
442
+ <a name="l00417"></a>00417 watchReadEvents(<span class="keyword">false</span>);
443
+ <a name="l00418"></a>00418 watchWriteEvents(<span class="keyword">false</span>);
444
+ <a name="l00419"></a>00419 }
445
+ <a name="l00420"></a>00420 <span class="comment"></span>
446
+ <a name="l00421"></a>00421 <span class="comment"> /**</span>
447
+ <a name="l00422"></a>00422 <span class="comment"> * Increase reference count.</span>
448
+ <a name="l00423"></a>00423 <span class="comment"> */</span>
449
+ <a name="l00424"></a><a class="code" href="classPassenger_1_1EventedClient.html#aec0aee41bd623d7a3f3cd8ae201ba717">00424</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#aec0aee41bd623d7a3f3cd8ae201ba717" title="Increase reference count.">ref</a>() {
450
+ <a name="l00425"></a>00425 refcount++;
451
+ <a name="l00426"></a>00426 }
452
+ <a name="l00427"></a>00427 <span class="comment"></span>
453
+ <a name="l00428"></a>00428 <span class="comment"> /**</span>
454
+ <a name="l00429"></a>00429 <span class="comment"> * Decrease reference count. Upon reaching 0, this EventedClient object</span>
455
+ <a name="l00430"></a>00430 <span class="comment"> * will be destroyed.</span>
456
+ <a name="l00431"></a>00431 <span class="comment"> */</span>
457
+ <a name="l00432"></a><a class="code" href="classPassenger_1_1EventedClient.html#a1e480f15dfd339ff781f8daedc5b8190">00432</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#a1e480f15dfd339ff781f8daedc5b8190" title="Decrease reference count.">unref</a>() {
458
+ <a name="l00433"></a>00433 refcount--;
459
+ <a name="l00434"></a>00434 assert(refcount &gt;= 0);
460
+ <a name="l00435"></a>00435 <span class="keywordflow">if</span> (refcount == 0) {
461
+ <a name="l00436"></a>00436 <span class="keyword">delete</span> <span class="keyword">this</span>;
462
+ <a name="l00437"></a>00437 }
463
+ <a name="l00438"></a>00438 }
464
+ <a name="l00439"></a>00439 <span class="comment"></span>
465
+ <a name="l00440"></a>00440 <span class="comment"> /**</span>
466
+ <a name="l00441"></a>00441 <span class="comment"> * Returns whether it is allowed to perform some kind of I/O with</span>
467
+ <a name="l00442"></a>00442 <span class="comment"> * this client, either reading or writing.</span>
468
+ <a name="l00443"></a>00443 <span class="comment"> * Usually true, and false when the client is either being disconnected</span>
469
+ <a name="l00444"></a>00444 <span class="comment"> * or has been disconnected. A return value of false indicates that</span>
470
+ <a name="l00445"></a>00445 <span class="comment"> * &lt;tt&gt;fd&lt;/tt&gt; might be -1, but even when it isn&#39;t -1 you shouldn&#39;t</span>
471
+ <a name="l00446"></a>00446 <span class="comment"> * access &lt;tt&gt;fd&lt;/tt&gt; anymore.</span>
472
+ <a name="l00447"></a>00447 <span class="comment"> * When the connection is half-closed (e.g. after closeWrite() has</span>
473
+ <a name="l00448"></a>00448 <span class="comment"> * been called) the return value is still be true. Only when I/O of any</span>
474
+ <a name="l00449"></a>00449 <span class="comment"> * kind is disallowed will this function return false.</span>
475
+ <a name="l00450"></a>00450 <span class="comment"> */</span>
476
+ <a name="l00451"></a><a class="code" href="classPassenger_1_1EventedClient.html#a50436eb8ec0cc38b5a7278962e98a22c">00451</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1EventedClient.html#a50436eb8ec0cc38b5a7278962e98a22c" title="Returns whether it is allowed to perform some kind of I/O with this client, either...">ioAllowed</a>()<span class="keyword"> const </span>{
477
+ <a name="l00452"></a>00452 <span class="keywordflow">return</span> state != EC_DISCONNECTING_WITH_WRITES_PENDING
478
+ <a name="l00453"></a>00453 &amp;&amp; state != EC_DISCONNECTED;
479
+ <a name="l00454"></a>00454 }
480
+ <a name="l00455"></a>00455 <span class="comment"></span>
481
+ <a name="l00456"></a>00456 <span class="comment"> /**</span>
482
+ <a name="l00457"></a>00457 <span class="comment"> * Returns whether it is allowed to write data to the client.</span>
483
+ <a name="l00458"></a>00458 <span class="comment"> * Usually true, and false when the client is either being disconnected</span>
484
+ <a name="l00459"></a>00459 <span class="comment"> * or has been disconnected or when the writer side of the client</span>
485
+ <a name="l00460"></a>00460 <span class="comment"> * connection has been closed. write() will do nothing if this function</span>
486
+ <a name="l00461"></a>00461 <span class="comment"> * returns false.</span>
487
+ <a name="l00462"></a>00462 <span class="comment"> */</span>
488
+ <a name="l00463"></a><a class="code" href="classPassenger_1_1EventedClient.html#aca719fb03ade09839827a16caa0e6e30">00463</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1EventedClient.html#aca719fb03ade09839827a16caa0e6e30" title="Returns whether it is allowed to write data to the client.">writeAllowed</a>()<span class="keyword"> const </span>{
489
+ <a name="l00464"></a>00464 <span class="keywordflow">return</span> state == EC_CONNECTED
490
+ <a name="l00465"></a>00465 || state == EC_WRITES_PENDING
491
+ <a name="l00466"></a>00466 || state == EC_TOO_MANY_WRITES_PENDING
492
+ <a name="l00467"></a>00467 || state == EC_RO_CONNECTED_WITH_WRITES_PENDING;
493
+ <a name="l00468"></a>00468 }
494
+ <a name="l00469"></a>00469 <span class="comment"></span>
495
+ <a name="l00470"></a>00470 <span class="comment"> /** Used by unit tests. */</span>
496
+ <a name="l00471"></a><a class="code" href="classPassenger_1_1EventedClient.html#a129f6d6a6123c9af1999eca4ae04a75a">00471</a> <span class="keywordtype">bool</span> <a class="code" href="classPassenger_1_1EventedClient.html#a129f6d6a6123c9af1999eca4ae04a75a" title="Used by unit tests.">readWatcherActive</a>()<span class="keyword"> const </span>{
497
+ <a name="l00472"></a>00472 <span class="keywordflow">return</span> readWatcher.is_active();
498
+ <a name="l00473"></a>00473 }
499
+ <a name="l00474"></a>00474 <span class="comment"></span>
500
+ <a name="l00475"></a>00475 <span class="comment"> /**</span>
501
+ <a name="l00476"></a>00476 <span class="comment"> * Returns the number of bytes that are scheduled to be sent to the</span>
502
+ <a name="l00477"></a>00477 <span class="comment"> * client at a later time.</span>
503
+ <a name="l00478"></a>00478 <span class="comment"> * </span>
504
+ <a name="l00479"></a>00479 <span class="comment"> * @see write()</span>
505
+ <a name="l00480"></a>00480 <span class="comment"> */</span>
506
+ <a name="l00481"></a><a class="code" href="classPassenger_1_1EventedClient.html#a0a032e54979b074641ffda807648a6e2">00481</a> <span class="keywordtype">size_t</span> <a class="code" href="classPassenger_1_1EventedClient.html#a0a032e54979b074641ffda807648a6e2" title="Returns the number of bytes that are scheduled to be sent to the client at a later...">pendingWrites</a>()<span class="keyword"> const </span>{
507
+ <a name="l00482"></a>00482 <span class="keywordflow">return</span> outbox.size();
508
+ <a name="l00483"></a>00483 }
509
+ <a name="l00484"></a>00484 <span class="comment"></span>
510
+ <a name="l00485"></a>00485 <span class="comment"> /**</span>
511
+ <a name="l00486"></a>00486 <span class="comment"> * Sets whether you&#39;re interested in read events. This will start or</span>
512
+ <a name="l00487"></a>00487 <span class="comment"> * stop the input readiness watcher appropriately according to the</span>
513
+ <a name="l00488"></a>00488 <span class="comment"> * current state.</span>
514
+ <a name="l00489"></a>00489 <span class="comment"> *</span>
515
+ <a name="l00490"></a>00490 <span class="comment"> * If the client connection is already being closed or has already</span>
516
+ <a name="l00491"></a>00491 <span class="comment"> * been closed then this method does nothing.</span>
517
+ <a name="l00492"></a>00492 <span class="comment"> */</span>
518
+ <a name="l00493"></a><a class="code" href="classPassenger_1_1EventedClient.html#a56ac52f1a4e77c49f72202d16e588f2f">00493</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#a56ac52f1a4e77c49f72202d16e588f2f" title="Sets whether you&amp;#39;re interested in read events.">notifyReads</a>(<span class="keywordtype">bool</span> enable) {
519
+ <a name="l00494"></a>00494 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1EventedClient.html#a50436eb8ec0cc38b5a7278962e98a22c" title="Returns whether it is allowed to perform some kind of I/O with this client, either...">ioAllowed</a>()) {
520
+ <a name="l00495"></a>00495 <span class="keywordflow">return</span>;
521
+ <a name="l00496"></a>00496 }
522
+ <a name="l00497"></a>00497
523
+ <a name="l00498"></a>00498 this_thread::disable_interruption di;
524
+ <a name="l00499"></a>00499 this_thread::disable_syscall_interruption dsi;
525
+ <a name="l00500"></a>00500 m_notifyReads = enable;
526
+ <a name="l00501"></a>00501 updateWatcherStates();
527
+ <a name="l00502"></a>00502 }
528
+ <a name="l00503"></a>00503 <span class="comment"></span>
529
+ <a name="l00504"></a>00504 <span class="comment"> /**</span>
530
+ <a name="l00505"></a>00505 <span class="comment"> * Sets a limit on the client outbox. The outbox is where data is stored</span>
531
+ <a name="l00506"></a>00506 <span class="comment"> * that could not be immediately sent to the client, e.g. because of</span>
532
+ <a name="l00507"></a>00507 <span class="comment"> * network congestion. Whenver the outbox&#39;s size grows past this limit,</span>
533
+ <a name="l00508"></a>00508 <span class="comment"> * EventedClient will enter a state in which it will stop listening for</span>
534
+ <a name="l00509"></a>00509 <span class="comment"> * read events and instead concentrate on sending out all pending data.</span>
535
+ <a name="l00510"></a>00510 <span class="comment"> *</span>
536
+ <a name="l00511"></a>00511 <span class="comment"> * Setting this to 0 means that the outbox has an unlimited size. Please</span>
537
+ <a name="l00512"></a>00512 <span class="comment"> * note however that this also means that the outbox&#39;s memory could grow</span>
538
+ <a name="l00513"></a>00513 <span class="comment"> * unbounded if the client is too slow at receiving data.</span>
539
+ <a name="l00514"></a>00514 <span class="comment"> *</span>
540
+ <a name="l00515"></a>00515 <span class="comment"> * The default value is some non-zero value.</span>
541
+ <a name="l00516"></a>00516 <span class="comment"> *</span>
542
+ <a name="l00517"></a>00517 <span class="comment"> * If the client connection is already being closed or has already</span>
543
+ <a name="l00518"></a>00518 <span class="comment"> * been closed then this method does nothing.</span>
544
+ <a name="l00519"></a>00519 <span class="comment"> */</span>
545
+ <a name="l00520"></a><a class="code" href="classPassenger_1_1EventedClient.html#ac1eb48c0d5382a97facbf9af40924849">00520</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#ac1eb48c0d5382a97facbf9af40924849" title="Sets a limit on the client outbox.">setOutboxLimit</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {
546
+ <a name="l00521"></a>00521 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1EventedClient.html#a50436eb8ec0cc38b5a7278962e98a22c" title="Returns whether it is allowed to perform some kind of I/O with this client, either...">ioAllowed</a>()) {
547
+ <a name="l00522"></a>00522 <span class="keywordflow">return</span>;
548
+ <a name="l00523"></a>00523 }
549
+ <a name="l00524"></a>00524
550
+ <a name="l00525"></a>00525 this_thread::disable_interruption di;
551
+ <a name="l00526"></a>00526 this_thread::disable_syscall_interruption dsi;
552
+ <a name="l00527"></a>00527 outboxLimit = size;
553
+ <a name="l00528"></a>00528 updateWatcherStates();
554
+ <a name="l00529"></a>00529 }
555
+ <a name="l00530"></a>00530
556
+ <a name="l00531"></a>00531 <span class="keywordtype">void</span> write(<span class="keyword">const</span> <a class="code" href="classPassenger_1_1StaticString.html" title="An immutable, static byte buffer.">StaticString</a> &amp;data) {
557
+ <a name="l00532"></a>00532 write(&amp;data, 1);
558
+ <a name="l00533"></a>00533 }
559
+ <a name="l00534"></a>00534 <span class="comment"></span>
560
+ <a name="l00535"></a>00535 <span class="comment"> /**</span>
561
+ <a name="l00536"></a>00536 <span class="comment"> * Sends data to this client. This method will try to send the data</span>
562
+ <a name="l00537"></a>00537 <span class="comment"> * immediately (in which no intermediate copies of the data will be made),</span>
563
+ <a name="l00538"></a>00538 <span class="comment"> * but if the client is not yet ready to receive data (e.g. because of</span>
564
+ <a name="l00539"></a>00539 <span class="comment"> * network congestion) then the data will be buffered and scheduled for</span>
565
+ <a name="l00540"></a>00540 <span class="comment"> * sending later.</span>
566
+ <a name="l00541"></a>00541 <span class="comment"> *</span>
567
+ <a name="l00542"></a>00542 <span class="comment"> * If an I/O error was encountered then the action taken depends on the</span>
568
+ <a name="l00543"></a>00543 <span class="comment"> * value of &lt;em&gt;writeActionError&lt;/em&gt;. By default it is DISCONNECT_FULL,</span>
569
+ <a name="l00544"></a>00544 <span class="comment"> * meaning the client connection will be closed by calling</span>
570
+ <a name="l00545"></a>00545 <span class="comment"> * &lt;tt&gt;disconnect(true)&lt;/tt&gt;. This means this method could potentially</span>
571
+ <a name="l00546"></a>00546 <span class="comment"> * call the &lt;tt&gt;onDisconnect&lt;/tt&gt; callback.</span>
572
+ <a name="l00547"></a>00547 <span class="comment"> *</span>
573
+ <a name="l00548"></a>00548 <span class="comment"> * If the client connection is already being closed, has already</span>
574
+ <a name="l00549"></a>00549 <span class="comment"> * been closed or if the writer side is closed, then this method does</span>
575
+ <a name="l00550"></a>00550 <span class="comment"> * nothing.</span>
576
+ <a name="l00551"></a>00551 <span class="comment"> *</span>
577
+ <a name="l00552"></a>00552 <span class="comment"> * The &lt;tt&gt;onPendingDataFlushed&lt;/tt&gt; callback will be called after</span>
578
+ <a name="l00553"></a>00553 <span class="comment"> * this data and whatever existing pending data have been written</span>
579
+ <a name="l00554"></a>00554 <span class="comment"> * out. That may either be immediately or after a short period of</span>
580
+ <a name="l00555"></a>00555 <span class="comment"> * of time.</span>
581
+ <a name="l00556"></a>00556 <span class="comment"> */</span>
582
+ <a name="l00557"></a><a class="code" href="classPassenger_1_1EventedClient.html#aa07723456786b9f18b973bd88ff51e27">00557</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#aa07723456786b9f18b973bd88ff51e27" title="Sends data to this client.">write</a>(<span class="keyword">const</span> <a class="code" href="classPassenger_1_1StaticString.html" title="An immutable, static byte buffer.">StaticString</a> data[], <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> count) {
583
+ <a name="l00558"></a>00558 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1EventedClient.html#aca719fb03ade09839827a16caa0e6e30" title="Returns whether it is allowed to write data to the client.">writeAllowed</a>()) {
584
+ <a name="l00559"></a>00559 <span class="keywordflow">return</span>;
585
+ <a name="l00560"></a>00560 }
586
+ <a name="l00561"></a>00561
587
+ <a name="l00562"></a>00562 ssize_t ret;
588
+ <a name="l00563"></a>00563 this_thread::disable_interruption di;
589
+ <a name="l00564"></a>00564 this_thread::disable_syscall_interruption dsi;
590
+ <a name="l00565"></a>00565
591
+ <a name="l00566"></a>00566 ret = gatheredWrite(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>, data, count, outbox);
592
+ <a name="l00567"></a>00567 <span class="keywordflow">if</span> (ret == -1) {
593
+ <a name="l00568"></a>00568 <span class="keywordtype">int</span> e = errno;
594
+ <a name="l00569"></a>00569 <span class="keywordflow">if</span> (<a class="code" href="classPassenger_1_1EventedClient.html#afc0934988a978a25538b7d8f2566c90a" title="Controls what to do when a write error is encountered.">writeErrorAction</a> == <a class="code" href="classPassenger_1_1EventedClient.html#a931edf284fed32f74ebf9dc35d993f17a627c2190c3a4dc848dc1a332ef9f5105" title="Forcefully disconnect the client.">DISCONNECT_FULL</a>) {
595
+ <a name="l00570"></a>00570 <a class="code" href="classPassenger_1_1EventedClient.html#a5b1a3011165ea9a47f6fe668a5010a20" title="Disconnects the client.">disconnect</a>(<span class="keyword">true</span>);
596
+ <a name="l00571"></a>00571 } <span class="keywordflow">else</span> {
597
+ <a name="l00572"></a>00572 <a class="code" href="classPassenger_1_1EventedClient.html#a9161e34ddc473c00fe4df8fdb1d1baef" title="Close only the writer side of the client connection.">closeWrite</a>();
598
+ <a name="l00573"></a>00573 }
599
+ <a name="l00574"></a>00574 emitSystemErrorEvent(<span class="stringliteral">&quot;Cannot write data to client&quot;</span>, e);
600
+ <a name="l00575"></a>00575 } <span class="keywordflow">else</span> {
601
+ <a name="l00576"></a>00576 updateWatcherStates();
602
+ <a name="l00577"></a>00577 <span class="keywordflow">if</span> (outbox.empty()) {
603
+ <a name="l00578"></a>00578 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a22e93ce2be05a4f47dbeba95d79a79b9" title="Called after all pending outgoing data have been written out.">onPendingDataFlushed</a>);
604
+ <a name="l00579"></a>00579 }
605
+ <a name="l00580"></a>00580 }
606
+ <a name="l00581"></a>00581 }
607
+ <a name="l00582"></a>00582 <span class="comment"></span>
608
+ <a name="l00583"></a>00583 <span class="comment"> /**</span>
609
+ <a name="l00584"></a>00584 <span class="comment"> * Close only the writer side of the client connection.</span>
610
+ <a name="l00585"></a>00585 <span class="comment"> * After calling this method, subsequent write() calls won&#39;t do anything</span>
611
+ <a name="l00586"></a>00586 <span class="comment"> * anymore. Any pending outgoing data will be sent out whenever the</span>
612
+ <a name="l00587"></a>00587 <span class="comment"> * opportunity arises.</span>
613
+ <a name="l00588"></a>00588 <span class="comment"> *</span>
614
+ <a name="l00589"></a>00589 <span class="comment"> * This function does nothing if the client is being disconnected,</span>
615
+ <a name="l00590"></a>00590 <span class="comment"> * already disconnected or if only the writer side is closed.</span>
616
+ <a name="l00591"></a>00591 <span class="comment"> */</span>
617
+ <a name="l00592"></a><a class="code" href="classPassenger_1_1EventedClient.html#a9161e34ddc473c00fe4df8fdb1d1baef">00592</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#a9161e34ddc473c00fe4df8fdb1d1baef" title="Close only the writer side of the client connection.">closeWrite</a>() {
618
+ <a name="l00593"></a>00593 this_thread::disable_syscall_interruption dsi;
619
+ <a name="l00594"></a>00594
620
+ <a name="l00595"></a>00595 <span class="keywordflow">switch</span> (state) {
621
+ <a name="l00596"></a>00596 <span class="keywordflow">case</span> EC_CONNECTED:
622
+ <a name="l00597"></a>00597 assert(outbox.empty());
623
+ <a name="l00598"></a>00598 state = EC_RO_CONNECTED;
624
+ <a name="l00599"></a>00599 <span class="keywordflow">if</span> (syscalls::shutdown(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>, SHUT_WR) == -1) {
625
+ <a name="l00600"></a>00600 <span class="keywordtype">int</span> e = errno;
626
+ <a name="l00601"></a>00601 emitSystemErrorEvent(
627
+ <a name="l00602"></a>00602 <span class="stringliteral">&quot;Cannot shutdown writer half of the client socket&quot;</span>,
628
+ <a name="l00603"></a>00603 e);
629
+ <a name="l00604"></a>00604 }
630
+ <a name="l00605"></a>00605 <span class="keywordflow">break</span>;
631
+ <a name="l00606"></a>00606 <span class="keywordflow">case</span> EC_WRITES_PENDING:
632
+ <a name="l00607"></a>00607 <span class="keywordflow">case</span> EC_TOO_MANY_WRITES_PENDING:
633
+ <a name="l00608"></a>00608 state = EC_RO_CONNECTED_WITH_WRITES_PENDING;
634
+ <a name="l00609"></a>00609 <span class="keywordflow">break</span>;
635
+ <a name="l00610"></a>00610 <span class="keywordflow">default</span>:
636
+ <a name="l00611"></a>00611 <span class="keywordflow">break</span>;
637
+ <a name="l00612"></a>00612 }
638
+ <a name="l00613"></a>00613 updateWatcherStates();
639
+ <a name="l00614"></a>00614 }
640
+ <a name="l00615"></a>00615 <span class="comment"></span>
641
+ <a name="l00616"></a>00616 <span class="comment"> /**</span>
642
+ <a name="l00617"></a>00617 <span class="comment"> * Disconnects the client. This actually closes the underlying file</span>
643
+ <a name="l00618"></a>00618 <span class="comment"> * descriptor, even if the FileDescriptor object still has references.</span>
644
+ <a name="l00619"></a>00619 <span class="comment"> *</span>
645
+ <a name="l00620"></a>00620 <span class="comment"> * If &lt;em&gt;force&lt;/em&gt; is true then the client will be disconnected</span>
646
+ <a name="l00621"></a>00621 <span class="comment"> * immediately, and any pending outgoing data will be discarded.</span>
647
+ <a name="l00622"></a>00622 <span class="comment"> * Otherwise the client will be disconnected after all pending</span>
648
+ <a name="l00623"></a>00623 <span class="comment"> * outgoing data have been sent; in the mean time no new data can be</span>
649
+ <a name="l00624"></a>00624 <span class="comment"> * received from or sent to the client.</span>
650
+ <a name="l00625"></a>00625 <span class="comment"> *</span>
651
+ <a name="l00626"></a>00626 <span class="comment"> * After the client has actually been disconnected (which may be either</span>
652
+ <a name="l00627"></a>00627 <span class="comment"> * immediately or after a short period of time), a disconnect event will</span>
653
+ <a name="l00628"></a>00628 <span class="comment"> * be emitted.</span>
654
+ <a name="l00629"></a>00629 <span class="comment"> *</span>
655
+ <a name="l00630"></a>00630 <span class="comment"> * If the client connection has already been closed then this method</span>
656
+ <a name="l00631"></a>00631 <span class="comment"> * does nothing. If the client connection is being closed (because</span>
657
+ <a name="l00632"></a>00632 <span class="comment"> * there&#39;s pending outgoing data) then the behavior depends on the</span>
658
+ <a name="l00633"></a>00633 <span class="comment"> * &lt;tt&gt;force&lt;/tt&gt; argument: if true then the connection is closed</span>
659
+ <a name="l00634"></a>00634 <span class="comment"> * immediately and the pending data is discarded, otherwise this</span>
660
+ <a name="l00635"></a>00635 <span class="comment"> * method does nothing.</span>
661
+ <a name="l00636"></a>00636 <span class="comment"> *</span>
662
+ <a name="l00637"></a>00637 <span class="comment"> * The &lt;tt&gt;onDisconnect&lt;/tt&gt; callback will be called after the file</span>
663
+ <a name="l00638"></a>00638 <span class="comment"> * descriptor is closed, which is either immediately or after all</span>
664
+ <a name="l00639"></a>00639 <span class="comment"> * pending data has been sent out.</span>
665
+ <a name="l00640"></a>00640 <span class="comment"> */</span>
666
+ <a name="l00641"></a><a class="code" href="classPassenger_1_1EventedClient.html#a5b1a3011165ea9a47f6fe668a5010a20">00641</a> <span class="keywordtype">void</span> <a class="code" href="classPassenger_1_1EventedClient.html#a5b1a3011165ea9a47f6fe668a5010a20" title="Disconnects the client.">disconnect</a>(<span class="keywordtype">bool</span> force = <span class="keyword">false</span>) {
667
+ <a name="l00642"></a>00642 <span class="keywordflow">if</span> (!<a class="code" href="classPassenger_1_1EventedClient.html#a50436eb8ec0cc38b5a7278962e98a22c" title="Returns whether it is allowed to perform some kind of I/O with this client, either...">ioAllowed</a>() &amp;&amp; !(state == EC_DISCONNECTING_WITH_WRITES_PENDING &amp;&amp; force)) {
668
+ <a name="l00643"></a>00643 <span class="keywordflow">return</span>;
669
+ <a name="l00644"></a>00644 }
670
+ <a name="l00645"></a>00645
671
+ <a name="l00646"></a>00646 this_thread::disable_interruption di;
672
+ <a name="l00647"></a>00647 this_thread::disable_syscall_interruption dsi;
673
+ <a name="l00648"></a>00648
674
+ <a name="l00649"></a>00649 <span class="keywordflow">if</span> (state == EC_CONNECTED || state == EC_RO_CONNECTED || force) {
675
+ <a name="l00650"></a>00650 state = EC_DISCONNECTED;
676
+ <a name="l00651"></a>00651 watchReadEvents(<span class="keyword">false</span>);
677
+ <a name="l00652"></a>00652 watchWriteEvents(<span class="keyword">false</span>);
678
+ <a name="l00653"></a>00653 <span class="keywordflow">try</span> {
679
+ <a name="l00654"></a>00654 <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>.<a class="code" href="classPassenger_1_1FileDescriptor.html#a02062f3cfb689b32781e11114c0abe5b" title="Close the underlying file descriptor.">close</a>();
680
+ <a name="l00655"></a>00655 } <span class="keywordflow">catch</span> (<span class="keyword">const</span> <a class="code" href="classPassenger_1_1SystemException.html" title="Represents an error returned by a system call or a standard library call.">SystemException</a> &amp;e) {
681
+ <a name="l00656"></a>00656 emitSystemErrorEvent(e.<a class="code" href="classPassenger_1_1SystemException.html#a84fa2ab4f5b7b96704734fcdfdaa0269" title="Returns a brief version of the exception message.">brief</a>(), e.<a class="code" href="classPassenger_1_1SystemException.html#aee7a6672bf79b72a4c3ee70c57d6a47c" title="The value of errno at the time the error occured.">code</a>());
682
+ <a name="l00657"></a>00657 }
683
+ <a name="l00658"></a>00658 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a211210ecd85eb2da47d200215132bb2d" title="Called when the client is disconnected.">onDisconnect</a>);
684
+ <a name="l00659"></a>00659 } <span class="keywordflow">else</span> {
685
+ <a name="l00660"></a>00660 state = EC_DISCONNECTING_WITH_WRITES_PENDING;
686
+ <a name="l00661"></a>00661 watchReadEvents(<span class="keyword">false</span>);
687
+ <a name="l00662"></a>00662 watchWriteEvents(<span class="keyword">true</span>);
688
+ <a name="l00663"></a>00663 <span class="keywordflow">if</span> (syscalls::shutdown(<a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>, SHUT_RD) == -1) {
689
+ <a name="l00664"></a>00664 <span class="keywordtype">int</span> e = errno;
690
+ <a name="l00665"></a>00665 emitSystemErrorEvent(
691
+ <a name="l00666"></a>00666 <span class="stringliteral">&quot;Cannot shutdown reader half of the client socket&quot;</span>,
692
+ <a name="l00667"></a>00667 e);
693
+ <a name="l00668"></a>00668 }
694
+ <a name="l00669"></a>00669 }
695
+ <a name="l00670"></a>00670 }
696
+ <a name="l00671"></a>00671 <span class="comment"></span>
697
+ <a name="l00672"></a>00672 <span class="comment"> /**</span>
698
+ <a name="l00673"></a>00673 <span class="comment"> * Detaches the client file descriptor so that this EventedClient no longer</span>
699
+ <a name="l00674"></a>00674 <span class="comment"> * has any control over it. Any EventedClient I/O watchers on the client file</span>
700
+ <a name="l00675"></a>00675 <span class="comment"> * descriptor will be stopped and further I/O on the file descriptor via</span>
701
+ <a name="l00676"></a>00676 <span class="comment"> * EventedClient will become impossible. Any pending outgoing data will be</span>
702
+ <a name="l00677"></a>00677 <span class="comment"> * discarded. The original client file descriptor is returned and</span>
703
+ <a name="l00678"></a>00678 <span class="comment"> * &lt;tt&gt;onDetach&lt;/tt&gt; is called. Subsequent calls to this function will</span>
704
+ <a name="l00679"></a>00679 <span class="comment"> * return -1 and will no longer call &lt;tt&gt;onDetach&lt;/tt&gt;.</span>
705
+ <a name="l00680"></a>00680 <span class="comment"> *</span>
706
+ <a name="l00681"></a>00681 <span class="comment"> * @post !ioAllowed()</span>
707
+ <a name="l00682"></a>00682 <span class="comment"> * @post fd == -1</span>
708
+ <a name="l00683"></a>00683 <span class="comment"> */</span>
709
+ <a name="l00684"></a><a class="code" href="classPassenger_1_1EventedClient.html#a408b593d118c3483bcef8118a7edba0f">00684</a> <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> <a class="code" href="classPassenger_1_1EventedClient.html#a408b593d118c3483bcef8118a7edba0f" title="Detaches the client file descriptor so that this EventedClient no longer has any...">detach</a>() {
710
+ <a name="l00685"></a>00685 <span class="keywordflow">if</span> (state == EC_DISCONNECTED) {
711
+ <a name="l00686"></a>00686 <span class="keywordflow">return</span> <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>;
712
+ <a name="l00687"></a>00687 } <span class="keywordflow">else</span> {
713
+ <a name="l00688"></a>00688 <a class="code" href="classPassenger_1_1FileDescriptor.html" title="Wrapper class around a file descriptor integer, for RAII behavior.">FileDescriptor</a> oldFd = <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a>;
714
+ <a name="l00689"></a>00689 state = EC_DISCONNECTED;
715
+ <a name="l00690"></a>00690 watchReadEvents(<span class="keyword">false</span>);
716
+ <a name="l00691"></a>00691 watchWriteEvents(<span class="keyword">false</span>);
717
+ <a name="l00692"></a>00692 <a class="code" href="classPassenger_1_1EventedClient.html#a4473719c16cae760e1811b7ccb1dc491" title="The client&amp;#39;s file descriptor.">fd</a> = -1;
718
+ <a name="l00693"></a>00693 emitEvent(<a class="code" href="classPassenger_1_1EventedClient.html#a742805d40508b0af89eb2ed2c1e50060" title="Called when detach() is called for the first time.">onDetach</a>);
719
+ <a name="l00694"></a>00694 <span class="keywordflow">return</span> oldFd;
720
+ <a name="l00695"></a>00695 }
721
+ <a name="l00696"></a>00696 }
722
+ <a name="l00697"></a>00697 };
723
+ <a name="l00698"></a>00698
724
+ <a name="l00699"></a>00699
725
+ <a name="l00700"></a>00700 } <span class="comment">// namespace Passenger</span>
726
+ <a name="l00701"></a>00701
727
+ <a name="l00702"></a>00702 <span class="preprocessor">#endif </span><span class="comment">/* _PASSENGER_EVENTED_CLIENT_H_ */</span>
728
+ </pre></div></div>
729
+ <hr size="1"/><address style="text-align: right;"><small>Generated by&nbsp;
730
+ <a href="http://www.doxygen.org/index.html">
731
+ <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.2 </small></address>
732
+ </body>
733
+ </html>