zeroc-ice 3.6b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (675) hide show
  1. checksums.yaml +7 -0
  2. data/ICE_LICENSE +54 -0
  3. data/LICENSE +339 -0
  4. data/bin/slice2rb +17 -0
  5. data/ext/Communicator.cpp +596 -0
  6. data/ext/Communicator.h +25 -0
  7. data/ext/Config.h +111 -0
  8. data/ext/Connection.cpp +381 -0
  9. data/ext/Connection.h +26 -0
  10. data/ext/Endpoint.cpp +311 -0
  11. data/ext/Endpoint.h +27 -0
  12. data/ext/ImplicitContext.cpp +152 -0
  13. data/ext/ImplicitContext.h +25 -0
  14. data/ext/Init.cpp +52 -0
  15. data/ext/Logger.cpp +151 -0
  16. data/ext/Logger.h +28 -0
  17. data/ext/ObjectFactory.cpp +140 -0
  18. data/ext/ObjectFactory.h +50 -0
  19. data/ext/Operation.cpp +676 -0
  20. data/ext/Operation.h +36 -0
  21. data/ext/Properties.cpp +369 -0
  22. data/ext/Properties.h +25 -0
  23. data/ext/Proxy.cpp +1354 -0
  24. data/ext/Proxy.h +27 -0
  25. data/ext/Slice.cpp +223 -0
  26. data/ext/Slice.h +22 -0
  27. data/ext/Types.cpp +3160 -0
  28. data/ext/Types.h +545 -0
  29. data/ext/Util.cpp +792 -0
  30. data/ext/Util.h +511 -0
  31. data/ext/extconf.rb +118 -0
  32. data/ext/ice/BZIP_LICENSE +42 -0
  33. data/ext/ice/MCPP_LICENSE +36 -0
  34. data/ext/ice/bzip2/blocksort.c +1094 -0
  35. data/ext/ice/bzip2/bzlib.c +1572 -0
  36. data/ext/ice/bzip2/bzlib.h +282 -0
  37. data/ext/ice/bzip2/bzlib_private.h +509 -0
  38. data/ext/ice/bzip2/compress.c +672 -0
  39. data/ext/ice/bzip2/crctable.c +104 -0
  40. data/ext/ice/bzip2/decompress.c +646 -0
  41. data/ext/ice/bzip2/huffman.c +205 -0
  42. data/ext/ice/bzip2/randtable.c +84 -0
  43. data/ext/ice/cpp/include/Ice/ACMF.h +30 -0
  44. data/ext/ice/cpp/include/Ice/Application.h +156 -0
  45. data/ext/ice/cpp/include/Ice/AsyncResult.h +363 -0
  46. data/ext/ice/cpp/include/Ice/AsyncResultF.h +26 -0
  47. data/ext/ice/cpp/include/Ice/BasicStream.h +1315 -0
  48. data/ext/ice/cpp/include/Ice/Buffer.h +159 -0
  49. data/ext/ice/cpp/include/Ice/BuiltinSequences.h +74 -0
  50. data/ext/ice/cpp/include/Ice/Communicator.h +194 -0
  51. data/ext/ice/cpp/include/Ice/CommunicatorAsync.h +115 -0
  52. data/ext/ice/cpp/include/Ice/CommunicatorF.h +60 -0
  53. data/ext/ice/cpp/include/Ice/Config.h +97 -0
  54. data/ext/ice/cpp/include/Ice/Connection.h +495 -0
  55. data/ext/ice/cpp/include/Ice/ConnectionAsync.h +115 -0
  56. data/ext/ice/cpp/include/Ice/ConnectionF.h +72 -0
  57. data/ext/ice/cpp/include/Ice/ConnectionFactoryF.h +30 -0
  58. data/ext/ice/cpp/include/Ice/ConnectionIF.h +37 -0
  59. data/ext/ice/cpp/include/Ice/Current.h +94 -0
  60. data/ext/ice/cpp/include/Ice/DefaultObjectFactory.h +48 -0
  61. data/ext/ice/cpp/include/Ice/DeprecatedStringConverter.h +62 -0
  62. data/ext/ice/cpp/include/Ice/DispatchInterceptor.h +33 -0
  63. data/ext/ice/cpp/include/Ice/Dispatcher.h +51 -0
  64. data/ext/ice/cpp/include/Ice/DynamicLibrary.h +105 -0
  65. data/ext/ice/cpp/include/Ice/DynamicLibraryF.h +29 -0
  66. data/ext/ice/cpp/include/Ice/Endpoint.h +350 -0
  67. data/ext/ice/cpp/include/Ice/EndpointF.h +97 -0
  68. data/ext/ice/cpp/include/Ice/EndpointTypes.h +74 -0
  69. data/ext/ice/cpp/include/Ice/Exception.h +114 -0
  70. data/ext/ice/cpp/include/Ice/FacetMap.h +56 -0
  71. data/ext/ice/cpp/include/Ice/FactoryTable.h +69 -0
  72. data/ext/ice/cpp/include/Ice/FactoryTableInit.h +87 -0
  73. data/ext/ice/cpp/include/Ice/Format.h +39 -0
  74. data/ext/ice/cpp/include/Ice/Functional.h +138 -0
  75. data/ext/ice/cpp/include/Ice/GCObject.h +73 -0
  76. data/ext/ice/cpp/include/Ice/Handle.h +192 -0
  77. data/ext/ice/cpp/include/Ice/Ice.h +54 -0
  78. data/ext/ice/cpp/include/Ice/Identity.h +160 -0
  79. data/ext/ice/cpp/include/Ice/ImplicitContext.h +96 -0
  80. data/ext/ice/cpp/include/Ice/ImplicitContextF.h +60 -0
  81. data/ext/ice/cpp/include/Ice/Incoming.h +131 -0
  82. data/ext/ice/cpp/include/Ice/IncomingAsync.h +108 -0
  83. data/ext/ice/cpp/include/Ice/IncomingAsyncF.h +35 -0
  84. data/ext/ice/cpp/include/Ice/Initialize.h +141 -0
  85. data/ext/ice/cpp/include/Ice/InstanceF.h +26 -0
  86. data/ext/ice/cpp/include/Ice/Instrumentation.h +377 -0
  87. data/ext/ice/cpp/include/Ice/InstrumentationF.h +71 -0
  88. data/ext/ice/cpp/include/Ice/LocalException.h +1022 -0
  89. data/ext/ice/cpp/include/Ice/LocalObject.h +36 -0
  90. data/ext/ice/cpp/include/Ice/LocalObjectF.h +26 -0
  91. data/ext/ice/cpp/include/Ice/Locator.h +2191 -0
  92. data/ext/ice/cpp/include/Ice/LocatorF.h +89 -0
  93. data/ext/ice/cpp/include/Ice/Logger.h +94 -0
  94. data/ext/ice/cpp/include/Ice/LoggerF.h +60 -0
  95. data/ext/ice/cpp/include/Ice/LoggerUtil.h +153 -0
  96. data/ext/ice/cpp/include/Ice/Makefile +26 -0
  97. data/ext/ice/cpp/include/Ice/Metrics.h +2989 -0
  98. data/ext/ice/cpp/include/Ice/MetricsAdminI.h +662 -0
  99. data/ext/ice/cpp/include/Ice/MetricsFunctional.h +144 -0
  100. data/ext/ice/cpp/include/Ice/MetricsObserverI.h +576 -0
  101. data/ext/ice/cpp/include/Ice/NativePropertiesAdmin.h +55 -0
  102. data/ext/ice/cpp/include/Ice/Object.h +165 -0
  103. data/ext/ice/cpp/include/Ice/ObjectAdapter.h +162 -0
  104. data/ext/ice/cpp/include/Ice/ObjectAdapterF.h +60 -0
  105. data/ext/ice/cpp/include/Ice/ObjectAdapterFactoryF.h +26 -0
  106. data/ext/ice/cpp/include/Ice/ObjectF.h +26 -0
  107. data/ext/ice/cpp/include/Ice/ObjectFactory.h +86 -0
  108. data/ext/ice/cpp/include/Ice/ObjectFactoryF.h +60 -0
  109. data/ext/ice/cpp/include/Ice/ObjectFactoryManagerF.h +26 -0
  110. data/ext/ice/cpp/include/Ice/ObserverHelper.h +177 -0
  111. data/ext/ice/cpp/include/Ice/Outgoing.h +197 -0
  112. data/ext/ice/cpp/include/Ice/OutgoingAsync.h +264 -0
  113. data/ext/ice/cpp/include/Ice/OutgoingAsyncF.h +38 -0
  114. data/ext/ice/cpp/include/Ice/Plugin.h +121 -0
  115. data/ext/ice/cpp/include/Ice/PluginF.h +66 -0
  116. data/ext/ice/cpp/include/Ice/Process.h +568 -0
  117. data/ext/ice/cpp/include/Ice/ProcessF.h +77 -0
  118. data/ext/ice/cpp/include/Ice/Properties.h +130 -0
  119. data/ext/ice/cpp/include/Ice/PropertiesAdmin.h +824 -0
  120. data/ext/ice/cpp/include/Ice/PropertiesF.h +83 -0
  121. data/ext/ice/cpp/include/Ice/Protocol.h +242 -0
  122. data/ext/ice/cpp/include/Ice/Proxy.h +2448 -0
  123. data/ext/ice/cpp/include/Ice/ProxyF.h +78 -0
  124. data/ext/ice/cpp/include/Ice/ProxyFactoryF.h +26 -0
  125. data/ext/ice/cpp/include/Ice/ProxyHandle.h +330 -0
  126. data/ext/ice/cpp/include/Ice/ReferenceF.h +34 -0
  127. data/ext/ice/cpp/include/Ice/RemoteLogger.h +1496 -0
  128. data/ext/ice/cpp/include/Ice/RequestHandlerF.h +29 -0
  129. data/ext/ice/cpp/include/Ice/ResponseHandlerF.h +25 -0
  130. data/ext/ice/cpp/include/Ice/Router.h +1155 -0
  131. data/ext/ice/cpp/include/Ice/RouterF.h +77 -0
  132. data/ext/ice/cpp/include/Ice/ServantLocator.h +90 -0
  133. data/ext/ice/cpp/include/Ice/ServantLocatorF.h +60 -0
  134. data/ext/ice/cpp/include/Ice/ServantManagerF.h +26 -0
  135. data/ext/ice/cpp/include/Ice/Service.h +260 -0
  136. data/ext/ice/cpp/include/Ice/SliceChecksumDict.h +56 -0
  137. data/ext/ice/cpp/include/Ice/SliceChecksums.h +34 -0
  138. data/ext/ice/cpp/include/Ice/SlicedData.h +103 -0
  139. data/ext/ice/cpp/include/Ice/SlicedDataF.h +34 -0
  140. data/ext/ice/cpp/include/Ice/Stream.h +449 -0
  141. data/ext/ice/cpp/include/Ice/StreamF.h +30 -0
  142. data/ext/ice/cpp/include/Ice/StreamHelpers.h +877 -0
  143. data/ext/ice/cpp/include/Ice/ThreadPoolF.h +28 -0
  144. data/ext/ice/cpp/include/Ice/UserExceptionFactory.h +56 -0
  145. data/ext/ice/cpp/include/Ice/Version.h +254 -0
  146. data/ext/ice/cpp/include/IceSSL/Config.h +23 -0
  147. data/ext/ice/cpp/include/IceSSL/ConnectionInfo.h +119 -0
  148. data/ext/ice/cpp/include/IceSSL/EndpointInfo.h +101 -0
  149. data/ext/ice/cpp/include/IceSSL/IceSSL.h +22 -0
  150. data/ext/ice/cpp/include/IceSSL/Makefile +26 -0
  151. data/ext/ice/cpp/include/IceSSL/Plugin.h +558 -0
  152. data/ext/ice/cpp/include/IceUtil/AbstractMutex.h +119 -0
  153. data/ext/ice/cpp/include/IceUtil/Cache.h +362 -0
  154. data/ext/ice/cpp/include/IceUtil/Cond.h +323 -0
  155. data/ext/ice/cpp/include/IceUtil/Config.h +234 -0
  156. data/ext/ice/cpp/include/IceUtil/CountDownLatch.h +50 -0
  157. data/ext/ice/cpp/include/IceUtil/CtrlCHandler.h +70 -0
  158. data/ext/ice/cpp/include/IceUtil/DisableWarnings.h +45 -0
  159. data/ext/ice/cpp/include/IceUtil/Exception.h +184 -0
  160. data/ext/ice/cpp/include/IceUtil/Functional.h +389 -0
  161. data/ext/ice/cpp/include/IceUtil/Handle.h +266 -0
  162. data/ext/ice/cpp/include/IceUtil/IceUtil.h +51 -0
  163. data/ext/ice/cpp/include/IceUtil/IconvStringConverter.h +302 -0
  164. data/ext/ice/cpp/include/IceUtil/InputUtil.h +47 -0
  165. data/ext/ice/cpp/include/IceUtil/Iterator.h +36 -0
  166. data/ext/ice/cpp/include/IceUtil/Lock.h +135 -0
  167. data/ext/ice/cpp/include/IceUtil/Makefile +26 -0
  168. data/ext/ice/cpp/include/IceUtil/Monitor.h +249 -0
  169. data/ext/ice/cpp/include/IceUtil/Mutex.h +357 -0
  170. data/ext/ice/cpp/include/IceUtil/MutexProtocol.h +28 -0
  171. data/ext/ice/cpp/include/IceUtil/MutexPtrLock.h +83 -0
  172. data/ext/ice/cpp/include/IceUtil/MutexPtrTryLock.h +82 -0
  173. data/ext/ice/cpp/include/IceUtil/Optional.h +322 -0
  174. data/ext/ice/cpp/include/IceUtil/Options.h +141 -0
  175. data/ext/ice/cpp/include/IceUtil/OutputUtil.h +362 -0
  176. data/ext/ice/cpp/include/IceUtil/PopDisableWarnings.h +19 -0
  177. data/ext/ice/cpp/include/IceUtil/PushDisableWarnings.h +26 -0
  178. data/ext/ice/cpp/include/IceUtil/Random.h +24 -0
  179. data/ext/ice/cpp/include/IceUtil/RecMutex.h +113 -0
  180. data/ext/ice/cpp/include/IceUtil/SHA1.h +65 -0
  181. data/ext/ice/cpp/include/IceUtil/ScannerConfig.h +44 -0
  182. data/ext/ice/cpp/include/IceUtil/ScopedArray.h +97 -0
  183. data/ext/ice/cpp/include/IceUtil/Shared.h +168 -0
  184. data/ext/ice/cpp/include/IceUtil/StringConverter.h +175 -0
  185. data/ext/ice/cpp/include/IceUtil/StringUtil.h +91 -0
  186. data/ext/ice/cpp/include/IceUtil/Thread.h +181 -0
  187. data/ext/ice/cpp/include/IceUtil/ThreadException.h +108 -0
  188. data/ext/ice/cpp/include/IceUtil/Time.h +209 -0
  189. data/ext/ice/cpp/include/IceUtil/Timer.h +143 -0
  190. data/ext/ice/cpp/include/IceUtil/UUID.h +22 -0
  191. data/ext/ice/cpp/include/IceUtil/UndefSysMacros.h +42 -0
  192. data/ext/ice/cpp/include/IceUtil/UniquePtr.h +101 -0
  193. data/ext/ice/cpp/include/Slice/CPlusPlusUtil.h +64 -0
  194. data/ext/ice/cpp/include/Slice/Checksum.h +26 -0
  195. data/ext/ice/cpp/include/Slice/CsUtil.h +92 -0
  196. data/ext/ice/cpp/include/Slice/DotNetNames.h +34 -0
  197. data/ext/ice/cpp/include/Slice/FileTracker.h +71 -0
  198. data/ext/ice/cpp/include/Slice/JavaUtil.h +277 -0
  199. data/ext/ice/cpp/include/Slice/Makefile +26 -0
  200. data/ext/ice/cpp/include/Slice/PHPUtil.h +50 -0
  201. data/ext/ice/cpp/include/Slice/Parser.h +1116 -0
  202. data/ext/ice/cpp/include/Slice/Preprocessor.h +68 -0
  203. data/ext/ice/cpp/include/Slice/PythonUtil.h +64 -0
  204. data/ext/ice/cpp/include/Slice/RubyUtil.h +54 -0
  205. data/ext/ice/cpp/include/Slice/Util.h +33 -0
  206. data/ext/ice/cpp/src/Ice/ACM.cpp +343 -0
  207. data/ext/ice/cpp/src/Ice/ACM.h +117 -0
  208. data/ext/ice/cpp/src/Ice/Acceptor.cpp +16 -0
  209. data/ext/ice/cpp/src/Ice/Acceptor.h +41 -0
  210. data/ext/ice/cpp/src/Ice/AcceptorF.h +30 -0
  211. data/ext/ice/cpp/src/Ice/Application.cpp +760 -0
  212. data/ext/ice/cpp/src/Ice/AsyncResult.cpp +599 -0
  213. data/ext/ice/cpp/src/Ice/Base64.cpp +269 -0
  214. data/ext/ice/cpp/src/Ice/Base64.h +36 -0
  215. data/ext/ice/cpp/src/Ice/BasicStream.cpp +3393 -0
  216. data/ext/ice/cpp/src/Ice/Buffer.cpp +98 -0
  217. data/ext/ice/cpp/src/Ice/BuiltinSequences.cpp +34 -0
  218. data/ext/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +718 -0
  219. data/ext/ice/cpp/src/Ice/CollocatedRequestHandler.h +106 -0
  220. data/ext/ice/cpp/src/Ice/Communicator.cpp +45 -0
  221. data/ext/ice/cpp/src/Ice/CommunicatorF.cpp +38 -0
  222. data/ext/ice/cpp/src/Ice/CommunicatorI.cpp +386 -0
  223. data/ext/ice/cpp/src/Ice/CommunicatorI.h +112 -0
  224. data/ext/ice/cpp/src/Ice/ConnectRequestHandler.cpp +546 -0
  225. data/ext/ice/cpp/src/Ice/ConnectRequestHandler.h +97 -0
  226. data/ext/ice/cpp/src/Ice/Connection.cpp +58 -0
  227. data/ext/ice/cpp/src/Ice/ConnectionF.cpp +38 -0
  228. data/ext/ice/cpp/src/Ice/ConnectionFactory.cpp +1639 -0
  229. data/ext/ice/cpp/src/Ice/ConnectionFactory.h +236 -0
  230. data/ext/ice/cpp/src/Ice/ConnectionI.cpp +3876 -0
  231. data/ext/ice/cpp/src/Ice/ConnectionI.h +364 -0
  232. data/ext/ice/cpp/src/Ice/ConnectionRequestHandler.cpp +115 -0
  233. data/ext/ice/cpp/src/Ice/ConnectionRequestHandler.h +50 -0
  234. data/ext/ice/cpp/src/Ice/Connector.cpp +16 -0
  235. data/ext/ice/cpp/src/Ice/Connector.h +36 -0
  236. data/ext/ice/cpp/src/Ice/ConnectorF.h +26 -0
  237. data/ext/ice/cpp/src/Ice/Current.cpp +38 -0
  238. data/ext/ice/cpp/src/Ice/DefaultsAndOverrides.cpp +168 -0
  239. data/ext/ice/cpp/src/Ice/DefaultsAndOverrides.h +57 -0
  240. data/ext/ice/cpp/src/Ice/DefaultsAndOverridesF.h +26 -0
  241. data/ext/ice/cpp/src/Ice/DeprecatedStringConverter.cpp +60 -0
  242. data/ext/ice/cpp/src/Ice/DispatchInterceptor.cpp +49 -0
  243. data/ext/ice/cpp/src/Ice/DynamicLibrary.cpp +281 -0
  244. data/ext/ice/cpp/src/Ice/Endpoint.cpp +53 -0
  245. data/ext/ice/cpp/src/Ice/EndpointF.cpp +38 -0
  246. data/ext/ice/cpp/src/Ice/EndpointFactory.cpp +25 -0
  247. data/ext/ice/cpp/src/Ice/EndpointFactory.h +44 -0
  248. data/ext/ice/cpp/src/Ice/EndpointFactoryF.h +26 -0
  249. data/ext/ice/cpp/src/Ice/EndpointFactoryManager.cpp +208 -0
  250. data/ext/ice/cpp/src/Ice/EndpointFactoryManager.h +46 -0
  251. data/ext/ice/cpp/src/Ice/EndpointFactoryManagerF.h +26 -0
  252. data/ext/ice/cpp/src/Ice/EndpointI.cpp +87 -0
  253. data/ext/ice/cpp/src/Ice/EndpointI.h +165 -0
  254. data/ext/ice/cpp/src/Ice/EndpointIF.h +41 -0
  255. data/ext/ice/cpp/src/Ice/EndpointTypes.cpp +38 -0
  256. data/ext/ice/cpp/src/Ice/EventHandler.cpp +35 -0
  257. data/ext/ice/cpp/src/Ice/EventHandler.h +78 -0
  258. data/ext/ice/cpp/src/Ice/EventHandlerF.h +26 -0
  259. data/ext/ice/cpp/src/Ice/EventLoggerMsg.h +53 -0
  260. data/ext/ice/cpp/src/Ice/Exception.cpp +832 -0
  261. data/ext/ice/cpp/src/Ice/FacetMap.cpp +34 -0
  262. data/ext/ice/cpp/src/Ice/FactoryTable.cpp +158 -0
  263. data/ext/ice/cpp/src/Ice/FactoryTableInit.cpp +95 -0
  264. data/ext/ice/cpp/src/Ice/GCObject.cpp +444 -0
  265. data/ext/ice/cpp/src/Ice/HashUtil.h +59 -0
  266. data/ext/ice/cpp/src/Ice/HttpParser.cpp +680 -0
  267. data/ext/ice/cpp/src/Ice/HttpParser.h +124 -0
  268. data/ext/ice/cpp/src/Ice/IPEndpointI.cpp +733 -0
  269. data/ext/ice/cpp/src/Ice/IPEndpointI.h +157 -0
  270. data/ext/ice/cpp/src/Ice/IPEndpointIF.h +29 -0
  271. data/ext/ice/cpp/src/Ice/Identity.cpp +42 -0
  272. data/ext/ice/cpp/src/Ice/ImplicitContext.cpp +41 -0
  273. data/ext/ice/cpp/src/Ice/ImplicitContextF.cpp +38 -0
  274. data/ext/ice/cpp/src/Ice/ImplicitContextI.cpp +639 -0
  275. data/ext/ice/cpp/src/Ice/ImplicitContextI.h +51 -0
  276. data/ext/ice/cpp/src/Ice/Incoming.cpp +757 -0
  277. data/ext/ice/cpp/src/Ice/IncomingAsync.cpp +340 -0
  278. data/ext/ice/cpp/src/Ice/IncomingRequest.h +37 -0
  279. data/ext/ice/cpp/src/Ice/Initialize.cpp +401 -0
  280. data/ext/ice/cpp/src/Ice/Instance.cpp +1928 -0
  281. data/ext/ice/cpp/src/Ice/Instance.h +198 -0
  282. data/ext/ice/cpp/src/Ice/Instrumentation.cpp +68 -0
  283. data/ext/ice/cpp/src/Ice/InstrumentationF.cpp +43 -0
  284. data/ext/ice/cpp/src/Ice/InstrumentationI.cpp +1083 -0
  285. data/ext/ice/cpp/src/Ice/InstrumentationI.h +262 -0
  286. data/ext/ice/cpp/src/Ice/LocalException.cpp +2091 -0
  287. data/ext/ice/cpp/src/Ice/LocalObject.cpp +29 -0
  288. data/ext/ice/cpp/src/Ice/Locator.cpp +1946 -0
  289. data/ext/ice/cpp/src/Ice/LocatorF.cpp +39 -0
  290. data/ext/ice/cpp/src/Ice/LocatorInfo.cpp +917 -0
  291. data/ext/ice/cpp/src/Ice/LocatorInfo.h +193 -0
  292. data/ext/ice/cpp/src/Ice/LocatorInfoF.h +34 -0
  293. data/ext/ice/cpp/src/Ice/Logger.cpp +40 -0
  294. data/ext/ice/cpp/src/Ice/LoggerAdminI.cpp +862 -0
  295. data/ext/ice/cpp/src/Ice/LoggerAdminI.h +46 -0
  296. data/ext/ice/cpp/src/Ice/LoggerF.cpp +38 -0
  297. data/ext/ice/cpp/src/Ice/LoggerI.cpp +199 -0
  298. data/ext/ice/cpp/src/Ice/LoggerI.h +57 -0
  299. data/ext/ice/cpp/src/Ice/LoggerUtil.cpp +107 -0
  300. data/ext/ice/cpp/src/Ice/Makefile +190 -0
  301. data/ext/ice/cpp/src/Ice/Metrics.cpp +2159 -0
  302. data/ext/ice/cpp/src/Ice/MetricsAdminI.cpp +669 -0
  303. data/ext/ice/cpp/src/Ice/MetricsObserverI.cpp +14 -0
  304. data/ext/ice/cpp/src/Ice/Network.cpp +2694 -0
  305. data/ext/ice/cpp/src/Ice/Network.h +291 -0
  306. data/ext/ice/cpp/src/Ice/NetworkF.h +28 -0
  307. data/ext/ice/cpp/src/Ice/NetworkProxy.cpp +325 -0
  308. data/ext/ice/cpp/src/Ice/NetworkProxy.h +74 -0
  309. data/ext/ice/cpp/src/Ice/NetworkProxyF.h +26 -0
  310. data/ext/ice/cpp/src/Ice/Object.cpp +440 -0
  311. data/ext/ice/cpp/src/Ice/ObjectAdapter.cpp +41 -0
  312. data/ext/ice/cpp/src/Ice/ObjectAdapterF.cpp +38 -0
  313. data/ext/ice/cpp/src/Ice/ObjectAdapterFactory.cpp +241 -0
  314. data/ext/ice/cpp/src/Ice/ObjectAdapterFactory.h +52 -0
  315. data/ext/ice/cpp/src/Ice/ObjectAdapterI.cpp +1498 -0
  316. data/ext/ice/cpp/src/Ice/ObjectAdapterI.h +155 -0
  317. data/ext/ice/cpp/src/Ice/ObjectFactory.cpp +41 -0
  318. data/ext/ice/cpp/src/Ice/ObjectFactoryF.cpp +38 -0
  319. data/ext/ice/cpp/src/Ice/ObjectFactoryManager.cpp +140 -0
  320. data/ext/ice/cpp/src/Ice/ObjectFactoryManager.h +43 -0
  321. data/ext/ice/cpp/src/Ice/ObserverHelper.cpp +84 -0
  322. data/ext/ice/cpp/src/Ice/OpaqueEndpointI.cpp +407 -0
  323. data/ext/ice/cpp/src/Ice/OpaqueEndpointI.h +70 -0
  324. data/ext/ice/cpp/src/Ice/Outgoing.cpp +737 -0
  325. data/ext/ice/cpp/src/Ice/OutgoingAsync.cpp +874 -0
  326. data/ext/ice/cpp/src/Ice/Plugin.cpp +43 -0
  327. data/ext/ice/cpp/src/Ice/PluginF.cpp +38 -0
  328. data/ext/ice/cpp/src/Ice/PluginManagerI.cpp +503 -0
  329. data/ext/ice/cpp/src/Ice/PluginManagerI.h +67 -0
  330. data/ext/ice/cpp/src/Ice/Process.cpp +299 -0
  331. data/ext/ice/cpp/src/Ice/ProcessF.cpp +39 -0
  332. data/ext/ice/cpp/src/Ice/Properties.cpp +45 -0
  333. data/ext/ice/cpp/src/Ice/PropertiesAdmin.cpp +555 -0
  334. data/ext/ice/cpp/src/Ice/PropertiesAdminI.cpp +207 -0
  335. data/ext/ice/cpp/src/Ice/PropertiesAdminI.h +45 -0
  336. data/ext/ice/cpp/src/Ice/PropertiesF.cpp +39 -0
  337. data/ext/ice/cpp/src/Ice/PropertiesI.cpp +759 -0
  338. data/ext/ice/cpp/src/Ice/PropertiesI.h +78 -0
  339. data/ext/ice/cpp/src/Ice/PropertyNames.cpp +1293 -0
  340. data/ext/ice/cpp/src/Ice/PropertyNames.h +81 -0
  341. data/ext/ice/cpp/src/Ice/Protocol.cpp +137 -0
  342. data/ext/ice/cpp/src/Ice/ProtocolInstance.cpp +98 -0
  343. data/ext/ice/cpp/src/Ice/ProtocolInstance.h +91 -0
  344. data/ext/ice/cpp/src/Ice/ProtocolInstanceF.h +26 -0
  345. data/ext/ice/cpp/src/Ice/ProtocolPluginFacade.cpp +51 -0
  346. data/ext/ice/cpp/src/Ice/ProtocolPluginFacade.h +67 -0
  347. data/ext/ice/cpp/src/Ice/ProtocolPluginFacadeF.h +26 -0
  348. data/ext/ice/cpp/src/Ice/Proxy.cpp +1810 -0
  349. data/ext/ice/cpp/src/Ice/ProxyFactory.cpp +305 -0
  350. data/ext/ice/cpp/src/Ice/ProxyFactory.h +57 -0
  351. data/ext/ice/cpp/src/Ice/Reference.cpp +1947 -0
  352. data/ext/ice/cpp/src/Ice/Reference.h +305 -0
  353. data/ext/ice/cpp/src/Ice/ReferenceFactory.cpp +937 -0
  354. data/ext/ice/cpp/src/Ice/ReferenceFactory.h +81 -0
  355. data/ext/ice/cpp/src/Ice/ReferenceFactoryF.h +24 -0
  356. data/ext/ice/cpp/src/Ice/RemoteLogger.cpp +958 -0
  357. data/ext/ice/cpp/src/Ice/ReplyStatus.h +29 -0
  358. data/ext/ice/cpp/src/Ice/RequestHandler.cpp +40 -0
  359. data/ext/ice/cpp/src/Ice/RequestHandler.h +90 -0
  360. data/ext/ice/cpp/src/Ice/RequestHandlerFactory.cpp +70 -0
  361. data/ext/ice/cpp/src/Ice/RequestHandlerFactory.h +41 -0
  362. data/ext/ice/cpp/src/Ice/ResponseHandler.cpp +20 -0
  363. data/ext/ice/cpp/src/Ice/ResponseHandler.h +39 -0
  364. data/ext/ice/cpp/src/Ice/RetryQueue.cpp +154 -0
  365. data/ext/ice/cpp/src/Ice/RetryQueue.h +69 -0
  366. data/ext/ice/cpp/src/Ice/RetryQueueF.h +24 -0
  367. data/ext/ice/cpp/src/Ice/Router.cpp +849 -0
  368. data/ext/ice/cpp/src/Ice/RouterF.cpp +39 -0
  369. data/ext/ice/cpp/src/Ice/RouterInfo.cpp +381 -0
  370. data/ext/ice/cpp/src/Ice/RouterInfo.h +148 -0
  371. data/ext/ice/cpp/src/Ice/RouterInfoF.h +30 -0
  372. data/ext/ice/cpp/src/Ice/Selector.cpp +926 -0
  373. data/ext/ice/cpp/src/Ice/Selector.h +231 -0
  374. data/ext/ice/cpp/src/Ice/ServantLocator.cpp +41 -0
  375. data/ext/ice/cpp/src/Ice/ServantLocatorF.cpp +38 -0
  376. data/ext/ice/cpp/src/Ice/ServantManager.cpp +495 -0
  377. data/ext/ice/cpp/src/Ice/ServantManager.h +74 -0
  378. data/ext/ice/cpp/src/Ice/Service.cpp +1897 -0
  379. data/ext/ice/cpp/src/Ice/SharedContext.h +51 -0
  380. data/ext/ice/cpp/src/Ice/SliceChecksumDict.cpp +34 -0
  381. data/ext/ice/cpp/src/Ice/SliceChecksums.cpp +80 -0
  382. data/ext/ice/cpp/src/Ice/SlicedData.cpp +80 -0
  383. data/ext/ice/cpp/src/Ice/Stream.cpp +53 -0
  384. data/ext/ice/cpp/src/Ice/StreamI.cpp +832 -0
  385. data/ext/ice/cpp/src/Ice/StreamI.h +198 -0
  386. data/ext/ice/cpp/src/Ice/StreamSocket.cpp +521 -0
  387. data/ext/ice/cpp/src/Ice/StreamSocket.h +85 -0
  388. data/ext/ice/cpp/src/Ice/StringConverterPlugin.cpp +145 -0
  389. data/ext/ice/cpp/src/Ice/SysLoggerI.cpp +167 -0
  390. data/ext/ice/cpp/src/Ice/SysLoggerI.h +43 -0
  391. data/ext/ice/cpp/src/Ice/TcpAcceptor.cpp +235 -0
  392. data/ext/ice/cpp/src/Ice/TcpAcceptor.h +67 -0
  393. data/ext/ice/cpp/src/Ice/TcpConnector.cpp +133 -0
  394. data/ext/ice/cpp/src/Ice/TcpConnector.h +51 -0
  395. data/ext/ice/cpp/src/Ice/TcpEndpointI.cpp +397 -0
  396. data/ext/ice/cpp/src/Ice/TcpEndpointI.h +93 -0
  397. data/ext/ice/cpp/src/Ice/TcpTransceiver.cpp +127 -0
  398. data/ext/ice/cpp/src/Ice/TcpTransceiver.h +61 -0
  399. data/ext/ice/cpp/src/Ice/ThreadPool.cpp +1357 -0
  400. data/ext/ice/cpp/src/Ice/ThreadPool.h +399 -0
  401. data/ext/ice/cpp/src/Ice/TraceLevels.cpp +43 -0
  402. data/ext/ice/cpp/src/Ice/TraceLevels.h +50 -0
  403. data/ext/ice/cpp/src/Ice/TraceLevelsF.h +26 -0
  404. data/ext/ice/cpp/src/Ice/TraceUtil.cpp +452 -0
  405. data/ext/ice/cpp/src/Ice/TraceUtil.h +28 -0
  406. data/ext/ice/cpp/src/Ice/Transceiver.cpp +24 -0
  407. data/ext/ice/cpp/src/Ice/Transceiver.h +52 -0
  408. data/ext/ice/cpp/src/Ice/TransceiverF.h +38 -0
  409. data/ext/ice/cpp/src/Ice/UdpConnector.cpp +144 -0
  410. data/ext/ice/cpp/src/Ice/UdpConnector.h +51 -0
  411. data/ext/ice/cpp/src/Ice/UdpEndpointI.cpp +483 -0
  412. data/ext/ice/cpp/src/Ice/UdpEndpointI.h +95 -0
  413. data/ext/ice/cpp/src/Ice/UdpTransceiver.cpp +1156 -0
  414. data/ext/ice/cpp/src/Ice/UdpTransceiver.h +123 -0
  415. data/ext/ice/cpp/src/Ice/Version.cpp +46 -0
  416. data/ext/ice/cpp/src/Ice/WSAcceptor.cpp +103 -0
  417. data/ext/ice/cpp/src/Ice/WSAcceptor.h +61 -0
  418. data/ext/ice/cpp/src/Ice/WSConnector.cpp +113 -0
  419. data/ext/ice/cpp/src/Ice/WSConnector.h +51 -0
  420. data/ext/ice/cpp/src/Ice/WSEndpoint.cpp +441 -0
  421. data/ext/ice/cpp/src/Ice/WSEndpoint.h +97 -0
  422. data/ext/ice/cpp/src/Ice/WSTransceiver.cpp +1728 -0
  423. data/ext/ice/cpp/src/Ice/WSTransceiver.h +149 -0
  424. data/ext/ice/cpp/src/IceDiscovery/IceDiscovery.cpp +594 -0
  425. data/ext/ice/cpp/src/IceDiscovery/IceDiscovery.h +1035 -0
  426. data/ext/ice/cpp/src/IceDiscovery/LocatorI.cpp +208 -0
  427. data/ext/ice/cpp/src/IceDiscovery/LocatorI.h +78 -0
  428. data/ext/ice/cpp/src/IceDiscovery/LookupI.cpp +308 -0
  429. data/ext/ice/cpp/src/IceDiscovery/LookupI.h +183 -0
  430. data/ext/ice/cpp/src/IceDiscovery/Makefile +61 -0
  431. data/ext/ice/cpp/src/IceDiscovery/PluginI.cpp +148 -0
  432. data/ext/ice/cpp/src/IceDiscovery/PluginI.h +39 -0
  433. data/ext/ice/cpp/src/IceSSL/AcceptorI.cpp +258 -0
  434. data/ext/ice/cpp/src/IceSSL/AcceptorI.h +66 -0
  435. data/ext/ice/cpp/src/IceSSL/Certificate.cpp +1334 -0
  436. data/ext/ice/cpp/src/IceSSL/ConnectionInfo.cpp +42 -0
  437. data/ext/ice/cpp/src/IceSSL/ConnectorI.cpp +151 -0
  438. data/ext/ice/cpp/src/IceSSL/ConnectorI.h +56 -0
  439. data/ext/ice/cpp/src/IceSSL/EndpointI.cpp +397 -0
  440. data/ext/ice/cpp/src/IceSSL/EndpointI.h +96 -0
  441. data/ext/ice/cpp/src/IceSSL/EndpointInfo.cpp +41 -0
  442. data/ext/ice/cpp/src/IceSSL/Instance.cpp +38 -0
  443. data/ext/ice/cpp/src/IceSSL/Instance.h +42 -0
  444. data/ext/ice/cpp/src/IceSSL/InstanceF.h +34 -0
  445. data/ext/ice/cpp/src/IceSSL/Makefile +82 -0
  446. data/ext/ice/cpp/src/IceSSL/OpenSSLEngine.cpp +1001 -0
  447. data/ext/ice/cpp/src/IceSSL/OpenSSLTransceiverI.cpp +607 -0
  448. data/ext/ice/cpp/src/IceSSL/OpenSSLTransceiverI.h +75 -0
  449. data/ext/ice/cpp/src/IceSSL/PluginI.cpp +102 -0
  450. data/ext/ice/cpp/src/IceSSL/PluginI.h +56 -0
  451. data/ext/ice/cpp/src/IceSSL/RFC2253.cpp +541 -0
  452. data/ext/ice/cpp/src/IceSSL/RFC2253.h +67 -0
  453. data/ext/ice/cpp/src/IceSSL/SChannelEngine.cpp +729 -0
  454. data/ext/ice/cpp/src/IceSSL/SChannelTransceiverI.cpp +1062 -0
  455. data/ext/ice/cpp/src/IceSSL/SChannelTransceiverI.h +130 -0
  456. data/ext/ice/cpp/src/IceSSL/SSLEngine.cpp +291 -0
  457. data/ext/ice/cpp/src/IceSSL/SSLEngine.h +264 -0
  458. data/ext/ice/cpp/src/IceSSL/SSLEngineF.h +41 -0
  459. data/ext/ice/cpp/src/IceSSL/SecureTransportEngine.cpp +1514 -0
  460. data/ext/ice/cpp/src/IceSSL/SecureTransportTransceiverI.cpp +609 -0
  461. data/ext/ice/cpp/src/IceSSL/SecureTransportTransceiverI.h +91 -0
  462. data/ext/ice/cpp/src/IceSSL/TrustManager.cpp +246 -0
  463. data/ext/ice/cpp/src/IceSSL/TrustManager.h +51 -0
  464. data/ext/ice/cpp/src/IceSSL/TrustManagerF.h +26 -0
  465. data/ext/ice/cpp/src/IceSSL/Util.cpp +1423 -0
  466. data/ext/ice/cpp/src/IceSSL/Util.h +136 -0
  467. data/ext/ice/cpp/src/IceUtil/ArgVector.cpp +65 -0
  468. data/ext/ice/cpp/src/IceUtil/ArgVector.h +41 -0
  469. data/ext/ice/cpp/src/IceUtil/Cond.cpp +386 -0
  470. data/ext/ice/cpp/src/IceUtil/ConvertUTF.cpp +477 -0
  471. data/ext/ice/cpp/src/IceUtil/ConvertUTF.h +144 -0
  472. data/ext/ice/cpp/src/IceUtil/CountDownLatch.cpp +184 -0
  473. data/ext/ice/cpp/src/IceUtil/CtrlCHandler.cpp +273 -0
  474. data/ext/ice/cpp/src/IceUtil/Exception.cpp +782 -0
  475. data/ext/ice/cpp/src/IceUtil/FileUtil.cpp +532 -0
  476. data/ext/ice/cpp/src/IceUtil/FileUtil.h +159 -0
  477. data/ext/ice/cpp/src/IceUtil/InputUtil.cpp +41 -0
  478. data/ext/ice/cpp/src/IceUtil/Makefile +68 -0
  479. data/ext/ice/cpp/src/IceUtil/MutexProtocol.cpp +24 -0
  480. data/ext/ice/cpp/src/IceUtil/Options.cpp +1049 -0
  481. data/ext/ice/cpp/src/IceUtil/OutputUtil.cpp +591 -0
  482. data/ext/ice/cpp/src/IceUtil/Random.cpp +185 -0
  483. data/ext/ice/cpp/src/IceUtil/RecMutex.cpp +257 -0
  484. data/ext/ice/cpp/src/IceUtil/SHA1.cpp +126 -0
  485. data/ext/ice/cpp/src/IceUtil/Shared.cpp +200 -0
  486. data/ext/ice/cpp/src/IceUtil/StopWatch.h +54 -0
  487. data/ext/ice/cpp/src/IceUtil/StringConverter.cpp +450 -0
  488. data/ext/ice/cpp/src/IceUtil/StringUtil.cpp +842 -0
  489. data/ext/ice/cpp/src/IceUtil/Thread.cpp +809 -0
  490. data/ext/ice/cpp/src/IceUtil/ThreadException.cpp +172 -0
  491. data/ext/ice/cpp/src/IceUtil/Time.cpp +306 -0
  492. data/ext/ice/cpp/src/IceUtil/Timer.cpp +251 -0
  493. data/ext/ice/cpp/src/IceUtil/UUID.cpp +174 -0
  494. data/ext/ice/cpp/src/IceUtil/Unicode.cpp +131 -0
  495. data/ext/ice/cpp/src/IceUtil/Unicode.h +49 -0
  496. data/ext/ice/cpp/src/Slice/CPlusPlusUtil.cpp +1139 -0
  497. data/ext/ice/cpp/src/Slice/Checksum.cpp +452 -0
  498. data/ext/ice/cpp/src/Slice/CsUtil.cpp +2650 -0
  499. data/ext/ice/cpp/src/Slice/DotNetNames.cpp +146 -0
  500. data/ext/ice/cpp/src/Slice/FileTracker.cpp +203 -0
  501. data/ext/ice/cpp/src/Slice/Grammar.cpp +4755 -0
  502. data/ext/ice/cpp/src/Slice/Grammar.h +98 -0
  503. data/ext/ice/cpp/src/Slice/GrammarUtil.h +234 -0
  504. data/ext/ice/cpp/src/Slice/JavaUtil.cpp +4376 -0
  505. data/ext/ice/cpp/src/Slice/MD5.cpp +57 -0
  506. data/ext/ice/cpp/src/Slice/MD5.h +44 -0
  507. data/ext/ice/cpp/src/Slice/MD5I.cpp +385 -0
  508. data/ext/ice/cpp/src/Slice/MD5I.h +91 -0
  509. data/ext/ice/cpp/src/Slice/Makefile +65 -0
  510. data/ext/ice/cpp/src/Slice/PHPUtil.cpp +156 -0
  511. data/ext/ice/cpp/src/Slice/Parser.cpp +6386 -0
  512. data/ext/ice/cpp/src/Slice/Preprocessor.cpp +686 -0
  513. data/ext/ice/cpp/src/Slice/Python.cpp +675 -0
  514. data/ext/ice/cpp/src/Slice/PythonUtil.cpp +2614 -0
  515. data/ext/ice/cpp/src/Slice/Ruby.cpp +317 -0
  516. data/ext/ice/cpp/src/Slice/RubyUtil.cpp +1774 -0
  517. data/ext/ice/cpp/src/Slice/Scanner.cpp +2426 -0
  518. data/ext/ice/cpp/src/Slice/Util.cpp +325 -0
  519. data/ext/ice/mcpp/config.h.Darwin +227 -0
  520. data/ext/ice/mcpp/config.h.Linux +227 -0
  521. data/ext/ice/mcpp/config.h.MINGW +7 -0
  522. data/ext/ice/mcpp/configed.H +382 -0
  523. data/ext/ice/mcpp/directive.c +1699 -0
  524. data/ext/ice/mcpp/eval.c +1673 -0
  525. data/ext/ice/mcpp/expand.c +2980 -0
  526. data/ext/ice/mcpp/internal.H +564 -0
  527. data/ext/ice/mcpp/main.c +1131 -0
  528. data/ext/ice/mcpp/mbchar.c +869 -0
  529. data/ext/ice/mcpp/mcpp_lib.h +31 -0
  530. data/ext/ice/mcpp/mcpp_out.h +13 -0
  531. data/ext/ice/mcpp/support.c +2811 -0
  532. data/ext/ice/mcpp/system.H +396 -0
  533. data/ext/ice/mcpp/system.c +4940 -0
  534. data/ice.gemspec +41 -0
  535. data/lib/Glacier2.rb +12 -0
  536. data/lib/Glacier2/Metrics.rb +99 -0
  537. data/lib/Glacier2/PermissionsVerifier.rb +168 -0
  538. data/lib/Glacier2/PermissionsVerifierF.rb +34 -0
  539. data/lib/Glacier2/Router.rb +141 -0
  540. data/lib/Glacier2/RouterF.rb +29 -0
  541. data/lib/Glacier2/SSLInfo.rb +79 -0
  542. data/lib/Glacier2/Session.rb +470 -0
  543. data/lib/Ice.rb +659 -0
  544. data/lib/Ice/BuiltinSequences.rb +64 -0
  545. data/lib/Ice/Communicator.rb +93 -0
  546. data/lib/Ice/CommunicatorF.rb +28 -0
  547. data/lib/Ice/Connection.rb +414 -0
  548. data/lib/Ice/ConnectionF.rb +36 -0
  549. data/lib/Ice/Current.rb +152 -0
  550. data/lib/Ice/Endpoint.rb +265 -0
  551. data/lib/Ice/EndpointF.rb +52 -0
  552. data/lib/Ice/EndpointTypes.rb +77 -0
  553. data/lib/Ice/FacetMap.rb +28 -0
  554. data/lib/Ice/Identity.rb +70 -0
  555. data/lib/Ice/ImplicitContext.rb +59 -0
  556. data/lib/Ice/ImplicitContextF.rb +28 -0
  557. data/lib/Ice/Instrumentation.rb +425 -0
  558. data/lib/Ice/InstrumentationF.rb +35 -0
  559. data/lib/Ice/LocalException.rb +1081 -0
  560. data/lib/Ice/Locator.rb +314 -0
  561. data/lib/Ice/LocatorF.rb +34 -0
  562. data/lib/Ice/Logger.rb +57 -0
  563. data/lib/Ice/LoggerF.rb +28 -0
  564. data/lib/Ice/Metrics.rb +696 -0
  565. data/lib/Ice/ObjectAdapterF.rb +28 -0
  566. data/lib/Ice/ObjectFactory.rb +53 -0
  567. data/lib/Ice/ObjectFactoryF.rb +28 -0
  568. data/lib/Ice/Plugin.rb +87 -0
  569. data/lib/Ice/PluginF.rb +32 -0
  570. data/lib/Ice/Process.rb +93 -0
  571. data/lib/Ice/ProcessF.rb +29 -0
  572. data/lib/Ice/Properties.rb +65 -0
  573. data/lib/Ice/PropertiesAdmin.rb +104 -0
  574. data/lib/Ice/PropertiesF.rb +33 -0
  575. data/lib/Ice/Router.rb +163 -0
  576. data/lib/Ice/RouterF.rb +29 -0
  577. data/lib/Ice/SliceChecksumDict.rb +28 -0
  578. data/lib/Ice/Version.rb +100 -0
  579. data/lib/IceBox.rb +10 -0
  580. data/lib/IceBox/IceBox.rb +272 -0
  581. data/lib/IceGrid.rb +17 -0
  582. data/lib/IceGrid/Admin.rb +1076 -0
  583. data/lib/IceGrid/Descriptor.rb +1505 -0
  584. data/lib/IceGrid/Exception.rb +401 -0
  585. data/lib/IceGrid/FileParser.rb +105 -0
  586. data/lib/IceGrid/Locator.rb +105 -0
  587. data/lib/IceGrid/Observer.rb +571 -0
  588. data/lib/IceGrid/Query.rb +168 -0
  589. data/lib/IceGrid/Registry.rb +120 -0
  590. data/lib/IceGrid/Session.rb +114 -0
  591. data/lib/IceGrid/UserAccountMapper.rb +101 -0
  592. data/lib/IcePatch2.rb +10 -0
  593. data/lib/IcePatch2/FileInfo.rb +75 -0
  594. data/lib/IcePatch2/FileServer.rb +141 -0
  595. data/lib/IceStorm.rb +11 -0
  596. data/lib/IceStorm/IceStorm.rb +463 -0
  597. data/lib/IceStorm/Metrics.rb +155 -0
  598. data/slice/Freeze/BackgroundSaveEvictor.ice +111 -0
  599. data/slice/Freeze/CatalogData.ice +49 -0
  600. data/slice/Freeze/Connection.ice +111 -0
  601. data/slice/Freeze/ConnectionF.ice +20 -0
  602. data/slice/Freeze/DB.ice +37 -0
  603. data/slice/Freeze/Evictor.ice +339 -0
  604. data/slice/Freeze/EvictorF.ice +22 -0
  605. data/slice/Freeze/EvictorStorage.ice +72 -0
  606. data/slice/Freeze/Exception.ice +100 -0
  607. data/slice/Freeze/Transaction.ice +57 -0
  608. data/slice/Freeze/TransactionalEvictor.ice +50 -0
  609. data/slice/Glacier2/Metrics.ice +77 -0
  610. data/slice/Glacier2/PermissionsVerifier.ice +105 -0
  611. data/slice/Glacier2/PermissionsVerifierF.ice +21 -0
  612. data/slice/Glacier2/Router.ice +178 -0
  613. data/slice/Glacier2/RouterF.ice +20 -0
  614. data/slice/Glacier2/SSLInfo.ice +50 -0
  615. data/slice/Glacier2/Session.ice +273 -0
  616. data/slice/Ice/BuiltinSequences.ice +48 -0
  617. data/slice/Ice/Communicator.ice +567 -0
  618. data/slice/Ice/CommunicatorF.ice +20 -0
  619. data/slice/Ice/Connection.ice +323 -0
  620. data/slice/Ice/ConnectionF.ice +22 -0
  621. data/slice/Ice/Current.ice +160 -0
  622. data/slice/Ice/Endpoint.ice +227 -0
  623. data/slice/Ice/EndpointF.ice +32 -0
  624. data/slice/Ice/EndpointTypes.ice +38 -0
  625. data/slice/Ice/FacetMap.ice +25 -0
  626. data/slice/Ice/Identity.ice +59 -0
  627. data/slice/Ice/ImplicitContext.ice +109 -0
  628. data/slice/Ice/ImplicitContextF.ice +20 -0
  629. data/slice/Ice/Instrumentation.ice +499 -0
  630. data/slice/Ice/InstrumentationF.ice +26 -0
  631. data/slice/Ice/LocalException.ice +1015 -0
  632. data/slice/Ice/Locator.ice +227 -0
  633. data/slice/Ice/LocatorF.ice +21 -0
  634. data/slice/Ice/Logger.ice +86 -0
  635. data/slice/Ice/LoggerF.ice +20 -0
  636. data/slice/Ice/Metrics.ice +422 -0
  637. data/slice/Ice/ObjectAdapter.ice +673 -0
  638. data/slice/Ice/ObjectAdapterF.ice +20 -0
  639. data/slice/Ice/ObjectFactory.ice +60 -0
  640. data/slice/Ice/ObjectFactoryF.ice +20 -0
  641. data/slice/Ice/Plugin.ice +117 -0
  642. data/slice/Ice/PluginF.ice +21 -0
  643. data/slice/Ice/Process.ice +54 -0
  644. data/slice/Ice/ProcessF.ice +20 -0
  645. data/slice/Ice/Properties.ice +228 -0
  646. data/slice/Ice/PropertiesAdmin.ice +75 -0
  647. data/slice/Ice/PropertiesF.ice +21 -0
  648. data/slice/Ice/RemoteLogger.ice +232 -0
  649. data/slice/Ice/Router.ice +83 -0
  650. data/slice/Ice/RouterF.ice +20 -0
  651. data/slice/Ice/ServantLocator.ice +117 -0
  652. data/slice/Ice/ServantLocatorF.ice +20 -0
  653. data/slice/Ice/SliceChecksumDict.ice +25 -0
  654. data/slice/Ice/Version.ice +39 -0
  655. data/slice/IceBox/IceBox.ice +194 -0
  656. data/slice/IceDiscovery/IceDiscovery.ice +32 -0
  657. data/slice/IceGrid/Admin.ice +1578 -0
  658. data/slice/IceGrid/Descriptor.ice +1079 -0
  659. data/slice/IceGrid/Discovery.ice +73 -0
  660. data/slice/IceGrid/Exception.ice +383 -0
  661. data/slice/IceGrid/FileParser.ice +61 -0
  662. data/slice/IceGrid/Locator.ice +56 -0
  663. data/slice/IceGrid/Observer.ice +394 -0
  664. data/slice/IceGrid/PluginFacade.ice +316 -0
  665. data/slice/IceGrid/Query.ice +130 -0
  666. data/slice/IceGrid/Registry.ice +138 -0
  667. data/slice/IceGrid/Session.ice +124 -0
  668. data/slice/IceGrid/UserAccountMapper.ice +58 -0
  669. data/slice/IcePatch2/FileInfo.ice +49 -0
  670. data/slice/IcePatch2/FileServer.ice +129 -0
  671. data/slice/IceSSL/ConnectionInfo.ice +34 -0
  672. data/slice/IceSSL/EndpointInfo.ice +41 -0
  673. data/slice/IceStorm/IceStorm.ice +405 -0
  674. data/slice/IceStorm/Metrics.ice +71 -0
  675. metadata +737 -0
@@ -0,0 +1,236 @@
1
+ // **********************************************************************
2
+ //
3
+ // Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
4
+ //
5
+ // This copy of Ice is licensed to you under the terms described in the
6
+ // ICE_LICENSE file included in this distribution.
7
+ //
8
+ // **********************************************************************
9
+
10
+ #ifndef ICE_CONNECTION_FACTORY_H
11
+ #define ICE_CONNECTION_FACTORY_H
12
+
13
+ #include <IceUtil/Mutex.h>
14
+ #include <IceUtil/Monitor.h>
15
+ #include <Ice/CommunicatorF.h>
16
+ #include <Ice/ConnectionFactoryF.h>
17
+ #include <Ice/ConnectionI.h>
18
+ #include <Ice/InstanceF.h>
19
+ #include <Ice/ObjectAdapterF.h>
20
+ #include <Ice/EndpointIF.h>
21
+ #include <Ice/Endpoint.h>
22
+ #include <Ice/ConnectorF.h>
23
+ #include <Ice/AcceptorF.h>
24
+ #include <Ice/TransceiverF.h>
25
+ #include <Ice/RouterInfoF.h>
26
+ #include <Ice/EventHandler.h>
27
+ #include <Ice/EndpointI.h>
28
+ #include <Ice/InstrumentationF.h>
29
+ #include <Ice/ACMF.h>
30
+
31
+ #include <list>
32
+ #include <set>
33
+
34
+ namespace Ice
35
+ {
36
+
37
+ class LocalException;
38
+ class ObjectAdapterI;
39
+ typedef IceUtil::Handle<ObjectAdapterI> ObjectAdapterIPtr;
40
+
41
+ }
42
+
43
+ namespace IceInternal
44
+ {
45
+
46
+ class OutgoingConnectionFactory : virtual public IceUtil::Shared, public IceUtil::Monitor<IceUtil::Mutex>
47
+ {
48
+ public:
49
+
50
+ class CreateConnectionCallback : virtual public IceUtil::Shared
51
+ {
52
+ public:
53
+
54
+ virtual void setConnection(const Ice::ConnectionIPtr&, bool) = 0;
55
+ virtual void setException(const Ice::LocalException&) = 0;
56
+ };
57
+ typedef IceUtil::Handle<CreateConnectionCallback> CreateConnectionCallbackPtr;
58
+
59
+ void destroy();
60
+
61
+ void updateConnectionObservers();
62
+
63
+ void waitUntilFinished();
64
+
65
+ void create(const std::vector<EndpointIPtr>&, bool, Ice::EndpointSelectionType,
66
+ const CreateConnectionCallbackPtr&);
67
+ void setRouterInfo(const RouterInfoPtr&);
68
+ void removeAdapter(const Ice::ObjectAdapterPtr&);
69
+ void flushAsyncBatchRequests(const CommunicatorFlushBatchPtr&);
70
+
71
+ private:
72
+
73
+ OutgoingConnectionFactory(const Ice::CommunicatorPtr&, const InstancePtr&);
74
+ virtual ~OutgoingConnectionFactory();
75
+ friend class Instance;
76
+
77
+ struct ConnectorInfo
78
+ {
79
+ ConnectorInfo(const ConnectorPtr& c, const EndpointIPtr& e) : connector(c), endpoint(e)
80
+ {
81
+ }
82
+
83
+ bool operator==(const ConnectorInfo& other) const;
84
+
85
+ ConnectorPtr connector;
86
+ EndpointIPtr endpoint;
87
+ };
88
+
89
+ class ConnectCallback : public Ice::ConnectionI::StartCallback, public IceInternal::EndpointI_connectors
90
+ {
91
+ public:
92
+
93
+ ConnectCallback(const InstancePtr&, const OutgoingConnectionFactoryPtr&, const std::vector<EndpointIPtr>&, bool,
94
+ const CreateConnectionCallbackPtr&, Ice::EndpointSelectionType);
95
+
96
+ virtual void connectionStartCompleted(const Ice::ConnectionIPtr&);
97
+ virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&);
98
+
99
+ virtual void connectors(const std::vector<ConnectorPtr>&);
100
+ virtual void exception(const Ice::LocalException&);
101
+
102
+ void getConnectors();
103
+ void nextEndpoint();
104
+
105
+ void getConnection();
106
+ void nextConnector();
107
+
108
+ void setConnection(const Ice::ConnectionIPtr&, bool);
109
+ void setException(const Ice::LocalException&);
110
+
111
+ bool hasConnector(const ConnectorInfo&);
112
+ bool removeConnectors(const std::vector<ConnectorInfo>&);
113
+ void removeFromPending();
114
+
115
+ bool operator<(const ConnectCallback&) const;
116
+
117
+ private:
118
+
119
+ const InstancePtr _instance;
120
+ const OutgoingConnectionFactoryPtr _factory;
121
+ const std::vector<EndpointIPtr> _endpoints;
122
+ const bool _hasMore;
123
+ const CreateConnectionCallbackPtr _callback;
124
+ const Ice::EndpointSelectionType _selType;
125
+ Ice::Instrumentation::ObserverPtr _observer;
126
+ std::vector<EndpointIPtr>::const_iterator _endpointsIter;
127
+ std::vector<ConnectorInfo> _connectors;
128
+ std::vector<ConnectorInfo>::const_iterator _iter;
129
+ };
130
+ typedef IceUtil::Handle<ConnectCallback> ConnectCallbackPtr;
131
+ friend class ConnectCallback;
132
+
133
+ std::vector<EndpointIPtr> applyOverrides(const std::vector<EndpointIPtr>&);
134
+ Ice::ConnectionIPtr findConnection(const std::vector<EndpointIPtr>&, bool&);
135
+ void incPendingConnectCount();
136
+ void decPendingConnectCount();
137
+ Ice::ConnectionIPtr getConnection(const std::vector<ConnectorInfo>&, const ConnectCallbackPtr&, bool&);
138
+ void finishGetConnection(const std::vector<ConnectorInfo>&, const ConnectorInfo&, const Ice::ConnectionIPtr&,
139
+ const ConnectCallbackPtr&);
140
+ void finishGetConnection(const std::vector<ConnectorInfo>&, const Ice::LocalException&, const ConnectCallbackPtr&);
141
+
142
+ bool addToPending(const ConnectCallbackPtr&, const std::vector<ConnectorInfo>&);
143
+ void removeFromPending(const ConnectCallbackPtr&, const std::vector<ConnectorInfo>&);
144
+
145
+ Ice::ConnectionIPtr findConnection(const std::vector<ConnectorInfo>&, bool&);
146
+ Ice::ConnectionIPtr createConnection(const TransceiverPtr&, const ConnectorInfo&);
147
+
148
+ void handleException(const Ice::LocalException&, bool);
149
+ void handleConnectionException(const Ice::LocalException&, bool);
150
+
151
+ Ice::CommunicatorPtr _communicator;
152
+ const InstancePtr _instance;
153
+ const FactoryACMMonitorPtr _monitor;
154
+ bool _destroyed;
155
+
156
+ std::multimap<ConnectorPtr, Ice::ConnectionIPtr> _connections;
157
+ std::map<ConnectorPtr, std::set<ConnectCallbackPtr> > _pending;
158
+
159
+ std::multimap<EndpointIPtr, Ice::ConnectionIPtr> _connectionsByEndpoint;
160
+ int _pendingConnectCount;
161
+ };
162
+
163
+ class IncomingConnectionFactory : public EventHandler,
164
+ public Ice::ConnectionI::StartCallback,
165
+ public IceUtil::Monitor<IceUtil::Mutex>
166
+
167
+ {
168
+ public:
169
+
170
+ void activate();
171
+ void hold();
172
+ void destroy();
173
+
174
+ void updateConnectionObservers();
175
+
176
+ void waitUntilHolding() const;
177
+ void waitUntilFinished();
178
+
179
+ EndpointIPtr endpoint() const;
180
+ std::list<Ice::ConnectionIPtr> connections() const;
181
+ void flushAsyncBatchRequests(const CommunicatorFlushBatchPtr&);
182
+
183
+ //
184
+ // Operations from EventHandler
185
+ //
186
+
187
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
188
+ virtual bool startAsync(SocketOperation);
189
+ virtual bool finishAsync(SocketOperation);
190
+ #endif
191
+
192
+ virtual void message(ThreadPoolCurrent&);
193
+ virtual void finished(ThreadPoolCurrent&, bool);
194
+ virtual std::string toString() const;
195
+ virtual NativeInfoPtr getNativeInfo();
196
+
197
+ virtual void connectionStartCompleted(const Ice::ConnectionIPtr&);
198
+ virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&);
199
+
200
+ private:
201
+
202
+ IncomingConnectionFactory(const InstancePtr&, const EndpointIPtr&, const Ice::ObjectAdapterIPtr&);
203
+ void initialize(const std::string&);
204
+ virtual ~IncomingConnectionFactory();
205
+ friend class Ice::ObjectAdapterI;
206
+
207
+ enum State
208
+ {
209
+ StateActive,
210
+ StateHolding,
211
+ StateClosed,
212
+ StateFinished
213
+ };
214
+
215
+ void setState(State);
216
+ void closeAcceptor(bool);
217
+
218
+ const InstancePtr _instance;
219
+ const FactoryACMMonitorPtr _monitor;
220
+
221
+ const AcceptorPtr _acceptor;
222
+ const TransceiverPtr _transceiver;
223
+ const EndpointIPtr _endpoint;
224
+
225
+ Ice::ObjectAdapterIPtr _adapter;
226
+
227
+ const bool _warn;
228
+
229
+ std::set<Ice::ConnectionIPtr> _connections;
230
+
231
+ State _state;
232
+ };
233
+
234
+ }
235
+
236
+ #endif
@@ -0,0 +1,3876 @@
1
+ // **********************************************************************
2
+ //
3
+ // Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
4
+ //
5
+ // This copy of Ice is licensed to you under the terms described in the
6
+ // ICE_LICENSE file included in this distribution.
7
+ //
8
+ // **********************************************************************
9
+
10
+ #include <IceUtil/DisableWarnings.h>
11
+ #include <Ice/ConnectionI.h>
12
+ #include <Ice/Instance.h>
13
+ #include <Ice/LoggerUtil.h>
14
+ #include <Ice/Properties.h>
15
+ #include <Ice/TraceUtil.h>
16
+ #include <Ice/TraceLevels.h>
17
+ #include <Ice/DefaultsAndOverrides.h>
18
+ #include <Ice/Transceiver.h>
19
+ #include <Ice/ThreadPool.h>
20
+ #include <Ice/ACM.h>
21
+ #include <Ice/ObjectAdapterI.h> // For getThreadPool() and getServantManager().
22
+ #include <Ice/EndpointI.h>
23
+ #include <Ice/Outgoing.h>
24
+ #include <Ice/OutgoingAsync.h>
25
+ #include <Ice/Incoming.h>
26
+ #include <Ice/LocalException.h>
27
+ #include <Ice/RequestHandler.h> // For RetryException
28
+ #include <Ice/ReferenceFactory.h> // For createProxy().
29
+ #include <Ice/ProxyFactory.h> // For createProxy().
30
+ #ifndef ICE_OS_WINRT
31
+ # include <bzlib.h>
32
+ #endif
33
+
34
+ using namespace std;
35
+ using namespace Ice;
36
+ using namespace Ice::Instrumentation;
37
+ using namespace IceInternal;
38
+
39
+ Ice::LocalObject* Ice::upCast(ConnectionI* p) { return p; }
40
+
41
+ namespace
42
+ {
43
+
44
+ const ::std::string __flushBatchRequests_name = "flushBatchRequests";
45
+
46
+
47
+ class TimeoutCallback : public IceUtil::TimerTask
48
+ {
49
+ public:
50
+
51
+ TimeoutCallback(Ice::ConnectionI* connection) : _connection(connection)
52
+ {
53
+ }
54
+
55
+ void
56
+ runTimerTask()
57
+ {
58
+ _connection->timedOut();
59
+ }
60
+
61
+ private:
62
+
63
+ Ice::ConnectionI* _connection;
64
+ };
65
+
66
+ class DispatchCall : public DispatchWorkItem
67
+ {
68
+ public:
69
+
70
+ DispatchCall(const ConnectionIPtr& connection, const ConnectionI::StartCallbackPtr& startCB,
71
+ const vector<ConnectionI::OutgoingMessage>& sentCBs, Byte compress, Int requestId,
72
+ Int invokeNum, const ServantManagerPtr& servantManager, const ObjectAdapterPtr& adapter,
73
+ const OutgoingAsyncPtr& outAsync, const ConnectionCallbackPtr& heartbeatCallback,
74
+ BasicStream& stream) :
75
+ DispatchWorkItem(connection),
76
+ _connection(connection),
77
+ _startCB(startCB),
78
+ _sentCBs(sentCBs),
79
+ _compress(compress),
80
+ _requestId(requestId),
81
+ _invokeNum(invokeNum),
82
+ _servantManager(servantManager),
83
+ _adapter(adapter),
84
+ _outAsync(outAsync),
85
+ _heartbeatCallback(heartbeatCallback),
86
+ _stream(stream.instance(), currentProtocolEncoding)
87
+ {
88
+ _stream.swap(stream);
89
+ }
90
+
91
+ virtual void
92
+ run()
93
+ {
94
+ _connection->dispatch(_startCB, _sentCBs, _compress, _requestId, _invokeNum, _servantManager, _adapter,
95
+ _outAsync, _heartbeatCallback, _stream);
96
+ }
97
+
98
+ private:
99
+
100
+ const ConnectionIPtr _connection;
101
+ const ConnectionI::StartCallbackPtr _startCB;
102
+ const vector<ConnectionI::OutgoingMessage> _sentCBs;
103
+ const Byte _compress;
104
+ const Int _requestId;
105
+ const Int _invokeNum;
106
+ const ServantManagerPtr _servantManager;
107
+ const ObjectAdapterPtr _adapter;
108
+ const OutgoingAsyncPtr _outAsync;
109
+ const ConnectionCallbackPtr _heartbeatCallback;
110
+ BasicStream _stream;
111
+ };
112
+
113
+ class FinishCall : public DispatchWorkItem
114
+ {
115
+ public:
116
+
117
+ FinishCall(const Ice::ConnectionIPtr& connection, bool close) :
118
+ DispatchWorkItem(connection), _connection(connection), _close(close)
119
+ {
120
+ }
121
+
122
+ virtual void
123
+ run()
124
+ {
125
+ _connection->finish(_close);
126
+ }
127
+
128
+ private:
129
+
130
+ const ConnectionIPtr _connection;
131
+ const bool _close;
132
+ };
133
+
134
+ ConnectionState connectionStateMap[] = {
135
+ ConnectionStateValidating, // StateNotInitialized
136
+ ConnectionStateValidating, // StateNotValidated
137
+ ConnectionStateActive, // StateActive
138
+ ConnectionStateHolding, // StateHolding
139
+ ConnectionStateClosing, // StateClosing
140
+ ConnectionStateClosing, // StateClosingPending
141
+ ConnectionStateClosed, // StateClosed
142
+ ConnectionStateClosed, // StateFinished
143
+ };
144
+
145
+ }
146
+
147
+ Ice::ConnectionI::Observer::Observer() : _readStreamPos(0), _writeStreamPos(0)
148
+ {
149
+ }
150
+
151
+ void
152
+ Ice::ConnectionI::Observer::startRead(const Buffer& buf)
153
+ {
154
+ if(_readStreamPos)
155
+ {
156
+ assert(!buf.b.empty());
157
+ _observer->receivedBytes(static_cast<int>(buf.i - _readStreamPos));
158
+ }
159
+ _readStreamPos = buf.b.empty() ? 0 : buf.i;
160
+ }
161
+
162
+ void
163
+ Ice::ConnectionI::Observer::finishRead(const Buffer& buf)
164
+ {
165
+ if(_readStreamPos == 0)
166
+ {
167
+ return;
168
+ }
169
+ assert(buf.i >= _readStreamPos);
170
+ _observer->receivedBytes(static_cast<int>(buf.i - _readStreamPos));
171
+ _readStreamPos = 0;
172
+ }
173
+
174
+ void
175
+ Ice::ConnectionI::Observer::startWrite(const Buffer& buf)
176
+ {
177
+ if(_writeStreamPos)
178
+ {
179
+ assert(!buf.b.empty());
180
+ _observer->sentBytes(static_cast<int>(buf.i - _writeStreamPos));
181
+ }
182
+ _writeStreamPos = buf.b.empty() ? 0 : buf.i;
183
+ }
184
+
185
+ void
186
+ Ice::ConnectionI::Observer::finishWrite(const Buffer& buf)
187
+ {
188
+ if(_writeStreamPos == 0)
189
+ {
190
+ return;
191
+ }
192
+ if(buf.i > _writeStreamPos)
193
+ {
194
+ _observer->sentBytes(static_cast<int>(buf.i - _writeStreamPos));
195
+ }
196
+ _writeStreamPos = 0;
197
+ }
198
+
199
+ void
200
+ Ice::ConnectionI::Observer::attach(const Ice::Instrumentation::ConnectionObserverPtr& observer)
201
+ {
202
+ ObserverHelperT<Ice::Instrumentation::ConnectionObserver>::attach(observer);
203
+ if(!observer)
204
+ {
205
+ _writeStreamPos = 0;
206
+ _readStreamPos = 0;
207
+ }
208
+ }
209
+
210
+
211
+ void
212
+ Ice::ConnectionI::OutgoingMessage::adopt(BasicStream* str)
213
+ {
214
+ if(adopted)
215
+ {
216
+ if(str)
217
+ {
218
+ delete stream;
219
+ stream = 0;
220
+ adopted = false;
221
+ }
222
+ else
223
+ {
224
+ return; // Stream is already adopted.
225
+ }
226
+ }
227
+ else if(!str)
228
+ {
229
+ if(out || outAsync)
230
+ {
231
+ return; // Adopting request stream is not necessary.
232
+ }
233
+ else
234
+ {
235
+ str = stream; // Adopt this stream
236
+ stream = 0;
237
+ }
238
+ }
239
+
240
+ assert(str);
241
+ stream = new BasicStream(str->instance(), currentProtocolEncoding);
242
+ stream->swap(*str);
243
+ adopted = true;
244
+ }
245
+
246
+ void
247
+ Ice::ConnectionI::OutgoingMessage::canceled(bool adoptStream)
248
+ {
249
+ assert((out || outAsync)); // Only requests can timeout.
250
+ out = 0;
251
+ outAsync = 0;
252
+ if(adoptStream)
253
+ {
254
+ adopt(0); // Adopt the request stream
255
+ }
256
+ else
257
+ {
258
+ assert(!adopted);
259
+ }
260
+ }
261
+
262
+ bool
263
+ Ice::ConnectionI::OutgoingMessage::sent()
264
+ {
265
+ if(adopted)
266
+ {
267
+ delete stream;
268
+ }
269
+ stream = 0;
270
+
271
+ if(out)
272
+ {
273
+ out->sent();
274
+ }
275
+ else if(outAsync)
276
+ {
277
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
278
+ invokeSent = outAsync->sent();
279
+ return invokeSent || receivedReply;
280
+ #else
281
+ return outAsync->sent();
282
+ #endif
283
+ }
284
+ return false;
285
+ }
286
+
287
+ void
288
+ Ice::ConnectionI::OutgoingMessage::completed(const Ice::LocalException& ex)
289
+ {
290
+ if(out)
291
+ {
292
+ out->completed(ex);
293
+ }
294
+ else if(outAsync)
295
+ {
296
+ if(outAsync->completed(ex))
297
+ {
298
+ outAsync->invokeCompleted();
299
+ }
300
+ }
301
+
302
+ if(adopted)
303
+ {
304
+ delete stream;
305
+ }
306
+ stream = 0;
307
+ }
308
+
309
+ void
310
+ Ice::ConnectionI::start(const StartCallbackPtr& callback)
311
+ {
312
+ try
313
+ {
314
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
315
+ if(_state >= StateClosed) // The connection might already be closed if the communicator was destroyed.
316
+ {
317
+ assert(_exception.get());
318
+ _exception->ice_throw();
319
+ }
320
+
321
+ if(!initialize() || !validate())
322
+ {
323
+ if(callback)
324
+ {
325
+ _startCallback = callback;
326
+ return;
327
+ }
328
+
329
+ //
330
+ // Wait for the connection to be validated.
331
+ //
332
+ while(_state <= StateNotValidated)
333
+ {
334
+ wait();
335
+ }
336
+
337
+ if(_state >= StateClosing)
338
+ {
339
+ assert(_exception.get());
340
+ _exception->ice_throw();
341
+ }
342
+ }
343
+
344
+ //
345
+ // We start out in holding state.
346
+ //
347
+ setState(StateHolding);
348
+ }
349
+ catch(const Ice::LocalException& ex)
350
+ {
351
+ exception(ex);
352
+ if(callback)
353
+ {
354
+ callback->connectionStartFailed(this, *_exception.get());
355
+ return;
356
+ }
357
+ else
358
+ {
359
+ waitUntilFinished();
360
+ throw;
361
+ }
362
+ }
363
+
364
+ if(callback)
365
+ {
366
+ callback->connectionStartCompleted(this);
367
+ }
368
+ }
369
+
370
+ void
371
+ Ice::ConnectionI::activate()
372
+ {
373
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
374
+ if(_state <= StateNotValidated)
375
+ {
376
+ return;
377
+ }
378
+ if(_acmLastActivity != IceUtil::Time())
379
+ {
380
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
381
+ }
382
+ setState(StateActive);
383
+ }
384
+
385
+ void
386
+ Ice::ConnectionI::hold()
387
+ {
388
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
389
+ if(_state <= StateNotValidated)
390
+ {
391
+ return;
392
+ }
393
+
394
+ setState(StateHolding);
395
+ }
396
+
397
+ void
398
+ Ice::ConnectionI::destroy(DestructionReason reason)
399
+ {
400
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
401
+
402
+ switch(reason)
403
+ {
404
+ case ObjectAdapterDeactivated:
405
+ {
406
+ setState(StateClosing, ObjectAdapterDeactivatedException(__FILE__, __LINE__));
407
+ break;
408
+ }
409
+
410
+ case CommunicatorDestroyed:
411
+ {
412
+ setState(StateClosing, CommunicatorDestroyedException(__FILE__, __LINE__));
413
+ break;
414
+ }
415
+ }
416
+ }
417
+
418
+ void
419
+ Ice::ConnectionI::close(bool force)
420
+ {
421
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
422
+
423
+ if(force)
424
+ {
425
+ setState(StateClosed, ForcedCloseConnectionException(__FILE__, __LINE__));
426
+ }
427
+ else
428
+ {
429
+ //
430
+ // If we do a graceful shutdown, then we wait until all
431
+ // outstanding requests have been completed. Otherwise, the
432
+ // CloseConnectionException will cause all outstanding
433
+ // requests to be retried, regardless of whether the server
434
+ // has processed them or not.
435
+ //
436
+ while(!_requests.empty() || !_asyncRequests.empty())
437
+ {
438
+ wait();
439
+ }
440
+
441
+ setState(StateClosing, CloseConnectionException(__FILE__, __LINE__));
442
+ }
443
+ }
444
+
445
+ bool
446
+ Ice::ConnectionI::isActiveOrHolding() const
447
+ {
448
+ //
449
+ // We can not use trylock here, otherwise the outgoing connection
450
+ // factory might return destroyed (closing or closed) connections,
451
+ // resulting in connection retry exhaustion.
452
+ //
453
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
454
+
455
+ return _state > StateNotValidated && _state < StateClosing;
456
+ }
457
+
458
+ bool
459
+ Ice::ConnectionI::isFinished() const
460
+ {
461
+ //
462
+ // We can use trylock here, because as long as there are still
463
+ // threads operating in this connection object, connection
464
+ // destruction is considered as not yet finished.
465
+ //
466
+ IceUtil::Monitor<IceUtil::Mutex>::TryLock sync(*this);
467
+
468
+ if(!sync.acquired())
469
+ {
470
+ return false;
471
+ }
472
+
473
+ if(_state != StateFinished || _dispatchCount != 0)
474
+ {
475
+ return false;
476
+ }
477
+
478
+ assert(_state == StateFinished);
479
+ return true;
480
+ }
481
+
482
+ void
483
+ Ice::ConnectionI::throwException() const
484
+ {
485
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
486
+
487
+ if(_exception.get())
488
+ {
489
+ assert(_state >= StateClosing);
490
+ _exception->ice_throw();
491
+ }
492
+ }
493
+
494
+ void
495
+ Ice::ConnectionI::waitUntilHolding() const
496
+ {
497
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
498
+
499
+ while(_state < StateHolding || _dispatchCount > 0)
500
+ {
501
+ wait();
502
+ }
503
+ }
504
+
505
+ void
506
+ Ice::ConnectionI::waitUntilFinished()
507
+ {
508
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
509
+
510
+ //
511
+ // We wait indefinitely until the connection is finished and all
512
+ // outstanding requests are completed. Otherwise we couldn't
513
+ // guarantee that there are no outstanding calls when deactivate()
514
+ // is called on the servant locators.
515
+ //
516
+ while(_state < StateFinished || _dispatchCount > 0)
517
+ {
518
+ wait();
519
+ }
520
+
521
+ assert(_state == StateFinished);
522
+
523
+ //
524
+ // Clear the OA. See bug 1673 for the details of why this is necessary.
525
+ //
526
+ _adapter = 0;
527
+ }
528
+
529
+ void
530
+ Ice::ConnectionI::updateObserver()
531
+ {
532
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
533
+ if(_state < StateNotValidated || _state > StateClosed)
534
+ {
535
+ return;
536
+ }
537
+
538
+ assert(_instance->initializationData().observer);
539
+ _observer.attach(_instance->initializationData().observer->getConnectionObserver(initConnectionInfo(),
540
+ _endpoint,
541
+ toConnectionState(_state),
542
+ _observer.get()));
543
+ }
544
+
545
+ void
546
+ Ice::ConnectionI::monitor(const IceUtil::Time& now, const ACMConfig& acm)
547
+ {
548
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
549
+ if(_state != StateActive)
550
+ {
551
+ return;
552
+ }
553
+ assert(acm.timeout != IceUtil::Time());
554
+
555
+ //
556
+ // We send a heartbeat if there was no activity in the last
557
+ // (timeout / 4) period. Sending a heartbeat sooner than really
558
+ // needed is safer to ensure that the receiver will receive in
559
+ // time the heartbeat. Sending the heartbeat if there was no
560
+ // activity in the last (timeout / 2) period isn't enough since
561
+ // monitor() is called only every (timeout / 2) period.
562
+ //
563
+ // Note that this doesn't imply that we are sending 4 heartbeats
564
+ // per timeout period because the monitor() method is sill only
565
+ // called every (timeout / 2) period.
566
+ //
567
+ if(acm.heartbeat == HeartbeatAlways ||
568
+ (acm.heartbeat != HeartbeatOff && _writeStream.b.empty() && now >= (_acmLastActivity + acm.timeout / 4)))
569
+ {
570
+ if(acm.heartbeat != HeartbeatOnInvocation || _dispatchCount > 0)
571
+ {
572
+ heartbeat();
573
+ }
574
+ }
575
+
576
+ if(static_cast<Int>(_readStream.b.size()) > headerSize || !_writeStream.b.empty())
577
+ {
578
+ //
579
+ // If writing or reading, nothing to do, the connection
580
+ // timeout will kick-in if writes or reads don't progress.
581
+ // This check is necessary because the actitivy timer is
582
+ // only set when a message is fully read/written.
583
+ //
584
+ return;
585
+ }
586
+
587
+ if(acm.close != CloseOff && now >= (_acmLastActivity + acm.timeout))
588
+ {
589
+ if(acm.close == CloseOnIdleForceful ||
590
+ (acm.close != CloseOnIdle && (!_requests.empty() || !_asyncRequests.empty())))
591
+ {
592
+ //
593
+ // Close the connection if we didn't receive a heartbeat in
594
+ // the last period.
595
+ //
596
+ setState(StateClosed, ConnectionTimeoutException(__FILE__, __LINE__));
597
+ }
598
+ else if(acm.close != CloseOnInvocation &&
599
+ _dispatchCount == 0 && _batchStream.b.empty() && _requests.empty() && _asyncRequests.empty())
600
+ {
601
+ //
602
+ // The connection is idle, close it.
603
+ //
604
+ setState(StateClosing, ConnectionTimeoutException(__FILE__, __LINE__));
605
+ }
606
+ }
607
+ }
608
+
609
+ bool
610
+ Ice::ConnectionI::sendRequest(Outgoing* out, bool compress, bool response)
611
+ {
612
+ BasicStream* os = out->os();
613
+
614
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
615
+ if(_exception.get())
616
+ {
617
+ //
618
+ // If the connection is closed before we even have a chance
619
+ // to send our request, we always try to send the request
620
+ // again.
621
+ //
622
+ throw RetryException(*_exception.get());
623
+ }
624
+
625
+ assert(_state > StateNotValidated);
626
+ assert(_state < StateClosing);
627
+
628
+ //
629
+ // Ensure the message isn't bigger than what we can send with the
630
+ // transport.
631
+ //
632
+ _transceiver->checkSendSize(*os);
633
+
634
+ Int requestId = 0;
635
+ if(response)
636
+ {
637
+ //
638
+ // Create a new unique request ID.
639
+ //
640
+ requestId = _nextRequestId++;
641
+ if(requestId <= 0)
642
+ {
643
+ _nextRequestId = 1;
644
+ requestId = _nextRequestId++;
645
+ }
646
+
647
+ //
648
+ // Fill in the request ID.
649
+ //
650
+ const Byte* p = reinterpret_cast<const Byte*>(&requestId);
651
+ #ifdef ICE_BIG_ENDIAN
652
+ reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize);
653
+ #else
654
+ copy(p, p + sizeof(Int), os->b.begin() + headerSize);
655
+ #endif
656
+ }
657
+
658
+ out->attachRemoteObserver(initConnectionInfo(), _endpoint, requestId);
659
+
660
+ //
661
+ // Send the message. If it can't be sent without blocking the message is added
662
+ // to _sendStreams and it will be sent by the selector thread.
663
+ //
664
+ bool sent = false;
665
+ try
666
+ {
667
+ OutgoingMessage message(out, os, compress, requestId);
668
+ sent = sendMessage(message) & AsyncStatusSent;
669
+ }
670
+ catch(const LocalException& ex)
671
+ {
672
+ setState(StateClosed, ex);
673
+ assert(_exception.get());
674
+ _exception->ice_throw();
675
+ }
676
+
677
+ if(response)
678
+ {
679
+ //
680
+ // Add to the requests map.
681
+ //
682
+ _requestsHint = _requests.insert(_requests.end(), pair<const Int, Outgoing*>(requestId, out));
683
+ }
684
+
685
+ return sent;
686
+ }
687
+
688
+ AsyncStatus
689
+ Ice::ConnectionI::sendAsyncRequest(const OutgoingAsyncPtr& out, bool compress, bool response)
690
+ {
691
+ BasicStream* os = out->getOs();
692
+
693
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
694
+ if(_exception.get())
695
+ {
696
+ //
697
+ // If the exception is closed before we even have a chance
698
+ // to send our request, we always try to send the request
699
+ // again.
700
+ //
701
+ throw RetryException(*_exception.get());
702
+ }
703
+
704
+ assert(_state > StateNotValidated);
705
+ assert(_state < StateClosing);
706
+
707
+ //
708
+ // Ensure the message isn't bigger than what we can send with the
709
+ // transport.
710
+ //
711
+ _transceiver->checkSendSize(*os);
712
+
713
+ //
714
+ // Notify the request that it's cancelable with this connection.
715
+ // This will throw if the request is canceled.
716
+ //
717
+ out->cancelable(this);
718
+
719
+ Int requestId = 0;
720
+ if(response)
721
+ {
722
+ //
723
+ // Create a new unique request ID.
724
+ //
725
+ requestId = _nextRequestId++;
726
+ if(requestId <= 0)
727
+ {
728
+ _nextRequestId = 1;
729
+ requestId = _nextRequestId++;
730
+ }
731
+
732
+ //
733
+ // Fill in the request ID.
734
+ //
735
+ const Byte* p = reinterpret_cast<const Byte*>(&requestId);
736
+ #ifdef ICE_BIG_ENDIAN
737
+ reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize);
738
+ #else
739
+ copy(p, p + sizeof(Int), os->b.begin() + headerSize);
740
+ #endif
741
+ }
742
+
743
+ out->attachRemoteObserver(initConnectionInfo(), _endpoint, requestId);
744
+
745
+ AsyncStatus status = AsyncStatusQueued;
746
+ try
747
+ {
748
+ OutgoingMessage message(out, os, compress, requestId);
749
+ status = sendMessage(message);
750
+ }
751
+ catch(const LocalException& ex)
752
+ {
753
+ setState(StateClosed, ex);
754
+ assert(_exception.get());
755
+ _exception->ice_throw();
756
+ }
757
+
758
+ if(response)
759
+ {
760
+ //
761
+ // Add to the async requests map.
762
+ //
763
+ _asyncRequestsHint = _asyncRequests.insert(_asyncRequests.end(),
764
+ pair<const Int, OutgoingAsyncPtr>(requestId, out));
765
+ }
766
+ return status;
767
+ }
768
+
769
+ void
770
+ Ice::ConnectionI::prepareBatchRequest(BasicStream* os)
771
+ {
772
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
773
+
774
+ //
775
+ // Wait if flushing is currently in progress.
776
+ //
777
+ while(_batchStreamInUse && !_exception.get())
778
+ {
779
+ wait();
780
+ }
781
+
782
+ if(_exception.get())
783
+ {
784
+ //
785
+ // If there were no batch requests queued when the connection failed, we can safely
786
+ // retry with a new connection. Otherwise, we must throw to notify the caller that
787
+ // some previous batch requests were not sent.
788
+ //
789
+ if(_batchStream.b.empty())
790
+ {
791
+ throw RetryException(*_exception.get());
792
+ }
793
+ else
794
+ {
795
+ _exception->ice_throw();
796
+ }
797
+ }
798
+
799
+ assert(_state > StateNotValidated);
800
+ assert(_state < StateClosing);
801
+
802
+ if(_batchStream.b.empty())
803
+ {
804
+ try
805
+ {
806
+ _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr));
807
+ }
808
+ catch(const LocalException& ex)
809
+ {
810
+ setState(StateClosed, ex);
811
+ ex.ice_throw();
812
+ }
813
+ }
814
+
815
+ _batchStreamInUse = true;
816
+ _batchMarker = _batchStream.b.size();
817
+ _batchStream.swap(*os);
818
+
819
+ //
820
+ // The batch stream now belongs to the caller, until
821
+ // finishBatchRequest() or abortBatchRequest() is called.
822
+ //
823
+ }
824
+
825
+ void
826
+ Ice::ConnectionI::finishBatchRequest(BasicStream* os, bool compress)
827
+ {
828
+ try
829
+ {
830
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
831
+
832
+ //
833
+ // Get the batch stream back.
834
+ //
835
+ _batchStream.swap(*os);
836
+
837
+ if(_exception.get())
838
+ {
839
+ return;
840
+ }
841
+
842
+ bool flush = false;
843
+ if(_batchAutoFlushSize > 0)
844
+ {
845
+ if(_batchStream.b.size() > _batchAutoFlushSize)
846
+ {
847
+ flush = true;
848
+ }
849
+
850
+ //
851
+ // Throw memory limit exception if the first message added causes us to
852
+ // go over limit. Otherwise put aside the marshalled message that caused
853
+ // limit to be exceeded and rollback stream to the marker.
854
+ //
855
+ try
856
+ {
857
+ _transceiver->checkSendSize(_batchStream);
858
+ }
859
+ catch(const Ice::Exception&)
860
+ {
861
+ if(_batchRequestNum > 0)
862
+ {
863
+ flush = true;
864
+ }
865
+ else
866
+ {
867
+ throw;
868
+ }
869
+ }
870
+ }
871
+
872
+ if(flush)
873
+ {
874
+ //
875
+ // Temporarily save the last request.
876
+ //
877
+ vector<Ice::Byte> lastRequest(_batchStream.b.begin() + _batchMarker, _batchStream.b.end());
878
+ _batchStream.b.resize(_batchMarker);
879
+
880
+ //
881
+ // Send the batch stream without the last request.
882
+ //
883
+ try
884
+ {
885
+ //
886
+ // Fill in the number of requests in the batch.
887
+ //
888
+ const Byte* p = reinterpret_cast<const Byte*>(&_batchRequestNum);
889
+ #ifdef ICE_BIG_ENDIAN
890
+ reverse_copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
891
+ #else
892
+ copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
893
+ #endif
894
+
895
+ OutgoingMessage message(&_batchStream, _batchRequestCompress);
896
+ sendMessage(message);
897
+ }
898
+ catch(const Ice::LocalException& ex)
899
+ {
900
+ setState(StateClosed, ex);
901
+ assert(_exception.get());
902
+ _exception->ice_throw();
903
+ }
904
+
905
+ //
906
+ // Reset the batch.
907
+ //
908
+ BasicStream dummy(_instance.get(), currentProtocolEncoding);
909
+ _batchStream.swap(dummy);
910
+ _batchRequestNum = 0;
911
+ _batchRequestCompress = false;
912
+ _batchMarker = 0;
913
+
914
+ //
915
+ // Start a new batch with the last message that caused us to go over the limit.
916
+ //
917
+ _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr));
918
+ _batchStream.writeBlob(&lastRequest[0], lastRequest.size());
919
+ }
920
+
921
+ //
922
+ // Increment the number of requests in the batch.
923
+ //
924
+ ++_batchRequestNum;
925
+
926
+ //
927
+ // We compress the whole batch if there is at least one compressed
928
+ // message.
929
+ //
930
+ if(compress)
931
+ {
932
+ _batchRequestCompress = true;
933
+ }
934
+
935
+ //
936
+ // Notify about the batch stream not being in use anymore.
937
+ //
938
+ assert(_batchStreamInUse);
939
+ _batchStreamInUse = false;
940
+ notifyAll();
941
+ }
942
+ catch(const Ice::LocalException&)
943
+ {
944
+ abortBatchRequest();
945
+ throw;
946
+ }
947
+ }
948
+
949
+ void
950
+ Ice::ConnectionI::abortBatchRequest()
951
+ {
952
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
953
+
954
+ BasicStream dummy(_instance.get(), currentProtocolEncoding);
955
+ _batchStream.swap(dummy);
956
+ _batchRequestNum = 0;
957
+ _batchRequestCompress = false;
958
+ _batchMarker = 0;
959
+
960
+ assert(_batchStreamInUse);
961
+ _batchStreamInUse = false;
962
+ notifyAll();
963
+ }
964
+
965
+ void
966
+ Ice::ConnectionI::flushBatchRequests()
967
+ {
968
+ FlushBatch out(this, _instance.get(), __flushBatchRequests_name);
969
+ out.invoke();
970
+ }
971
+
972
+ AsyncResultPtr
973
+ Ice::ConnectionI::begin_flushBatchRequests()
974
+ {
975
+ return __begin_flushBatchRequests(__dummyCallback, 0);
976
+ }
977
+
978
+ AsyncResultPtr
979
+ Ice::ConnectionI::begin_flushBatchRequests(const CallbackPtr& cb, const LocalObjectPtr& cookie)
980
+ {
981
+ return __begin_flushBatchRequests(cb, cookie);
982
+ }
983
+
984
+ AsyncResultPtr
985
+ Ice::ConnectionI::begin_flushBatchRequests(const Callback_Connection_flushBatchRequestsPtr& cb,
986
+ const LocalObjectPtr& cookie)
987
+ {
988
+ return __begin_flushBatchRequests(cb, cookie);
989
+ }
990
+
991
+ AsyncResultPtr
992
+ Ice::ConnectionI::begin_flushBatchRequests(const IceInternal::Function<void (const Exception&)>& exception,
993
+ const IceInternal::Function<void (bool)>& sent)
994
+ {
995
+ #ifdef ICE_CPP11
996
+ class Cpp11CB : public IceInternal::Cpp11FnCallbackNC
997
+ {
998
+ public:
999
+
1000
+ Cpp11CB(const IceInternal::Function<void (const Exception&)>& excb,
1001
+ const IceInternal::Function<void (bool)>& sentcb) :
1002
+ IceInternal::Cpp11FnCallbackNC(excb, sentcb)
1003
+ {
1004
+ CallbackBase::checkCallback(true, excb != nullptr);
1005
+ }
1006
+
1007
+ virtual void
1008
+ completed(const AsyncResultPtr& __result) const
1009
+ {
1010
+ ConnectionPtr __con = __result->getConnection();
1011
+ assert(__con);
1012
+ try
1013
+ {
1014
+ __con->end_flushBatchRequests(__result);
1015
+ assert(false);
1016
+ }
1017
+ catch(const Exception& ex)
1018
+ {
1019
+ IceInternal::Cpp11FnCallbackNC::exception(__result, ex);
1020
+ }
1021
+ }
1022
+ };
1023
+
1024
+ return __begin_flushBatchRequests(new Cpp11CB(exception, sent), 0);
1025
+ #else
1026
+ assert(false); // Ice not built with C++11 support.
1027
+ return 0;
1028
+ #endif
1029
+ }
1030
+
1031
+ AsyncResultPtr
1032
+ Ice::ConnectionI::__begin_flushBatchRequests(const CallbackBasePtr& cb, const LocalObjectPtr& cookie)
1033
+ {
1034
+ ConnectionFlushBatchPtr result = new ConnectionFlushBatch(this,
1035
+ _communicator,
1036
+ _instance,
1037
+ __flushBatchRequests_name,
1038
+ cb,
1039
+ cookie);
1040
+ result->invoke();
1041
+ return result;
1042
+ }
1043
+
1044
+ void
1045
+ Ice::ConnectionI::end_flushBatchRequests(const AsyncResultPtr& r)
1046
+ {
1047
+ AsyncResult::__check(r, this, __flushBatchRequests_name);
1048
+ r->__wait();
1049
+ }
1050
+
1051
+ bool
1052
+ Ice::ConnectionI::flushBatchRequests(OutgoingBase* out)
1053
+ {
1054
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1055
+ while(_batchStreamInUse && !_exception.get())
1056
+ {
1057
+ wait();
1058
+ }
1059
+
1060
+ if(_exception.get())
1061
+ {
1062
+ _exception->ice_throw();
1063
+ }
1064
+
1065
+ if(_batchRequestNum == 0)
1066
+ {
1067
+ out->sent();
1068
+ return true;
1069
+ }
1070
+
1071
+ //
1072
+ // Fill in the number of requests in the batch.
1073
+ //
1074
+ const Byte* p = reinterpret_cast<const Byte*>(&_batchRequestNum);
1075
+ #ifdef ICE_BIG_ENDIAN
1076
+ reverse_copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
1077
+ #else
1078
+ copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
1079
+ #endif
1080
+ _batchStream.swap(*out->os());
1081
+
1082
+ out->attachRemoteObserver(initConnectionInfo(), _endpoint, 0);
1083
+
1084
+ //
1085
+ // Send the batch stream.
1086
+ //
1087
+ bool sent = false;
1088
+ try
1089
+ {
1090
+ OutgoingMessage message(out, out->os(), _batchRequestCompress, 0);
1091
+ sent = sendMessage(message) & AsyncStatusSent;
1092
+ }
1093
+ catch(const Ice::LocalException& ex)
1094
+ {
1095
+ setState(StateClosed, ex);
1096
+ assert(_exception.get());
1097
+ _exception->ice_throw();
1098
+ }
1099
+
1100
+ //
1101
+ // Reset the batch stream.
1102
+ //
1103
+ BasicStream dummy(_instance.get(), Ice::currentProtocolEncoding);
1104
+ _batchStream.swap(dummy);
1105
+ _batchRequestNum = 0;
1106
+ _batchRequestCompress = false;
1107
+ _batchMarker = 0;
1108
+ return sent;
1109
+ }
1110
+
1111
+ AsyncStatus
1112
+ Ice::ConnectionI::flushAsyncBatchRequests(const OutgoingAsyncBasePtr& outAsync)
1113
+ {
1114
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1115
+ while(_batchStreamInUse && !_exception.get())
1116
+ {
1117
+ wait();
1118
+ }
1119
+
1120
+ if(_exception.get())
1121
+ {
1122
+ _exception->ice_throw();
1123
+ }
1124
+
1125
+ if(_batchRequestNum == 0)
1126
+ {
1127
+ AsyncStatus status = AsyncStatusSent;
1128
+ if(outAsync->sent())
1129
+ {
1130
+ status = static_cast<AsyncStatus>(status | AsyncStatusInvokeSentCallback);
1131
+ }
1132
+ return status;
1133
+ }
1134
+
1135
+ //
1136
+ // Notify the request that it's cancelable with this connection.
1137
+ // This will throw if the request is canceled.
1138
+ //
1139
+ outAsync->cancelable(this);
1140
+
1141
+ //
1142
+ // Fill in the number of requests in the batch.
1143
+ //
1144
+ const Byte* p = reinterpret_cast<const Byte*>(&_batchRequestNum);
1145
+ #ifdef ICE_BIG_ENDIAN
1146
+ reverse_copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
1147
+ #else
1148
+ copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize);
1149
+ #endif
1150
+ _batchStream.swap(*outAsync->getOs());
1151
+
1152
+ outAsync->attachRemoteObserver(initConnectionInfo(), _endpoint, 0);
1153
+
1154
+ //
1155
+ // Send the batch stream.
1156
+ //
1157
+ AsyncStatus status = AsyncStatusQueued;
1158
+ try
1159
+ {
1160
+ OutgoingMessage message(outAsync, outAsync->getOs(), _batchRequestCompress, 0);
1161
+ status = sendMessage(message);
1162
+ }
1163
+ catch(const Ice::LocalException& ex)
1164
+ {
1165
+ setState(StateClosed, ex);
1166
+ assert(_exception.get());
1167
+ _exception->ice_throw();
1168
+ }
1169
+
1170
+ //
1171
+ // Reset the batch stream.
1172
+ //
1173
+ BasicStream dummy(_instance.get(), Ice::currentProtocolEncoding);
1174
+ _batchStream.swap(dummy);
1175
+ _batchRequestNum = 0;
1176
+ _batchRequestCompress = false;
1177
+ _batchMarker = 0;
1178
+ return status;
1179
+ }
1180
+
1181
+ void
1182
+ Ice::ConnectionI::setCallback(const ConnectionCallbackPtr& callback)
1183
+ {
1184
+ {
1185
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1186
+ if(_state >= StateClosed)
1187
+ {
1188
+ if(callback)
1189
+ {
1190
+ class CallbackWorkItem : public DispatchWorkItem
1191
+ {
1192
+ public:
1193
+
1194
+ CallbackWorkItem(const ConnectionIPtr& connection, const ConnectionCallbackPtr& callback) :
1195
+ _connection(connection),
1196
+ _callback(callback)
1197
+ {
1198
+ }
1199
+
1200
+ virtual void run()
1201
+ {
1202
+ _connection->closeCallback(_callback);
1203
+ }
1204
+
1205
+ private:
1206
+
1207
+ const ConnectionIPtr _connection;
1208
+ const ConnectionCallbackPtr _callback;
1209
+ };
1210
+ _threadPool->dispatch(new CallbackWorkItem(this, callback));
1211
+ }
1212
+ }
1213
+ else
1214
+ {
1215
+ _callback = callback;
1216
+ }
1217
+ }
1218
+ }
1219
+
1220
+ void
1221
+ Ice::ConnectionI::closeCallback(const ConnectionCallbackPtr& callback)
1222
+ {
1223
+ try
1224
+ {
1225
+ callback->closed(this);
1226
+ }
1227
+ catch(const std::exception& ex)
1228
+ {
1229
+ Error out(_instance->initializationData().logger);
1230
+ out << "connection callback exception:\n" << ex << '\n' << _desc;
1231
+ }
1232
+ catch(...)
1233
+ {
1234
+ Error out(_instance->initializationData().logger);
1235
+ out << "connection callback exception:\nunknown c++ exception" << '\n' << _desc;
1236
+ }
1237
+ }
1238
+
1239
+ void
1240
+ Ice::ConnectionI::setACM(const IceUtil::Optional<int>& timeout,
1241
+ const IceUtil::Optional<Ice::ACMClose>& close,
1242
+ const IceUtil::Optional<Ice::ACMHeartbeat>& heartbeat)
1243
+ {
1244
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1245
+ if(!_monitor || _state >= StateClosed)
1246
+ {
1247
+ return;
1248
+ }
1249
+
1250
+ if(_state == StateActive)
1251
+ {
1252
+ _monitor->remove(this);
1253
+ }
1254
+ _monitor = _monitor->acm(timeout, close, heartbeat);
1255
+
1256
+ if(_monitor->getACM().timeout <= 0)
1257
+ {
1258
+ _acmLastActivity = IceUtil::Time(); // Disable the recording of last activity.
1259
+ }
1260
+ else if(_acmLastActivity == IceUtil::Time() && _state == StateActive)
1261
+ {
1262
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
1263
+ }
1264
+
1265
+ if(_state == StateActive)
1266
+ {
1267
+ _monitor->add(this);
1268
+ }
1269
+ }
1270
+
1271
+ ACM
1272
+ Ice::ConnectionI::getACM()
1273
+ {
1274
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1275
+ ACM acm;
1276
+ acm.timeout = 0;
1277
+ acm.close = CloseOff;
1278
+ acm.heartbeat = HeartbeatOff;
1279
+ return _monitor ? _monitor->getACM() : acm;
1280
+ }
1281
+
1282
+ void
1283
+ Ice::ConnectionI::requestCanceled(OutgoingBase* out, const Ice::LocalException& ex)
1284
+ {
1285
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1286
+ if(_state >= StateClosed)
1287
+ {
1288
+ return; // The request has already been or will be shortly notified of the failure.
1289
+ }
1290
+
1291
+ for(deque<OutgoingMessage>::iterator o = _sendStreams.begin(); o != _sendStreams.end(); ++o)
1292
+ {
1293
+ if(o->out == out)
1294
+ {
1295
+ if(o->requestId)
1296
+ {
1297
+ if(_requestsHint != _requests.end() && _requestsHint->second == dynamic_cast<Outgoing*>(out))
1298
+ {
1299
+ _requests.erase(_requestsHint);
1300
+ _requestsHint = _requests.end();
1301
+ }
1302
+ else
1303
+ {
1304
+ _requests.erase(o->requestId);
1305
+ }
1306
+ }
1307
+
1308
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1309
+ {
1310
+ setState(StateClosed, ex);
1311
+ }
1312
+ else
1313
+ {
1314
+ //
1315
+ // If the request is being sent, don't remove it from the send streams,
1316
+ // it will be removed once the sending is finished.
1317
+ //
1318
+ if(o == _sendStreams.begin())
1319
+ {
1320
+ o->canceled(true); // true = adopt the stream.
1321
+ }
1322
+ else
1323
+ {
1324
+ o->canceled(false);
1325
+ _sendStreams.erase(o);
1326
+ }
1327
+ out->completed(ex);
1328
+ }
1329
+ return;
1330
+ }
1331
+ }
1332
+
1333
+ Outgoing* o = dynamic_cast<Outgoing*>(out);
1334
+ if(o)
1335
+ {
1336
+ if(_requestsHint != _requests.end() && _requestsHint->second == o)
1337
+ {
1338
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1339
+ {
1340
+ setState(StateClosed, ex);
1341
+ }
1342
+ else
1343
+ {
1344
+ o->completed(ex);
1345
+ _requests.erase(_requestsHint);
1346
+ _requestsHint = _requests.end();
1347
+ }
1348
+ return;
1349
+ }
1350
+ else
1351
+ {
1352
+ for(map<Int, Outgoing*>::iterator p = _requests.begin(); p != _requests.end(); ++p)
1353
+ {
1354
+ if(p->second == o)
1355
+ {
1356
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1357
+ {
1358
+ setState(StateClosed, ex);
1359
+ }
1360
+ else
1361
+ {
1362
+ o->completed(ex);
1363
+ assert(p != _requestsHint);
1364
+ _requests.erase(p);
1365
+ }
1366
+ return; // We're done.
1367
+ }
1368
+ }
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ void
1374
+ Ice::ConnectionI::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, const LocalException& ex)
1375
+ {
1376
+ //
1377
+ // NOTE: This isn't called from a thread pool thread.
1378
+ //
1379
+
1380
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1381
+ if(_state >= StateClosed)
1382
+ {
1383
+ return; // The request has already been or will be shortly notified of the failure.
1384
+ }
1385
+
1386
+ for(deque<OutgoingMessage>::iterator o = _sendStreams.begin(); o != _sendStreams.end(); ++o)
1387
+ {
1388
+ if(o->outAsync.get() == outAsync.get())
1389
+ {
1390
+ if(o->requestId)
1391
+ {
1392
+ if(_asyncRequestsHint != _asyncRequests.end() &&
1393
+ _asyncRequestsHint->second == OutgoingAsyncPtr::dynamicCast(outAsync))
1394
+ {
1395
+ _asyncRequests.erase(_asyncRequestsHint);
1396
+ _asyncRequestsHint = _asyncRequests.end();
1397
+ }
1398
+ else
1399
+ {
1400
+ _asyncRequests.erase(o->requestId);
1401
+ }
1402
+ }
1403
+
1404
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1405
+ {
1406
+ setState(StateClosed, ex);
1407
+ }
1408
+ else
1409
+ {
1410
+ //
1411
+ // If the request is being sent, don't remove it from the send streams,
1412
+ // it will be removed once the sending is finished.
1413
+ //
1414
+ if(o == _sendStreams.begin())
1415
+ {
1416
+ o->canceled(true); // true = adopt the stream
1417
+ }
1418
+ else
1419
+ {
1420
+ o->canceled(false);
1421
+ _sendStreams.erase(o);
1422
+ }
1423
+ if(outAsync->completed(ex))
1424
+ {
1425
+ outAsync->invokeCompletedAsync();
1426
+ }
1427
+ }
1428
+ return;
1429
+ }
1430
+ }
1431
+
1432
+ OutgoingAsyncPtr o = OutgoingAsyncPtr::dynamicCast(outAsync);
1433
+ if(o)
1434
+ {
1435
+ if(_asyncRequestsHint != _asyncRequests.end())
1436
+ {
1437
+ if(_asyncRequestsHint->second == o)
1438
+ {
1439
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1440
+ {
1441
+ setState(StateClosed, ex);
1442
+ }
1443
+ else
1444
+ {
1445
+ _asyncRequests.erase(_asyncRequestsHint);
1446
+ _asyncRequestsHint = _asyncRequests.end();
1447
+ if(outAsync->completed(ex))
1448
+ {
1449
+ outAsync->invokeCompletedAsync();
1450
+ }
1451
+ }
1452
+ return;
1453
+ }
1454
+ }
1455
+
1456
+ for(map<Int, OutgoingAsyncPtr>::iterator p = _asyncRequests.begin(); p != _asyncRequests.end(); ++p)
1457
+ {
1458
+ if(p->second.get() == o.get())
1459
+ {
1460
+ if(dynamic_cast<const Ice::ConnectionTimeoutException*>(&ex))
1461
+ {
1462
+ setState(StateClosed, ex);
1463
+ }
1464
+ else
1465
+ {
1466
+ assert(p != _asyncRequestsHint);
1467
+ _asyncRequests.erase(p);
1468
+ if(outAsync->completed(ex))
1469
+ {
1470
+ outAsync->invokeCompletedAsync();
1471
+ }
1472
+ }
1473
+ return;
1474
+ }
1475
+ }
1476
+ }
1477
+ }
1478
+
1479
+ void
1480
+ Ice::ConnectionI::sendResponse(Int, BasicStream* os, Byte compressFlag, bool /*amd*/)
1481
+ {
1482
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1483
+ assert(_state > StateNotValidated);
1484
+
1485
+ try
1486
+ {
1487
+ if(--_dispatchCount == 0)
1488
+ {
1489
+ if(_state == StateFinished)
1490
+ {
1491
+ reap();
1492
+ }
1493
+ notifyAll();
1494
+ }
1495
+
1496
+ if(_state >= StateClosed)
1497
+ {
1498
+ assert(_exception.get());
1499
+ _exception->ice_throw();
1500
+ }
1501
+
1502
+ OutgoingMessage message(os, compressFlag > 0);
1503
+ sendMessage(message);
1504
+
1505
+ if(_state == StateClosing && _dispatchCount == 0)
1506
+ {
1507
+ initiateShutdown();
1508
+ }
1509
+
1510
+ return;
1511
+ }
1512
+ catch(const LocalException& ex)
1513
+ {
1514
+ setState(StateClosed, ex);
1515
+ }
1516
+ }
1517
+
1518
+ void
1519
+ Ice::ConnectionI::sendNoResponse()
1520
+ {
1521
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1522
+ assert(_state > StateNotValidated);
1523
+
1524
+ try
1525
+ {
1526
+ if(--_dispatchCount == 0)
1527
+ {
1528
+ if(_state == StateFinished)
1529
+ {
1530
+ reap();
1531
+ }
1532
+ notifyAll();
1533
+ }
1534
+
1535
+ if(_state >= StateClosed)
1536
+ {
1537
+ assert(_exception.get());
1538
+ _exception->ice_throw();
1539
+ }
1540
+
1541
+ if(_state == StateClosing && _dispatchCount == 0)
1542
+ {
1543
+ initiateShutdown();
1544
+ }
1545
+ }
1546
+ catch(const LocalException& ex)
1547
+ {
1548
+ setState(StateClosed, ex);
1549
+ }
1550
+ }
1551
+
1552
+ bool
1553
+ Ice::ConnectionI::systemException(Int, const SystemException&, bool /*amd*/)
1554
+ {
1555
+ return false; // System exceptions aren't marshalled.
1556
+ }
1557
+
1558
+ void
1559
+ Ice::ConnectionI::invokeException(Ice::Int, const LocalException& ex, int invokeNum, bool /*amd*/)
1560
+ {
1561
+ //
1562
+ // Fatal exception while invoking a request. Since sendResponse/sendNoResponse isn't
1563
+ // called in case of a fatal exception we decrement _dispatchCount here.
1564
+ //
1565
+
1566
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1567
+ setState(StateClosed, ex);
1568
+
1569
+ if(invokeNum > 0)
1570
+ {
1571
+ assert(_dispatchCount >= invokeNum);
1572
+ _dispatchCount -= invokeNum;
1573
+ if(_dispatchCount == 0)
1574
+ {
1575
+ if(_state == StateFinished)
1576
+ {
1577
+ reap();
1578
+ }
1579
+ notifyAll();
1580
+ }
1581
+ }
1582
+ }
1583
+
1584
+ EndpointIPtr
1585
+ Ice::ConnectionI::endpoint() const
1586
+ {
1587
+ return _endpoint; // No mutex protection necessary, _endpoint is immutable.
1588
+ }
1589
+
1590
+ ConnectorPtr
1591
+ Ice::ConnectionI::connector() const
1592
+ {
1593
+ return _connector; // No mutex protection necessary, _connector is immutable.
1594
+ }
1595
+
1596
+ void
1597
+ Ice::ConnectionI::setAdapter(const ObjectAdapterPtr& adapter)
1598
+ {
1599
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1600
+
1601
+ if(_state <= StateNotValidated || _state >= StateClosing)
1602
+ {
1603
+ return;
1604
+ }
1605
+
1606
+ _adapter = adapter;
1607
+
1608
+ if(_adapter)
1609
+ {
1610
+ _servantManager = dynamic_cast<ObjectAdapterI*>(_adapter.get())->getServantManager();
1611
+ if(!_servantManager)
1612
+ {
1613
+ _adapter = 0;
1614
+ }
1615
+ }
1616
+ else
1617
+ {
1618
+ _servantManager = 0;
1619
+ }
1620
+
1621
+ //
1622
+ // We never change the thread pool with which we were initially
1623
+ // registered, even if we add or remove an object adapter.
1624
+ //
1625
+ }
1626
+
1627
+ ObjectAdapterPtr
1628
+ Ice::ConnectionI::getAdapter() const
1629
+ {
1630
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1631
+ return _adapter;
1632
+ }
1633
+
1634
+ EndpointPtr
1635
+ Ice::ConnectionI::getEndpoint() const
1636
+ {
1637
+ return _endpoint; // No mutex protection necessary, _endpoint is immutable.
1638
+ }
1639
+
1640
+ ObjectPrx
1641
+ Ice::ConnectionI::createProxy(const Identity& ident) const
1642
+ {
1643
+ //
1644
+ // Create a reference and return a reverse proxy for this
1645
+ // reference.
1646
+ //
1647
+ ConnectionIPtr self = const_cast<ConnectionI*>(this);
1648
+ return _instance->proxyFactory()->referenceToProxy(_instance->referenceFactory()->create(ident, self));
1649
+ }
1650
+
1651
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
1652
+ bool
1653
+ Ice::ConnectionI::startAsync(SocketOperation operation)
1654
+ {
1655
+ if(_state >= StateClosed)
1656
+ {
1657
+ return false;
1658
+ }
1659
+
1660
+ try
1661
+ {
1662
+ if(operation & SocketOperationWrite)
1663
+ {
1664
+ if(_observer)
1665
+ {
1666
+ _observer.startWrite(_writeStream);
1667
+ }
1668
+
1669
+ if(_transceiver->startWrite(_writeStream) && !_sendStreams.empty())
1670
+ {
1671
+ // The whole message is written, assume it's sent now for at-most-once semantics.
1672
+ _sendStreams.front().isSent = true;
1673
+ }
1674
+ }
1675
+ else if(operation & SocketOperationRead)
1676
+ {
1677
+ if(!_hasMoreData)
1678
+ {
1679
+ if(_observer && !_readHeader)
1680
+ {
1681
+ _observer.startRead(_readStream);
1682
+ }
1683
+
1684
+ _transceiver->startRead(_readStream);
1685
+ }
1686
+ else
1687
+ {
1688
+ _transceiver->getNativeInfo()->completed(IceInternal::SocketOperationRead);
1689
+ }
1690
+ }
1691
+ }
1692
+ catch(const Ice::LocalException& ex)
1693
+ {
1694
+ setState(StateClosed, ex);
1695
+ return false;
1696
+ }
1697
+ return true;
1698
+ }
1699
+
1700
+ bool
1701
+ Ice::ConnectionI::finishAsync(SocketOperation operation)
1702
+ {
1703
+ try
1704
+ {
1705
+ if(operation & SocketOperationWrite)
1706
+ {
1707
+ Buffer::Container::iterator start = _writeStream.i;
1708
+ _transceiver->finishWrite(_writeStream);
1709
+ if(_instance->traceLevels()->network >= 3 && _writeStream.i != start)
1710
+ {
1711
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
1712
+ out << "sent " << (_writeStream.i - start);
1713
+ if(!_endpoint->datagram())
1714
+ {
1715
+ out << " of " << (_writeStream.b.end() - start);
1716
+ }
1717
+ out << " bytes via " << _endpoint->protocol() << "\n" << toString();
1718
+ }
1719
+
1720
+ if(_observer)
1721
+ {
1722
+ _observer.finishWrite(_writeStream);
1723
+ }
1724
+ }
1725
+ else if(operation & SocketOperationRead)
1726
+ {
1727
+ if(!_hasMoreData)
1728
+ {
1729
+ Buffer::Container::iterator start = _readStream.i;
1730
+ _transceiver->finishRead(_readStream, _hasMoreData);
1731
+ if(_instance->traceLevels()->network >= 3 && _readStream.i != start)
1732
+ {
1733
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
1734
+ out << "received ";
1735
+ if(_endpoint->datagram())
1736
+ {
1737
+ out << _readStream.b.size();
1738
+ }
1739
+ else
1740
+ {
1741
+ out << (_readStream.i - start) << " of " << (_readStream.b.end() - start);
1742
+ }
1743
+ out << " bytes via " << _endpoint->protocol() << "\n" << toString();
1744
+ }
1745
+
1746
+ if(_observer && !_readHeader)
1747
+ {
1748
+ _observer.finishRead(_readStream);
1749
+ }
1750
+ }
1751
+ }
1752
+ }
1753
+ catch(const Ice::LocalException& ex)
1754
+ {
1755
+ setState(StateClosed, ex);
1756
+ }
1757
+ return _state < StateClosed;
1758
+ }
1759
+ #endif
1760
+
1761
+ void
1762
+ Ice::ConnectionI::message(ThreadPoolCurrent& current)
1763
+ {
1764
+ StartCallbackPtr startCB;
1765
+ vector<OutgoingMessage> sentCBs;
1766
+ Byte compress = 0;
1767
+ Int requestId = 0;
1768
+ Int invokeNum = 0;
1769
+ ServantManagerPtr servantManager;
1770
+ ObjectAdapterPtr adapter;
1771
+ OutgoingAsyncPtr outAsync;
1772
+ ConnectionCallbackPtr heartbeatCallback;
1773
+ int dispatchCount = 0;
1774
+
1775
+ ThreadPoolMessage<ConnectionI> msg(current, *this);
1776
+
1777
+ {
1778
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
1779
+
1780
+ ThreadPoolMessage<ConnectionI>::IOScope io(msg);
1781
+ if(!io)
1782
+ {
1783
+ return;
1784
+ }
1785
+
1786
+ if(_state >= StateClosed)
1787
+ {
1788
+ return;
1789
+ }
1790
+
1791
+ SocketOperation readyOp = current.operation;
1792
+ try
1793
+ {
1794
+ unscheduleTimeout(current.operation);
1795
+
1796
+ SocketOperation writeOp = SocketOperationNone;
1797
+ SocketOperation readOp = SocketOperationNone;
1798
+ if(readyOp & SocketOperationWrite)
1799
+ {
1800
+ if(_observer)
1801
+ {
1802
+ _observer.startWrite(_writeStream);
1803
+ }
1804
+ writeOp = write(_writeStream);
1805
+ if(_observer && !(writeOp & SocketOperationWrite))
1806
+ {
1807
+ _observer.finishWrite(_writeStream);
1808
+ }
1809
+ }
1810
+
1811
+ while(readyOp & SocketOperationRead)
1812
+ {
1813
+ if(_observer && !_readHeader)
1814
+ {
1815
+ _observer.startRead(_readStream);
1816
+ }
1817
+
1818
+ readOp = read(_readStream);
1819
+ if(readOp & SocketOperationRead)
1820
+ {
1821
+ break;
1822
+ }
1823
+ if(_observer && !_readHeader)
1824
+ {
1825
+ assert(_readStream.i == _readStream.b.end());
1826
+ _observer.finishRead(_readStream);
1827
+ }
1828
+
1829
+ if(_readHeader) // Read header if necessary.
1830
+ {
1831
+ _readHeader = false;
1832
+
1833
+ if(_observer)
1834
+ {
1835
+ _observer->receivedBytes(static_cast<int>(headerSize));
1836
+ }
1837
+
1838
+ ptrdiff_t pos = _readStream.i - _readStream.b.begin();
1839
+ if(pos < headerSize)
1840
+ {
1841
+ //
1842
+ // This situation is possible for small UDP packets.
1843
+ //
1844
+ throw IllegalMessageSizeException(__FILE__, __LINE__);
1845
+ }
1846
+
1847
+ _readStream.i = _readStream.b.begin();
1848
+ const Byte* m;
1849
+ _readStream.readBlob(m, static_cast<Int>(sizeof(magic)));
1850
+ if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3])
1851
+ {
1852
+ BadMagicException ex(__FILE__, __LINE__);
1853
+ ex.badMagic = Ice::ByteSeq(&m[0], &m[0] + sizeof(magic));
1854
+ throw ex;
1855
+ }
1856
+ ProtocolVersion pv;
1857
+ _readStream.read(pv);
1858
+ checkSupportedProtocol(pv);
1859
+ EncodingVersion ev;
1860
+ _readStream.read(ev);
1861
+ checkSupportedProtocolEncoding(ev);
1862
+
1863
+ Byte messageType;
1864
+ _readStream.read(messageType);
1865
+ Byte compress;
1866
+ _readStream.read(compress);
1867
+ Int size;
1868
+ _readStream.read(size);
1869
+ if(size < headerSize)
1870
+ {
1871
+ throw IllegalMessageSizeException(__FILE__, __LINE__);
1872
+ }
1873
+ if(size > static_cast<Int>(_messageSizeMax))
1874
+ {
1875
+ Ex::throwMemoryLimitException(__FILE__, __LINE__, size, _messageSizeMax);
1876
+ }
1877
+ if(size > static_cast<Int>(_readStream.b.size()))
1878
+ {
1879
+ _readStream.b.resize(size);
1880
+ }
1881
+ _readStream.i = _readStream.b.begin() + pos;
1882
+ }
1883
+
1884
+ if(_readStream.i != _readStream.b.end())
1885
+ {
1886
+ if(_endpoint->datagram())
1887
+ {
1888
+ throw DatagramLimitException(__FILE__, __LINE__); // The message was truncated.
1889
+ }
1890
+ continue;
1891
+ }
1892
+ break;
1893
+ }
1894
+
1895
+ SocketOperation newOp = static_cast<SocketOperation>(readOp | writeOp);
1896
+ readyOp = static_cast<SocketOperation>(readyOp & ~newOp);
1897
+ assert(readyOp || newOp);
1898
+
1899
+ if(_state <= StateNotValidated)
1900
+ {
1901
+ if(newOp)
1902
+ {
1903
+ //
1904
+ // Wait for all the transceiver conditions to be
1905
+ // satisfied before continuing.
1906
+ //
1907
+ scheduleTimeout(newOp);
1908
+ _threadPool->update(this, current.operation, newOp);
1909
+ return;
1910
+ }
1911
+
1912
+ if(_state == StateNotInitialized && !initialize(current.operation))
1913
+ {
1914
+ return;
1915
+ }
1916
+
1917
+ if(_state <= StateNotValidated && !validate(current.operation))
1918
+ {
1919
+ return;
1920
+ }
1921
+
1922
+ _threadPool->unregister(this, current.operation);
1923
+
1924
+ //
1925
+ // We start out in holding state.
1926
+ //
1927
+ setState(StateHolding);
1928
+ if(_startCallback)
1929
+ {
1930
+ swap(_startCallback, startCB);
1931
+ if(startCB)
1932
+ {
1933
+ ++dispatchCount;
1934
+ }
1935
+ }
1936
+ }
1937
+ else
1938
+ {
1939
+ assert(_state <= StateClosingPending);
1940
+
1941
+ //
1942
+ // We parse messages first, if we receive a close
1943
+ // connection message we won't send more messages.
1944
+ //
1945
+ if(readyOp & SocketOperationRead)
1946
+ {
1947
+ newOp = static_cast<SocketOperation>(newOp | parseMessage(current.stream,
1948
+ invokeNum,
1949
+ requestId,
1950
+ compress,
1951
+ servantManager,
1952
+ adapter,
1953
+ outAsync,
1954
+ heartbeatCallback,
1955
+ dispatchCount));
1956
+ }
1957
+
1958
+ if(readyOp & SocketOperationWrite)
1959
+ {
1960
+ newOp = static_cast<SocketOperation>(newOp | sendNextMessage(sentCBs));
1961
+ if(!sentCBs.empty())
1962
+ {
1963
+ ++dispatchCount;
1964
+ }
1965
+ }
1966
+
1967
+ if(_state < StateClosed)
1968
+ {
1969
+ scheduleTimeout(newOp);
1970
+ _threadPool->update(this, current.operation, newOp);
1971
+ }
1972
+ }
1973
+
1974
+ if(_acmLastActivity != IceUtil::Time())
1975
+ {
1976
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
1977
+ }
1978
+
1979
+ if(dispatchCount == 0)
1980
+ {
1981
+ return; // Nothing to dispatch we're done!
1982
+ }
1983
+
1984
+ _dispatchCount += dispatchCount;
1985
+ io.completed();
1986
+ }
1987
+ catch(const DatagramLimitException&) // Expected.
1988
+ {
1989
+ if(_warnUdp)
1990
+ {
1991
+ Warning out(_instance->initializationData().logger);
1992
+ out << "maximum datagram size of " << _readStream.i - _readStream.b.begin() << " exceeded";
1993
+ }
1994
+ _readStream.resize(headerSize);
1995
+ _readStream.i = _readStream.b.begin();
1996
+ _readHeader = true;
1997
+ return;
1998
+ }
1999
+ catch(const SocketException& ex)
2000
+ {
2001
+ setState(StateClosed, ex);
2002
+ return;
2003
+ }
2004
+ catch(const LocalException& ex)
2005
+ {
2006
+ if(_endpoint->datagram())
2007
+ {
2008
+ if(_warn)
2009
+ {
2010
+ Warning out(_instance->initializationData().logger);
2011
+ out << "datagram connection exception:\n" << ex << '\n' << _desc;
2012
+ }
2013
+ _readStream.resize(headerSize);
2014
+ _readStream.i = _readStream.b.begin();
2015
+ _readHeader = true;
2016
+ }
2017
+ else
2018
+ {
2019
+ setState(StateClosed, ex);
2020
+ }
2021
+ return;
2022
+ }
2023
+ }
2024
+
2025
+ if(!_dispatcher) // Optimization, call dispatch() directly if there's no dispatcher.
2026
+ {
2027
+ dispatch(startCB, sentCBs, compress, requestId, invokeNum, servantManager, adapter, outAsync, heartbeatCallback,
2028
+ current.stream);
2029
+ }
2030
+ else
2031
+ {
2032
+ _threadPool->dispatchFromThisThread(new DispatchCall(this, startCB, sentCBs, compress, requestId, invokeNum,
2033
+ servantManager, adapter, outAsync, heartbeatCallback,
2034
+ current.stream));
2035
+ }
2036
+ }
2037
+
2038
+ void
2039
+ ConnectionI::dispatch(const StartCallbackPtr& startCB, const vector<OutgoingMessage>& sentCBs,
2040
+ Byte compress, Int requestId, Int invokeNum, const ServantManagerPtr& servantManager,
2041
+ const ObjectAdapterPtr& adapter, const OutgoingAsyncPtr& outAsync,
2042
+ const ConnectionCallbackPtr& heartbeatCallback, BasicStream& stream)
2043
+ {
2044
+ int dispatchedCount = 0;
2045
+
2046
+ //
2047
+ // Notify the factory that the connection establishment and
2048
+ // validation has completed.
2049
+ //
2050
+ if(startCB)
2051
+ {
2052
+ startCB->connectionStartCompleted(this);
2053
+ ++dispatchedCount;
2054
+ }
2055
+
2056
+ //
2057
+ // Notify AMI calls that the message was sent.
2058
+ //
2059
+ if(!sentCBs.empty())
2060
+ {
2061
+ for(vector<OutgoingMessage>::const_iterator p = sentCBs.begin(); p != sentCBs.end(); ++p)
2062
+ {
2063
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
2064
+ if(p->invokeSent)
2065
+ {
2066
+ p->outAsync->invokeSent();
2067
+ }
2068
+ if(p->receivedReply)
2069
+ {
2070
+ OutgoingAsyncPtr outAsync = OutgoingAsyncPtr::dynamicCast(p->outAsync);
2071
+ if(outAsync->completed())
2072
+ {
2073
+ outAsync->invokeCompleted();
2074
+ }
2075
+ }
2076
+ #else
2077
+ p->outAsync->invokeSent();
2078
+ #endif
2079
+ }
2080
+ ++dispatchedCount;
2081
+ }
2082
+
2083
+ //
2084
+ // Asynchronous replies must be handled outside the thread
2085
+ // synchronization, so that nested calls are possible.
2086
+ //
2087
+ if(outAsync)
2088
+ {
2089
+ outAsync->invokeCompleted();
2090
+ ++dispatchedCount;
2091
+ }
2092
+
2093
+ if(heartbeatCallback)
2094
+ {
2095
+ try
2096
+ {
2097
+ heartbeatCallback->heartbeat(this);
2098
+ }
2099
+ catch(const std::exception& ex)
2100
+ {
2101
+ Error out(_instance->initializationData().logger);
2102
+ out << "connection callback exception:\n" << ex << '\n' << _desc;
2103
+ }
2104
+ catch(...)
2105
+ {
2106
+ Error out(_instance->initializationData().logger);
2107
+ out << "connection callback exception:\nunknown c++ exception" << '\n' << _desc;
2108
+ }
2109
+ ++dispatchedCount;
2110
+ }
2111
+
2112
+ //
2113
+ // Method invocation (or multiple invocations for batch messages)
2114
+ // must be done outside the thread synchronization, so that nested
2115
+ // calls are possible.
2116
+ //
2117
+ if(invokeNum)
2118
+ {
2119
+ invokeAll(stream, invokeNum, requestId, compress, servantManager, adapter);
2120
+
2121
+ //
2122
+ // Don't increase count, the dispatch count is
2123
+ // decreased when the incoming reply is sent.
2124
+ //
2125
+ }
2126
+
2127
+ //
2128
+ // Decrease dispatch count.
2129
+ //
2130
+ if(dispatchedCount > 0)
2131
+ {
2132
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2133
+ _dispatchCount -= dispatchedCount;
2134
+ if(_dispatchCount == 0)
2135
+ {
2136
+ //
2137
+ // Only initiate shutdown if not already done. It might
2138
+ // have already been done if the sent callback or AMI
2139
+ // callback was dispatched when the connection was already
2140
+ // in the closing state.
2141
+ //
2142
+ if(_state == StateClosing)
2143
+ {
2144
+ try
2145
+ {
2146
+ initiateShutdown();
2147
+ }
2148
+ catch(const LocalException& ex)
2149
+ {
2150
+ setState(StateClosed, ex);
2151
+ }
2152
+ }
2153
+ else if(_state == StateFinished)
2154
+ {
2155
+ reap();
2156
+ }
2157
+ notifyAll();
2158
+ }
2159
+ }
2160
+ }
2161
+
2162
+ void
2163
+ Ice::ConnectionI::finished(ThreadPoolCurrent& current, bool close)
2164
+ {
2165
+ {
2166
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2167
+ assert(_state == StateClosed);
2168
+ unscheduleTimeout(static_cast<SocketOperation>(SocketOperationRead | SocketOperationWrite));
2169
+ }
2170
+
2171
+ //
2172
+ // If there are no callbacks to call, we don't call ioCompleted() since we're not going
2173
+ // to call code that will potentially block (this avoids promoting a new leader and
2174
+ // unecessary thread creation, especially if this is called on shutdown).
2175
+ //
2176
+ if(!_startCallback && _sendStreams.empty() && _asyncRequests.empty() && !_callback)
2177
+ {
2178
+ finish(close);
2179
+ return;
2180
+ }
2181
+
2182
+ current.ioCompleted();
2183
+ if(!_dispatcher) // Optimization, call finish() directly if there's no dispatcher.
2184
+ {
2185
+ finish(close);
2186
+ }
2187
+ else
2188
+ {
2189
+ _threadPool->dispatchFromThisThread(new FinishCall(this, close));
2190
+ }
2191
+ }
2192
+
2193
+ void
2194
+ Ice::ConnectionI::finish(bool close)
2195
+ {
2196
+ if(!_initialized)
2197
+ {
2198
+ if(_instance->traceLevels()->network >= 2)
2199
+ {
2200
+ string verb = _connector ? "establish" : "accept";
2201
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
2202
+ out << "failed to " << verb << " " << _endpoint->protocol() << " connection\n" << toString()
2203
+ << "\n" << *_exception.get();
2204
+ }
2205
+ }
2206
+ else
2207
+ {
2208
+ if(_instance->traceLevels()->network >= 1)
2209
+ {
2210
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
2211
+ out << "closed " << _endpoint->protocol() << " connection\n" << toString();
2212
+
2213
+ //
2214
+ // Trace the cause of unexpected connection closures
2215
+ //
2216
+ if(!(dynamic_cast<const CloseConnectionException*>(_exception.get()) ||
2217
+ dynamic_cast<const ForcedCloseConnectionException*>(_exception.get()) ||
2218
+ dynamic_cast<const ConnectionTimeoutException*>(_exception.get()) ||
2219
+ dynamic_cast<const CommunicatorDestroyedException*>(_exception.get()) ||
2220
+ dynamic_cast<const ObjectAdapterDeactivatedException*>(_exception.get())))
2221
+ {
2222
+ out << "\n" << *_exception.get();
2223
+ }
2224
+ }
2225
+ }
2226
+
2227
+ if(close)
2228
+ {
2229
+ _transceiver->close();
2230
+ }
2231
+
2232
+ if(_startCallback)
2233
+ {
2234
+ _startCallback->connectionStartFailed(this, *_exception.get());
2235
+ _startCallback = 0;
2236
+ }
2237
+
2238
+ if(!_sendStreams.empty())
2239
+ {
2240
+ if(!_writeStream.b.empty())
2241
+ {
2242
+ //
2243
+ // Return the stream to the outgoing call. This is important for
2244
+ // retriable AMI calls which are not marshalled again.
2245
+ //
2246
+ OutgoingMessage* message = &_sendStreams.front();
2247
+ _writeStream.swap(*message->stream);
2248
+
2249
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
2250
+ //
2251
+ // The current message might be sent but not yet removed from _sendStreams. If
2252
+ // the response has been received in the meantime, we remove the message from
2253
+ // _sendStreams to not call finished on a message which is already done.
2254
+ //
2255
+ if(message->isSent || message->receivedReply)
2256
+ {
2257
+ if(message->sent() && message->invokeSent)
2258
+ {
2259
+ message->outAsync->invokeSent();
2260
+ }
2261
+ if(message->receivedReply)
2262
+ {
2263
+ OutgoingAsyncPtr outAsync = OutgoingAsyncPtr::dynamicCast(message->outAsync);
2264
+ if(outAsync->completed())
2265
+ {
2266
+ outAsync->invokeCompleted();
2267
+ }
2268
+ }
2269
+ _sendStreams.pop_front();
2270
+ }
2271
+ #endif
2272
+ }
2273
+
2274
+ for(deque<OutgoingMessage>::iterator o = _sendStreams.begin(); o != _sendStreams.end(); ++o)
2275
+ {
2276
+ o->completed(*_exception.get());
2277
+ if(o->requestId) // Make sure finished isn't called twice.
2278
+ {
2279
+ if(o->out)
2280
+ {
2281
+ _requests.erase(o->requestId);
2282
+ }
2283
+ else
2284
+ {
2285
+ _asyncRequests.erase(o->requestId);
2286
+ }
2287
+ }
2288
+ }
2289
+ _sendStreams.clear(); // Must be cleared before _requests because of Outgoing* references in OutgoingMessage
2290
+ }
2291
+
2292
+ for(map<Int, Outgoing*>::const_iterator p = _requests.begin(); p != _requests.end(); ++p)
2293
+ {
2294
+ p->second->completed(*_exception.get());
2295
+ }
2296
+ _requests.clear();
2297
+
2298
+ for(map<Int, OutgoingAsyncPtr>::const_iterator q = _asyncRequests.begin(); q != _asyncRequests.end(); ++q)
2299
+ {
2300
+ if(q->second->completed(*_exception.get()))
2301
+ {
2302
+ q->second->invokeCompleted();
2303
+ }
2304
+ }
2305
+ _asyncRequests.clear();
2306
+
2307
+ if(_callback)
2308
+ {
2309
+ closeCallback(_callback);
2310
+ _callback = 0;
2311
+ }
2312
+
2313
+ //
2314
+ // This must be done last as this will cause waitUntilFinished() to return (and communicator
2315
+ // objects such as the timer might be destroyed too).
2316
+ //
2317
+ {
2318
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2319
+ setState(StateFinished);
2320
+
2321
+ if(_dispatchCount == 0)
2322
+ {
2323
+ reap();
2324
+ }
2325
+ }
2326
+ }
2327
+
2328
+ string
2329
+ Ice::ConnectionI::toString() const
2330
+ {
2331
+ return _desc; // No mutex lock, _desc is immutable.
2332
+ }
2333
+
2334
+ NativeInfoPtr
2335
+ Ice::ConnectionI::getNativeInfo()
2336
+ {
2337
+ return _transceiver->getNativeInfo();
2338
+ }
2339
+
2340
+ void
2341
+ Ice::ConnectionI::timedOut()
2342
+ {
2343
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2344
+ if(_state <= StateNotValidated)
2345
+ {
2346
+ setState(StateClosed, ConnectTimeoutException(__FILE__, __LINE__));
2347
+ }
2348
+ else if(_state < StateClosing)
2349
+ {
2350
+ setState(StateClosed, TimeoutException(__FILE__, __LINE__));
2351
+ }
2352
+ else if(_state < StateClosed)
2353
+ {
2354
+ setState(StateClosed, CloseTimeoutException(__FILE__, __LINE__));
2355
+ }
2356
+ }
2357
+
2358
+ string
2359
+ Ice::ConnectionI::type() const
2360
+ {
2361
+ return _type; // No mutex lock, _type is immutable.
2362
+ }
2363
+
2364
+ Ice::Int
2365
+ Ice::ConnectionI::timeout() const
2366
+ {
2367
+ return _endpoint->timeout(); // No mutex lock, _endpoint is immutable.
2368
+ }
2369
+
2370
+ ConnectionInfoPtr
2371
+ Ice::ConnectionI::getInfo() const
2372
+ {
2373
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2374
+ if(_state >= StateClosed)
2375
+ {
2376
+ _exception->ice_throw();
2377
+ }
2378
+ return initConnectionInfo();
2379
+ }
2380
+
2381
+ void
2382
+ Ice::ConnectionI::exception(const LocalException& ex)
2383
+ {
2384
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
2385
+ setState(StateClosed, ex);
2386
+ }
2387
+
2388
+ Ice::ConnectionI::ConnectionI(const CommunicatorPtr& communicator,
2389
+ const InstancePtr& instance,
2390
+ const ACMMonitorPtr& monitor,
2391
+ const TransceiverPtr& transceiver,
2392
+ const ConnectorPtr& connector,
2393
+ const EndpointIPtr& endpoint,
2394
+ const ObjectAdapterIPtr& adapter) :
2395
+ _communicator(communicator),
2396
+ _instance(instance),
2397
+ _monitor(monitor),
2398
+ _transceiver(transceiver),
2399
+ _desc(transceiver->toString()),
2400
+ _type(transceiver->protocol()),
2401
+ _connector(connector),
2402
+ _endpoint(endpoint),
2403
+ _adapter(adapter),
2404
+ _dispatcher(_instance->initializationData().dispatcher), // Cached for better performance.
2405
+ _logger(_instance->initializationData().logger), // Cached for better performance.
2406
+ _traceLevels(_instance->traceLevels()), // Cached for better performance.
2407
+ _timer(_instance->timer()), // Cached for better performance.
2408
+ _writeTimeout(new TimeoutCallback(this)),
2409
+ _writeTimeoutScheduled(false),
2410
+ _readTimeout(new TimeoutCallback(this)),
2411
+ _readTimeoutScheduled(false),
2412
+ _warn(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Connections") > 0),
2413
+ _warnUdp(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Datagrams") > 0),
2414
+ _compressionLevel(1),
2415
+ _nextRequestId(1),
2416
+ _requestsHint(_requests.end()),
2417
+ _asyncRequestsHint(_asyncRequests.end()),
2418
+ _messageSizeMax(adapter ? adapter->messageSizeMax() : _instance->messageSizeMax()),
2419
+ _batchAutoFlushSize(_instance->batchAutoFlushSize()),
2420
+ _batchStream(_instance.get(), Ice::currentProtocolEncoding),
2421
+ _batchStreamInUse(false),
2422
+ _batchRequestNum(0),
2423
+ _batchRequestCompress(false),
2424
+ _batchMarker(0),
2425
+ _readStream(_instance.get(), Ice::currentProtocolEncoding),
2426
+ _readHeader(false),
2427
+ _writeStream(_instance.get(), Ice::currentProtocolEncoding),
2428
+ _dispatchCount(0),
2429
+ _state(StateNotInitialized),
2430
+ _shutdownInitiated(false),
2431
+ _initialized(false),
2432
+ _validated(false)
2433
+ {
2434
+ const Ice::PropertiesPtr& properties = _instance->initializationData().properties;
2435
+
2436
+ int& compressionLevel = const_cast<int&>(_compressionLevel);
2437
+ compressionLevel = properties->getPropertyAsIntWithDefault("Ice.Compression.Level", 1);
2438
+ if(compressionLevel < 1)
2439
+ {
2440
+ compressionLevel = 1;
2441
+ }
2442
+ else if(compressionLevel > 9)
2443
+ {
2444
+ compressionLevel = 9;
2445
+ }
2446
+
2447
+ if(adapter)
2448
+ {
2449
+ _servantManager = adapter->getServantManager();
2450
+ }
2451
+
2452
+ if(_monitor && _monitor->getACM().timeout > 0)
2453
+ {
2454
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
2455
+ }
2456
+
2457
+ __setNoDelete(true);
2458
+ try
2459
+ {
2460
+ if(adapter)
2461
+ {
2462
+ const_cast<ThreadPoolPtr&>(_threadPool) = adapter->getThreadPool();
2463
+ }
2464
+ else
2465
+ {
2466
+ const_cast<ThreadPoolPtr&>(_threadPool) = _instance->clientThreadPool();
2467
+ }
2468
+ _threadPool->initialize(this);
2469
+ }
2470
+ catch(const IceUtil::Exception&)
2471
+ {
2472
+ __setNoDelete(false);
2473
+ throw;
2474
+ }
2475
+ __setNoDelete(false);
2476
+ }
2477
+
2478
+ Ice::ConnectionI::~ConnectionI()
2479
+ {
2480
+ assert(!_startCallback);
2481
+ assert(!_callback);
2482
+ assert(_state == StateFinished);
2483
+ assert(_dispatchCount == 0);
2484
+ assert(_sendStreams.empty());
2485
+ assert(_requests.empty());
2486
+ assert(_asyncRequests.empty());
2487
+ }
2488
+
2489
+ void
2490
+ Ice::ConnectionI::setState(State state, const LocalException& ex)
2491
+ {
2492
+ //
2493
+ // If setState() is called with an exception, then only closed and
2494
+ // closing states are permissible.
2495
+ //
2496
+ assert(state >= StateClosing);
2497
+
2498
+ if(_state == state) // Don't switch twice.
2499
+ {
2500
+ return;
2501
+ }
2502
+
2503
+ if(!_exception.get())
2504
+ {
2505
+ //
2506
+ // If we are in closed state, an exception must be set.
2507
+ //
2508
+ assert(_state != StateClosed);
2509
+
2510
+ _exception.reset(ex.ice_clone());
2511
+
2512
+ //
2513
+ // We don't warn if we are not validated.
2514
+ //
2515
+ if(_warn && _validated)
2516
+ {
2517
+ //
2518
+ // Don't warn about certain expected exceptions.
2519
+ //
2520
+ if(!(dynamic_cast<const CloseConnectionException*>(_exception.get()) ||
2521
+ dynamic_cast<const ForcedCloseConnectionException*>(_exception.get()) ||
2522
+ dynamic_cast<const ConnectionTimeoutException*>(_exception.get()) ||
2523
+ dynamic_cast<const CommunicatorDestroyedException*>(_exception.get()) ||
2524
+ dynamic_cast<const ObjectAdapterDeactivatedException*>(_exception.get()) ||
2525
+ (dynamic_cast<const ConnectionLostException*>(_exception.get()) && _state >= StateClosing)))
2526
+ {
2527
+ Warning out(_logger);
2528
+ out << "connection exception:\n" << *_exception.get() << '\n' << _desc;
2529
+ }
2530
+ }
2531
+ }
2532
+
2533
+ //
2534
+ // We must set the new state before we notify requests of any
2535
+ // exceptions. Otherwise new requests may retry on a connection
2536
+ // that is not yet marked as closed or closing.
2537
+ //
2538
+ setState(state);
2539
+ }
2540
+
2541
+ void
2542
+ Ice::ConnectionI::setState(State state)
2543
+ {
2544
+ //
2545
+ // We don't want to send close connection messages if the endpoint
2546
+ // only supports oneway transmission from client to server.
2547
+ //
2548
+ if(_endpoint->datagram() && state == StateClosing)
2549
+ {
2550
+ state = StateClosed;
2551
+ }
2552
+
2553
+ //
2554
+ // Skip graceful shutdown if we are destroyed before validation.
2555
+ //
2556
+ if(_state <= StateNotValidated && state == StateClosing)
2557
+ {
2558
+ state = StateClosed;
2559
+ }
2560
+
2561
+ if(_state == state) // Don't switch twice.
2562
+ {
2563
+ return;
2564
+ }
2565
+
2566
+ try
2567
+ {
2568
+ switch(state)
2569
+ {
2570
+ case StateNotInitialized:
2571
+ {
2572
+ assert(false);
2573
+ break;
2574
+ }
2575
+
2576
+ case StateNotValidated:
2577
+ {
2578
+ if(_state != StateNotInitialized)
2579
+ {
2580
+ assert(_state == StateClosed);
2581
+ return;
2582
+ }
2583
+ break;
2584
+ }
2585
+
2586
+ case StateActive:
2587
+ {
2588
+ //
2589
+ // Can only switch from holding or not validated to
2590
+ // active.
2591
+ //
2592
+ if(_state != StateHolding && _state != StateNotValidated)
2593
+ {
2594
+ return;
2595
+ }
2596
+ _threadPool->_register(this, SocketOperationRead);
2597
+ break;
2598
+ }
2599
+
2600
+ case StateHolding:
2601
+ {
2602
+ //
2603
+ // Can only switch from active or not validated to
2604
+ // holding.
2605
+ //
2606
+ if(_state != StateActive && _state != StateNotValidated)
2607
+ {
2608
+ return;
2609
+ }
2610
+ if(_state == StateActive)
2611
+ {
2612
+ _threadPool->unregister(this, SocketOperationRead);
2613
+ }
2614
+ break;
2615
+ }
2616
+
2617
+ case StateClosing:
2618
+ case StateClosingPending:
2619
+ {
2620
+ //
2621
+ // Can't change back from closing pending.
2622
+ //
2623
+ if(_state >= StateClosingPending)
2624
+ {
2625
+ return;
2626
+ }
2627
+ break;
2628
+ }
2629
+
2630
+ case StateClosed:
2631
+ {
2632
+ if(_state == StateFinished)
2633
+ {
2634
+ return;
2635
+ }
2636
+
2637
+ //
2638
+ // Don't need to close now for connections so only close the transceiver
2639
+ // if the selector request it.
2640
+ //
2641
+ if(_threadPool->finish(this, false))
2642
+ {
2643
+ _transceiver->close();
2644
+ }
2645
+ break;
2646
+ }
2647
+
2648
+ case StateFinished:
2649
+ {
2650
+ assert(_state == StateClosed);
2651
+ _communicator = 0;
2652
+ break;
2653
+ }
2654
+ }
2655
+ }
2656
+ catch(const Ice::LocalException& ex)
2657
+ {
2658
+ Error out(_logger);
2659
+ out << "unexpected connection exception:\n" << ex << '\n' << _desc;
2660
+ }
2661
+
2662
+ //
2663
+ // We only register with the connection monitor if our new state
2664
+ // is StateActive. Otherwise we unregister with the connection
2665
+ // monitor, but only if we were registered before, i.e., if our
2666
+ // old state was StateActive.
2667
+ //
2668
+ if(_monitor)
2669
+ {
2670
+ if(state == StateActive)
2671
+ {
2672
+ if(_acmLastActivity != IceUtil::Time())
2673
+ {
2674
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
2675
+ }
2676
+ _monitor->add(this);
2677
+ }
2678
+ else if(_state == StateActive)
2679
+ {
2680
+ _monitor->remove(this);
2681
+ }
2682
+ }
2683
+
2684
+ if(_instance->initializationData().observer)
2685
+ {
2686
+ ConnectionState oldState = toConnectionState(_state);
2687
+ ConnectionState newState = toConnectionState(state);
2688
+ if(oldState != newState)
2689
+ {
2690
+ _observer.attach(_instance->initializationData().observer->getConnectionObserver(initConnectionInfo(),
2691
+ _endpoint,
2692
+ newState,
2693
+ _observer.get()));
2694
+ }
2695
+ if(_observer && state == StateClosed && _exception.get())
2696
+ {
2697
+ if(!(dynamic_cast<const CloseConnectionException*>(_exception.get()) ||
2698
+ dynamic_cast<const ForcedCloseConnectionException*>(_exception.get()) ||
2699
+ dynamic_cast<const ConnectionTimeoutException*>(_exception.get()) ||
2700
+ dynamic_cast<const CommunicatorDestroyedException*>(_exception.get()) ||
2701
+ dynamic_cast<const ObjectAdapterDeactivatedException*>(_exception.get()) ||
2702
+ (dynamic_cast<const ConnectionLostException*>(_exception.get()) && _state >= StateClosing)))
2703
+ {
2704
+ _observer->failed(_exception->ice_name());
2705
+ }
2706
+ }
2707
+ }
2708
+ _state = state;
2709
+
2710
+ notifyAll();
2711
+
2712
+ if(_state == StateClosing && _dispatchCount == 0)
2713
+ {
2714
+ try
2715
+ {
2716
+ initiateShutdown();
2717
+ }
2718
+ catch(const LocalException& ex)
2719
+ {
2720
+ setState(StateClosed, ex);
2721
+ }
2722
+ }
2723
+ }
2724
+
2725
+ void
2726
+ Ice::ConnectionI::initiateShutdown()
2727
+ {
2728
+ assert(_state == StateClosing);
2729
+ assert(_dispatchCount == 0);
2730
+
2731
+ if(_shutdownInitiated)
2732
+ {
2733
+ return;
2734
+ }
2735
+ _shutdownInitiated = true;
2736
+
2737
+ if(!_endpoint->datagram())
2738
+ {
2739
+ //
2740
+ // Before we shut down, we send a close connection message.
2741
+ //
2742
+ BasicStream os(_instance.get(), Ice::currentProtocolEncoding);
2743
+ os.write(magic[0]);
2744
+ os.write(magic[1]);
2745
+ os.write(magic[2]);
2746
+ os.write(magic[3]);
2747
+ os.write(currentProtocol);
2748
+ os.write(currentProtocolEncoding);
2749
+ os.write(closeConnectionMsg);
2750
+ os.write(static_cast<Byte>(1)); // compression status: compression supported but not used.
2751
+ os.write(headerSize); // Message size.
2752
+
2753
+ OutgoingMessage message(&os, false);
2754
+ if(sendMessage(message) & AsyncStatusSent)
2755
+ {
2756
+ setState(StateClosingPending);
2757
+
2758
+ //
2759
+ // Notify the the transceiver of the graceful connection closure.
2760
+ //
2761
+ SocketOperation op = _transceiver->closing(true, *_exception.get());
2762
+ if(op)
2763
+ {
2764
+ scheduleTimeout(op);
2765
+ _threadPool->_register(this, op);
2766
+ }
2767
+ }
2768
+ }
2769
+ }
2770
+
2771
+ void
2772
+ Ice::ConnectionI::heartbeat()
2773
+ {
2774
+ assert(_state == StateActive);
2775
+
2776
+ if(!_endpoint->datagram())
2777
+ {
2778
+ BasicStream os(_instance.get(), Ice::currentProtocolEncoding);
2779
+ os.write(magic[0]);
2780
+ os.write(magic[1]);
2781
+ os.write(magic[2]);
2782
+ os.write(magic[3]);
2783
+ os.write(currentProtocol);
2784
+ os.write(currentProtocolEncoding);
2785
+ os.write(validateConnectionMsg);
2786
+ os.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection).
2787
+ os.write(headerSize); // Message size.
2788
+ os.i = os.b.begin();
2789
+ try
2790
+ {
2791
+ OutgoingMessage message(&os, false);
2792
+ sendMessage(message);
2793
+ }
2794
+ catch(const LocalException& ex)
2795
+ {
2796
+ setState(StateClosed, ex);
2797
+ assert(_exception.get());
2798
+ }
2799
+ }
2800
+ }
2801
+
2802
+ bool
2803
+ Ice::ConnectionI::initialize(SocketOperation operation)
2804
+ {
2805
+ SocketOperation s = _transceiver->initialize(_readStream, _writeStream, _hasMoreData);
2806
+ if(s != SocketOperationNone)
2807
+ {
2808
+ scheduleTimeout(s);
2809
+ _threadPool->update(this, operation, s);
2810
+ return false;
2811
+ }
2812
+
2813
+ //
2814
+ // Update the connection description once the transceiver is initialized.
2815
+ //
2816
+ const_cast<string&>(_desc) = _transceiver->toString();
2817
+ _initialized = true;
2818
+ setState(StateNotValidated);
2819
+ return true;
2820
+ }
2821
+
2822
+ bool
2823
+ Ice::ConnectionI::validate(SocketOperation operation)
2824
+ {
2825
+ if(!_endpoint->datagram()) // Datagram connections are always implicitly validated.
2826
+ {
2827
+ if(_adapter) // The server side has the active role for connection validation.
2828
+ {
2829
+ if(_writeStream.b.empty())
2830
+ {
2831
+ _writeStream.write(magic[0]);
2832
+ _writeStream.write(magic[1]);
2833
+ _writeStream.write(magic[2]);
2834
+ _writeStream.write(magic[3]);
2835
+ _writeStream.write(currentProtocol);
2836
+ _writeStream.write(currentProtocolEncoding);
2837
+ _writeStream.write(validateConnectionMsg);
2838
+ _writeStream.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection).
2839
+ _writeStream.write(headerSize); // Message size.
2840
+ _writeStream.i = _writeStream.b.begin();
2841
+ traceSend(_writeStream, _logger, _traceLevels);
2842
+ }
2843
+
2844
+ if(_observer)
2845
+ {
2846
+ _observer.startWrite(_writeStream);
2847
+ }
2848
+
2849
+ if(_writeStream.i != _writeStream.b.end())
2850
+ {
2851
+ SocketOperation op = write(_writeStream);
2852
+ if(op)
2853
+ {
2854
+ scheduleTimeout(op);
2855
+ _threadPool->update(this, operation, op);
2856
+ return false;
2857
+ }
2858
+ }
2859
+
2860
+ if(_observer)
2861
+ {
2862
+ _observer.finishWrite(_writeStream);
2863
+ }
2864
+ }
2865
+ else // The client side has the passive role for connection validation.
2866
+ {
2867
+ if(_readStream.b.empty())
2868
+ {
2869
+ _readStream.b.resize(headerSize);
2870
+ _readStream.i = _readStream.b.begin();
2871
+ }
2872
+
2873
+ if(_observer)
2874
+ {
2875
+ _observer.startRead(_readStream);
2876
+ }
2877
+
2878
+ if(_readStream.i != _readStream.b.end())
2879
+ {
2880
+ SocketOperation op = read(_readStream);
2881
+ if(op)
2882
+ {
2883
+ scheduleTimeout(op);
2884
+ _threadPool->update(this, operation, op);
2885
+ return false;
2886
+ }
2887
+ }
2888
+
2889
+ if(_observer)
2890
+ {
2891
+ _observer.finishRead(_readStream);
2892
+ }
2893
+
2894
+ assert(_readStream.i == _readStream.b.end());
2895
+ _readStream.i = _readStream.b.begin();
2896
+ Byte m[4];
2897
+ _readStream.read(m[0]);
2898
+ _readStream.read(m[1]);
2899
+ _readStream.read(m[2]);
2900
+ _readStream.read(m[3]);
2901
+ if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3])
2902
+ {
2903
+ BadMagicException ex(__FILE__, __LINE__);
2904
+ ex.badMagic = Ice::ByteSeq(&m[0], &m[0] + sizeof(magic));
2905
+ throw ex;
2906
+ }
2907
+ ProtocolVersion pv;
2908
+ _readStream.read(pv);
2909
+ checkSupportedProtocol(pv);
2910
+ EncodingVersion ev;
2911
+ _readStream.read(ev);
2912
+ checkSupportedProtocolEncoding(ev);
2913
+ Byte messageType;
2914
+ _readStream.read(messageType);
2915
+ if(messageType != validateConnectionMsg)
2916
+ {
2917
+ throw ConnectionNotValidatedException(__FILE__, __LINE__);
2918
+ }
2919
+ Byte compress;
2920
+ _readStream.read(compress); // Ignore compression status for validate connection.
2921
+ Int size;
2922
+ _readStream.read(size);
2923
+ if(size != headerSize)
2924
+ {
2925
+ throw IllegalMessageSizeException(__FILE__, __LINE__);
2926
+ }
2927
+ traceRecv(_readStream, _logger, _traceLevels);
2928
+
2929
+ _validated = true;
2930
+ }
2931
+ }
2932
+
2933
+ _writeStream.resize(0);
2934
+ _writeStream.i = _writeStream.b.begin();
2935
+
2936
+ _readStream.resize(headerSize);
2937
+ _readStream.i = _readStream.b.begin();
2938
+ _readHeader = true;
2939
+
2940
+ if(_instance->traceLevels()->network >= 1)
2941
+ {
2942
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
2943
+ if(_endpoint->datagram())
2944
+ {
2945
+ out << "starting to " << (_connector ? "send" : "receive") << " " << _endpoint->protocol() << " messages\n";
2946
+ out << _transceiver->toDetailedString();
2947
+ }
2948
+ else
2949
+ {
2950
+ out << (_connector ? "established" : "accepted") << " " << _endpoint->protocol() << " connection\n";
2951
+ out << toString();
2952
+ }
2953
+ }
2954
+
2955
+ return true;
2956
+ }
2957
+
2958
+ SocketOperation
2959
+ Ice::ConnectionI::sendNextMessage(vector<OutgoingMessage>& callbacks)
2960
+ {
2961
+ if(_sendStreams.empty())
2962
+ {
2963
+ return SocketOperationNone;
2964
+ }
2965
+ else if(_state == StateClosingPending && _writeStream.i == _writeStream.b.begin())
2966
+ {
2967
+ // Message wasn't sent, empty the _writeStream, we're not going to send more data.
2968
+ OutgoingMessage* message = &_sendStreams.front();
2969
+ _writeStream.swap(*message->stream);
2970
+ return SocketOperationNone;
2971
+ }
2972
+
2973
+ assert(!_writeStream.b.empty() && _writeStream.i == _writeStream.b.end());
2974
+ try
2975
+ {
2976
+ while(true)
2977
+ {
2978
+ //
2979
+ // Notify the message that it was sent.
2980
+ //
2981
+ OutgoingMessage* message = &_sendStreams.front();
2982
+ if(message->stream)
2983
+ {
2984
+ _writeStream.swap(*message->stream);
2985
+ if(message->sent())
2986
+ {
2987
+ callbacks.push_back(*message);
2988
+ }
2989
+ }
2990
+ _sendStreams.pop_front();
2991
+
2992
+ //
2993
+ // If there's nothing left to send, we're done.
2994
+ //
2995
+ if(_sendStreams.empty())
2996
+ {
2997
+ break;
2998
+ }
2999
+
3000
+ //
3001
+ // If we are in the closed state or if the close is
3002
+ // pending, don't continue sending.
3003
+ //
3004
+ // This can occur if parseMessage (called before
3005
+ // sendNextMessage by message()) closes the connection.
3006
+ //
3007
+ if(_state >= StateClosingPending)
3008
+ {
3009
+ return SocketOperationNone;
3010
+ }
3011
+
3012
+ //
3013
+ // Otherwise, prepare the next message stream for writing.
3014
+ //
3015
+ message = &_sendStreams.front();
3016
+ assert(!message->stream->i);
3017
+ #ifndef ICE_OS_WINRT
3018
+ if(message->compress && message->stream->b.size() >= 100) // Only compress messages > 100 bytes.
3019
+ {
3020
+ //
3021
+ // Message compressed. Request compressed response, if any.
3022
+ //
3023
+ message->stream->b[9] = 2;
3024
+
3025
+ //
3026
+ // Do compression.
3027
+ //
3028
+ BasicStream stream(_instance.get(), Ice::currentProtocolEncoding);
3029
+ doCompress(*message->stream, stream);
3030
+
3031
+ if(message->outAsync)
3032
+ {
3033
+ trace("sending asynchronous request", *message->stream, _logger, _traceLevels);
3034
+ }
3035
+ else
3036
+ {
3037
+ traceSend(*message->stream, _logger, _traceLevels);
3038
+ }
3039
+
3040
+ message->adopt(&stream); // Adopt the compressed stream.
3041
+ message->stream->i = message->stream->b.begin();
3042
+ }
3043
+ else
3044
+ {
3045
+ #endif
3046
+ if(message->compress)
3047
+ {
3048
+ //
3049
+ // Message not compressed. Request compressed response, if any.
3050
+ //
3051
+ message->stream->b[9] = 1;
3052
+ }
3053
+
3054
+ //
3055
+ // No compression, just fill in the message size.
3056
+ //
3057
+ Int sz = static_cast<Int>(message->stream->b.size());
3058
+ const Byte* p = reinterpret_cast<const Byte*>(&sz);
3059
+ #ifdef ICE_BIG_ENDIAN
3060
+ reverse_copy(p, p + sizeof(Int), message->stream->b.begin() + 10);
3061
+ #else
3062
+ copy(p, p + sizeof(Int), message->stream->b.begin() + 10);
3063
+ #endif
3064
+ message->stream->i = message->stream->b.begin();
3065
+ if(message->outAsync)
3066
+ {
3067
+ trace("sending asynchronous request", *message->stream, _logger, _traceLevels);
3068
+ }
3069
+ else
3070
+ {
3071
+ traceSend(*message->stream, _logger, _traceLevels);
3072
+ }
3073
+ #ifndef ICE_OS_WINRT
3074
+ }
3075
+ #endif
3076
+ _writeStream.swap(*message->stream);
3077
+
3078
+ //
3079
+ // Send the message.
3080
+ //
3081
+ if(_observer)
3082
+ {
3083
+ _observer.startWrite(_writeStream);
3084
+ }
3085
+ assert(_writeStream.i);
3086
+ if(_writeStream.i != _writeStream.b.end())
3087
+ {
3088
+ SocketOperation op = write(_writeStream);
3089
+ if(op)
3090
+ {
3091
+ return op;
3092
+ }
3093
+ }
3094
+ if(_observer)
3095
+ {
3096
+ _observer.finishWrite(_writeStream);
3097
+ }
3098
+ }
3099
+
3100
+ //
3101
+ // If all the messages were sent and we are in the closing state, we schedule
3102
+ // the close timeout to wait for the peer to close the connection.
3103
+ //
3104
+ if(_state == StateClosing && _shutdownInitiated)
3105
+ {
3106
+ setState(StateClosingPending);
3107
+ SocketOperation op = _transceiver->closing(true, *_exception.get());
3108
+ if(op)
3109
+ {
3110
+ return op;
3111
+ }
3112
+ }
3113
+ }
3114
+ catch(const Ice::LocalException& ex)
3115
+ {
3116
+ setState(StateClosed, ex);
3117
+ }
3118
+ return SocketOperationNone;
3119
+ }
3120
+
3121
+ AsyncStatus
3122
+ Ice::ConnectionI::sendMessage(OutgoingMessage& message)
3123
+ {
3124
+ assert(_state < StateClosed);
3125
+
3126
+ message.stream->i = 0; // Reset the message stream iterator before starting sending the message.
3127
+
3128
+ if(!_sendStreams.empty())
3129
+ {
3130
+ _sendStreams.push_back(message);
3131
+ _sendStreams.back().adopt(0);
3132
+ return AsyncStatusQueued;
3133
+ }
3134
+
3135
+ //
3136
+ // Attempt to send the message without blocking. If the send blocks, we register
3137
+ // the connection with the selector thread.
3138
+ //
3139
+
3140
+ message.stream->i = message.stream->b.begin();
3141
+ SocketOperation op;
3142
+ #ifndef ICE_OS_WINRT
3143
+ if(message.compress && message.stream->b.size() >= 100) // Only compress messages larger than 100 bytes.
3144
+ {
3145
+ //
3146
+ // Message compressed. Request compressed response, if any.
3147
+ //
3148
+ message.stream->b[9] = 2;
3149
+
3150
+ //
3151
+ // Do compression.
3152
+ //
3153
+ BasicStream stream(_instance.get(), Ice::currentProtocolEncoding);
3154
+ doCompress(*message.stream, stream);
3155
+ stream.i = stream.b.begin();
3156
+
3157
+ if(message.outAsync)
3158
+ {
3159
+ trace("sending asynchronous request", *message.stream, _logger, _traceLevels);
3160
+ }
3161
+ else
3162
+ {
3163
+ traceSend(*message.stream, _logger, _traceLevels);
3164
+ }
3165
+
3166
+ //
3167
+ // Send the message without blocking.
3168
+ //
3169
+ if(_observer)
3170
+ {
3171
+ _observer.startWrite(stream);
3172
+ }
3173
+ op = write(stream);
3174
+ if(!op)
3175
+ {
3176
+ if(_observer)
3177
+ {
3178
+ _observer.finishWrite(stream);
3179
+ }
3180
+
3181
+ AsyncStatus status = AsyncStatusSent;
3182
+ if(message.sent())
3183
+ {
3184
+ status = static_cast<AsyncStatus>(status | AsyncStatusInvokeSentCallback);
3185
+ }
3186
+ if(_acmLastActivity != IceUtil::Time())
3187
+ {
3188
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
3189
+ }
3190
+ return status;
3191
+ }
3192
+
3193
+ _sendStreams.push_back(message);
3194
+ _sendStreams.back().adopt(&stream);
3195
+ }
3196
+ else
3197
+ {
3198
+ #endif
3199
+ if(message.compress)
3200
+ {
3201
+ //
3202
+ // Message not compressed. Request compressed response, if any.
3203
+ //
3204
+ message.stream->b[9] = 1;
3205
+ }
3206
+
3207
+ //
3208
+ // No compression, just fill in the message size.
3209
+ //
3210
+ Int sz = static_cast<Int>(message.stream->b.size());
3211
+ const Byte* p = reinterpret_cast<const Byte*>(&sz);
3212
+ #ifdef ICE_BIG_ENDIAN
3213
+ reverse_copy(p, p + sizeof(Int), message.stream->b.begin() + 10);
3214
+ #else
3215
+ copy(p, p + sizeof(Int), message.stream->b.begin() + 10);
3216
+ #endif
3217
+ message.stream->i = message.stream->b.begin();
3218
+
3219
+ if(message.outAsync)
3220
+ {
3221
+ trace("sending asynchronous request", *message.stream, _logger, _traceLevels);
3222
+ }
3223
+ else
3224
+ {
3225
+ traceSend(*message.stream, _logger, _traceLevels);
3226
+ }
3227
+
3228
+ //
3229
+ // Send the message without blocking.
3230
+ //
3231
+ if(_observer)
3232
+ {
3233
+ _observer.startWrite(*message.stream);
3234
+ }
3235
+ op = write(*message.stream);
3236
+ if(!op)
3237
+ {
3238
+ if(_observer)
3239
+ {
3240
+ _observer.finishWrite(*message.stream);
3241
+ }
3242
+ AsyncStatus status = AsyncStatusSent;
3243
+ if(message.sent())
3244
+ {
3245
+ status = static_cast<AsyncStatus>(status | AsyncStatusInvokeSentCallback);
3246
+ }
3247
+ if(_acmLastActivity != IceUtil::Time())
3248
+ {
3249
+ _acmLastActivity = IceUtil::Time::now(IceUtil::Time::Monotonic);
3250
+ }
3251
+ return status;
3252
+ }
3253
+
3254
+ _sendStreams.push_back(message);
3255
+ _sendStreams.back().adopt(0); // Adopt the stream.
3256
+ #ifndef ICE_OS_WINRT
3257
+ }
3258
+ #endif
3259
+
3260
+ _writeStream.swap(*_sendStreams.back().stream);
3261
+ scheduleTimeout(op);
3262
+ _threadPool->_register(this, op);
3263
+ return AsyncStatusQueued;
3264
+ }
3265
+
3266
+ #ifndef ICE_OS_WINRT
3267
+ static string
3268
+ getBZ2Error(int bzError)
3269
+ {
3270
+ if(bzError == BZ_RUN_OK)
3271
+ {
3272
+ return ": BZ_RUN_OK";
3273
+ }
3274
+ else if(bzError == BZ_FLUSH_OK)
3275
+ {
3276
+ return ": BZ_FLUSH_OK";
3277
+ }
3278
+ else if(bzError == BZ_FINISH_OK)
3279
+ {
3280
+ return ": BZ_FINISH_OK";
3281
+ }
3282
+ else if(bzError == BZ_STREAM_END)
3283
+ {
3284
+ return ": BZ_STREAM_END";
3285
+ }
3286
+ else if(bzError == BZ_CONFIG_ERROR)
3287
+ {
3288
+ return ": BZ_CONFIG_ERROR";
3289
+ }
3290
+ else if(bzError == BZ_SEQUENCE_ERROR)
3291
+ {
3292
+ return ": BZ_SEQUENCE_ERROR";
3293
+ }
3294
+ else if(bzError == BZ_PARAM_ERROR)
3295
+ {
3296
+ return ": BZ_PARAM_ERROR";
3297
+ }
3298
+ else if(bzError == BZ_MEM_ERROR)
3299
+ {
3300
+ return ": BZ_MEM_ERROR";
3301
+ }
3302
+ else if(bzError == BZ_DATA_ERROR)
3303
+ {
3304
+ return ": BZ_DATA_ERROR";
3305
+ }
3306
+ else if(bzError == BZ_DATA_ERROR_MAGIC)
3307
+ {
3308
+ return ": BZ_DATA_ERROR_MAGIC";
3309
+ }
3310
+ else if(bzError == BZ_IO_ERROR)
3311
+ {
3312
+ return ": BZ_IO_ERROR";
3313
+ }
3314
+ else if(bzError == BZ_UNEXPECTED_EOF)
3315
+ {
3316
+ return ": BZ_UNEXPECTED_EOF";
3317
+ }
3318
+ else if(bzError == BZ_OUTBUFF_FULL)
3319
+ {
3320
+ return ": BZ_OUTBUFF_FULL";
3321
+ }
3322
+ else
3323
+ {
3324
+ return "";
3325
+ }
3326
+ }
3327
+
3328
+ void
3329
+ Ice::ConnectionI::doCompress(BasicStream& uncompressed, BasicStream& compressed)
3330
+ {
3331
+ const Byte* p;
3332
+
3333
+ //
3334
+ // Compress the message body, but not the header.
3335
+ //
3336
+ unsigned int uncompressedLen = static_cast<unsigned int>(uncompressed.b.size() - headerSize);
3337
+ unsigned int compressedLen = static_cast<unsigned int>(uncompressedLen * 1.01 + 600);
3338
+ compressed.b.resize(headerSize + sizeof(Int) + compressedLen);
3339
+ int bzError = BZ2_bzBuffToBuffCompress(reinterpret_cast<char*>(&compressed.b[0]) + headerSize + sizeof(Int),
3340
+ &compressedLen,
3341
+ reinterpret_cast<char*>(&uncompressed.b[0]) + headerSize,
3342
+ uncompressedLen,
3343
+ _compressionLevel, 0, 0);
3344
+ if(bzError != BZ_OK)
3345
+ {
3346
+ CompressionException ex(__FILE__, __LINE__);
3347
+ ex.reason = "BZ2_bzBuffToBuffCompress failed" + getBZ2Error(bzError);
3348
+ throw ex;
3349
+ }
3350
+ compressed.b.resize(headerSize + sizeof(Int) + compressedLen);
3351
+
3352
+ //
3353
+ // Write the size of the compressed stream into the header of the
3354
+ // uncompressed stream. Since the header will be copied, this size
3355
+ // will also be in the header of the compressed stream.
3356
+ //
3357
+ Int compressedSize = static_cast<Int>(compressed.b.size());
3358
+ p = reinterpret_cast<const Byte*>(&compressedSize);
3359
+ #ifdef ICE_BIG_ENDIAN
3360
+ reverse_copy(p, p + sizeof(Int), uncompressed.b.begin() + 10);
3361
+ #else
3362
+ copy(p, p + sizeof(Int), uncompressed.b.begin() + 10);
3363
+ #endif
3364
+
3365
+ //
3366
+ // Add the size of the uncompressed stream before the message body
3367
+ // of the compressed stream.
3368
+ //
3369
+ Int uncompressedSize = static_cast<Int>(uncompressed.b.size());
3370
+ p = reinterpret_cast<const Byte*>(&uncompressedSize);
3371
+ #ifdef ICE_BIG_ENDIAN
3372
+ reverse_copy(p, p + sizeof(Int), compressed.b.begin() + headerSize);
3373
+ #else
3374
+ copy(p, p + sizeof(Int), compressed.b.begin() + headerSize);
3375
+ #endif
3376
+
3377
+ //
3378
+ // Copy the header from the uncompressed stream to the compressed one.
3379
+ //
3380
+ copy(uncompressed.b.begin(), uncompressed.b.begin() + headerSize, compressed.b.begin());
3381
+ }
3382
+
3383
+ void
3384
+ Ice::ConnectionI::doUncompress(BasicStream& compressed, BasicStream& uncompressed)
3385
+ {
3386
+ Int uncompressedSize;
3387
+ compressed.i = compressed.b.begin() + headerSize;
3388
+ compressed.read(uncompressedSize);
3389
+ if(uncompressedSize <= headerSize)
3390
+ {
3391
+ throw IllegalMessageSizeException(__FILE__, __LINE__);
3392
+ }
3393
+
3394
+ if(uncompressedSize > static_cast<Int>(_messageSizeMax))
3395
+ {
3396
+ Ex::throwMemoryLimitException(__FILE__, __LINE__, uncompressedSize, _messageSizeMax);
3397
+ }
3398
+ uncompressed.resize(uncompressedSize);
3399
+
3400
+ unsigned int uncompressedLen = uncompressedSize - headerSize;
3401
+ unsigned int compressedLen = static_cast<unsigned int>(compressed.b.size() - headerSize - sizeof(Int));
3402
+ int bzError = BZ2_bzBuffToBuffDecompress(reinterpret_cast<char*>(&uncompressed.b[0]) + headerSize,
3403
+ &uncompressedLen,
3404
+ reinterpret_cast<char*>(&compressed.b[0]) + headerSize + sizeof(Int),
3405
+ compressedLen,
3406
+ 0, 0);
3407
+ if(bzError != BZ_OK)
3408
+ {
3409
+ CompressionException ex(__FILE__, __LINE__);
3410
+ ex.reason = "BZ2_bzBuffToBuffCompress failed" + getBZ2Error(bzError);
3411
+ throw ex;
3412
+ }
3413
+
3414
+ copy(compressed.b.begin(), compressed.b.begin() + headerSize, uncompressed.b.begin());
3415
+ }
3416
+ #endif
3417
+
3418
+ SocketOperation
3419
+ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& requestId, Byte& compress,
3420
+ ServantManagerPtr& servantManager, ObjectAdapterPtr& adapter,
3421
+ OutgoingAsyncPtr& outAsync, ConnectionCallbackPtr& heartbeatCallback,
3422
+ int& dispatchCount)
3423
+ {
3424
+ assert(_state > StateNotValidated && _state < StateClosed);
3425
+
3426
+ _readStream.swap(stream);
3427
+ _readStream.resize(headerSize);
3428
+ _readStream.i = _readStream.b.begin();
3429
+ _readHeader = true;
3430
+
3431
+ assert(stream.i == stream.b.end());
3432
+
3433
+ //
3434
+ // Connection is validated on first message. This is only used by
3435
+ // setState() to check wether or not we can print a connection
3436
+ // warning (a client might close the connection forcefully if the
3437
+ // connection isn't validated).
3438
+ //
3439
+ _validated = true;
3440
+
3441
+ try
3442
+ {
3443
+ //
3444
+ // We don't need to check magic and version here. This has
3445
+ // already been done by the ThreadPool, which provides us
3446
+ // with the stream.
3447
+ //
3448
+ assert(stream.i == stream.b.end());
3449
+ stream.i = stream.b.begin() + 8;
3450
+ Byte messageType;
3451
+ stream.read(messageType);
3452
+ stream.read(compress);
3453
+
3454
+ #ifndef ICE_OS_WINRT
3455
+ if(compress == 2)
3456
+ {
3457
+ BasicStream ustream(_instance.get(), Ice::currentProtocolEncoding);
3458
+ doUncompress(stream, ustream);
3459
+ stream.b.swap(ustream.b);
3460
+ }
3461
+ #endif
3462
+ stream.i = stream.b.begin() + headerSize;
3463
+
3464
+ switch(messageType)
3465
+ {
3466
+ case closeConnectionMsg:
3467
+ {
3468
+ traceRecv(stream, _logger, _traceLevels);
3469
+ if(_endpoint->datagram())
3470
+ {
3471
+ if(_warn)
3472
+ {
3473
+ Warning out(_logger);
3474
+ out << "ignoring close connection message for datagram connection:\n" << _desc;
3475
+ }
3476
+ }
3477
+ else
3478
+ {
3479
+ setState(StateClosingPending, CloseConnectionException(__FILE__, __LINE__));
3480
+
3481
+ //
3482
+ // Notify the the transceiver of the graceful connection closure.
3483
+ //
3484
+ SocketOperation op = _transceiver->closing(false, *_exception.get());
3485
+ if(op)
3486
+ {
3487
+ return op;
3488
+ }
3489
+ setState(StateClosed);
3490
+ }
3491
+ break;
3492
+ }
3493
+
3494
+ case requestMsg:
3495
+ {
3496
+ if(_state >= StateClosing)
3497
+ {
3498
+ trace("received request during closing\n(ignored by server, client will retry)", stream, _logger,
3499
+ _traceLevels);
3500
+ }
3501
+ else
3502
+ {
3503
+ traceRecv(stream, _logger, _traceLevels);
3504
+ stream.read(requestId);
3505
+ invokeNum = 1;
3506
+ servantManager = _servantManager;
3507
+ adapter = _adapter;
3508
+ ++dispatchCount;
3509
+ }
3510
+ break;
3511
+ }
3512
+
3513
+ case requestBatchMsg:
3514
+ {
3515
+ if(_state >= StateClosing)
3516
+ {
3517
+ trace("received batch request during closing\n(ignored by server, client will retry)", stream,
3518
+ _logger, _traceLevels);
3519
+ }
3520
+ else
3521
+ {
3522
+ traceRecv(stream, _logger, _traceLevels);
3523
+ stream.read(invokeNum);
3524
+ if(invokeNum < 0)
3525
+ {
3526
+ invokeNum = 0;
3527
+ throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
3528
+ }
3529
+ servantManager = _servantManager;
3530
+ adapter = _adapter;
3531
+ dispatchCount += invokeNum;
3532
+ }
3533
+ break;
3534
+ }
3535
+
3536
+ case replyMsg:
3537
+ {
3538
+ traceRecv(stream, _logger, _traceLevels);
3539
+
3540
+ stream.read(requestId);
3541
+
3542
+ map<Int, Outgoing*>::iterator p = _requests.end();
3543
+ map<Int, OutgoingAsyncPtr>::iterator q = _asyncRequests.end();
3544
+
3545
+ if(_requestsHint != _requests.end())
3546
+ {
3547
+ if(_requestsHint->first == requestId)
3548
+ {
3549
+ p = _requestsHint;
3550
+ }
3551
+ }
3552
+
3553
+ if(p == _requests.end())
3554
+ {
3555
+ if(_asyncRequestsHint != _asyncRequests.end())
3556
+ {
3557
+ if(_asyncRequestsHint->first == requestId)
3558
+ {
3559
+ q = _asyncRequestsHint;
3560
+ }
3561
+ }
3562
+ }
3563
+
3564
+ if(p == _requests.end() && q == _asyncRequests.end())
3565
+ {
3566
+ p = _requests.find(requestId);
3567
+ }
3568
+
3569
+ if(p == _requests.end() && q == _asyncRequests.end())
3570
+ {
3571
+ q = _asyncRequests.find(requestId);
3572
+ }
3573
+
3574
+ if(p != _requests.end())
3575
+ {
3576
+ p->second->completed(stream);
3577
+
3578
+ if(p == _requestsHint)
3579
+ {
3580
+ _requests.erase(p++);
3581
+ _requestsHint = p;
3582
+ }
3583
+ else
3584
+ {
3585
+ _requests.erase(p);
3586
+ }
3587
+ notifyAll(); // Notify threads blocked in close(false)
3588
+ }
3589
+ else if(q != _asyncRequests.end())
3590
+ {
3591
+ outAsync = q->second;
3592
+
3593
+ if(q == _asyncRequestsHint)
3594
+ {
3595
+ _asyncRequests.erase(q++);
3596
+ _asyncRequestsHint = q;
3597
+ }
3598
+ else
3599
+ {
3600
+ _asyncRequests.erase(q);
3601
+ }
3602
+
3603
+ stream.swap(*outAsync->getIs());
3604
+
3605
+ #if defined(ICE_USE_IOCP) || defined(ICE_OS_WINRT)
3606
+ //
3607
+ // If we just received the reply of a request which isn't acknowledge as
3608
+ // sent yet, we queue the reply instead of processing it right away. It
3609
+ // will be processed once the write callback is invoked for the message.
3610
+ //
3611
+ OutgoingMessage* message = _sendStreams.empty() ? 0 : &_sendStreams.front();
3612
+ if(message && message->outAsync.get() == outAsync.get())
3613
+ {
3614
+ message->receivedReply = true;
3615
+ outAsync = 0;
3616
+ }
3617
+ else if(outAsync->completed())
3618
+ {
3619
+ ++dispatchCount;
3620
+ }
3621
+ else
3622
+ {
3623
+ outAsync = 0;
3624
+ }
3625
+ #else
3626
+ if(outAsync->completed())
3627
+ {
3628
+ ++dispatchCount;
3629
+ }
3630
+ else
3631
+ {
3632
+ outAsync = 0;
3633
+ }
3634
+ #endif
3635
+ notifyAll(); // Notify threads blocked in close(false)
3636
+ }
3637
+
3638
+ break;
3639
+ }
3640
+
3641
+ case validateConnectionMsg:
3642
+ {
3643
+ traceRecv(stream, _logger, _traceLevels);
3644
+ if(_callback)
3645
+ {
3646
+ heartbeatCallback = _callback;
3647
+ ++dispatchCount;
3648
+ }
3649
+ break;
3650
+ }
3651
+
3652
+ default:
3653
+ {
3654
+ trace("received unknown message\n(invalid, closing connection)", stream, _logger, _traceLevels);
3655
+ throw UnknownMessageException(__FILE__, __LINE__);
3656
+ }
3657
+ }
3658
+ }
3659
+ catch(const LocalException& ex)
3660
+ {
3661
+ if(_endpoint->datagram())
3662
+ {
3663
+ if(_warn)
3664
+ {
3665
+ Warning out(_logger);
3666
+ out << "datagram connection exception:\n" << ex << '\n' << _desc;
3667
+ }
3668
+ }
3669
+ else
3670
+ {
3671
+ setState(StateClosed, ex);
3672
+ }
3673
+ }
3674
+
3675
+ return _state == StateHolding ? SocketOperationNone : SocketOperationRead;
3676
+ }
3677
+
3678
+ void
3679
+ Ice::ConnectionI::invokeAll(BasicStream& stream, Int invokeNum, Int requestId, Byte compress,
3680
+ const ServantManagerPtr& servantManager, const ObjectAdapterPtr& adapter)
3681
+ {
3682
+ //
3683
+ // Note: In contrast to other private or protected methods, this
3684
+ // operation must be called *without* the mutex locked.
3685
+ //
3686
+
3687
+ try
3688
+ {
3689
+ while(invokeNum > 0)
3690
+ {
3691
+ //
3692
+ // Prepare the invocation.
3693
+ //
3694
+ bool response = !_endpoint->datagram() && requestId != 0;
3695
+ assert(!response || invokeNum == 1);
3696
+
3697
+ Incoming in(_instance.get(), this, this, adapter, response, compress, requestId);
3698
+
3699
+ //
3700
+ // Dispatch the invocation.
3701
+ //
3702
+ in.invoke(servantManager, &stream);
3703
+
3704
+ --invokeNum;
3705
+ }
3706
+
3707
+ stream.clear();
3708
+ }
3709
+ catch(const LocalException& ex)
3710
+ {
3711
+ invokeException(requestId, ex, invokeNum, false); // Fatal invocation exception
3712
+ }
3713
+ }
3714
+
3715
+ void
3716
+ Ice::ConnectionI::scheduleTimeout(SocketOperation status)
3717
+ {
3718
+ int timeout;
3719
+ if(_state < StateActive)
3720
+ {
3721
+ DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides();
3722
+ if(defaultsAndOverrides->overrideConnectTimeout)
3723
+ {
3724
+ timeout = defaultsAndOverrides->overrideConnectTimeoutValue;
3725
+ }
3726
+ else
3727
+ {
3728
+ timeout = _endpoint->timeout();
3729
+ }
3730
+ }
3731
+ else if(_state < StateClosingPending)
3732
+ {
3733
+ if(_readHeader) // No timeout for reading the header.
3734
+ {
3735
+ status = static_cast<SocketOperation>(status & ~SocketOperationRead);
3736
+ }
3737
+ timeout = _endpoint->timeout();
3738
+ }
3739
+ else
3740
+ {
3741
+ DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides();
3742
+ if(defaultsAndOverrides->overrideCloseTimeout)
3743
+ {
3744
+ timeout = defaultsAndOverrides->overrideCloseTimeoutValue;
3745
+ }
3746
+ else
3747
+ {
3748
+ timeout = _endpoint->timeout();
3749
+ }
3750
+ }
3751
+
3752
+ if(timeout < 0)
3753
+ {
3754
+ return;
3755
+ }
3756
+
3757
+ try
3758
+ {
3759
+ if(status & IceInternal::SocketOperationRead)
3760
+ {
3761
+ if(_readTimeoutScheduled)
3762
+ {
3763
+ _timer->cancel(_readTimeout);
3764
+ }
3765
+ _timer->schedule(_readTimeout, IceUtil::Time::milliSeconds(timeout));
3766
+ _readTimeoutScheduled = true;
3767
+ }
3768
+ if(status & (IceInternal::SocketOperationWrite | IceInternal::SocketOperationConnect))
3769
+ {
3770
+ if(_writeTimeoutScheduled)
3771
+ {
3772
+ _timer->cancel(_writeTimeout);
3773
+ }
3774
+ _timer->schedule(_writeTimeout, IceUtil::Time::milliSeconds(timeout));
3775
+ _writeTimeoutScheduled = true;
3776
+ }
3777
+ }
3778
+ catch(const IceUtil::Exception&)
3779
+ {
3780
+ assert(false);
3781
+ }
3782
+ }
3783
+
3784
+ void
3785
+ Ice::ConnectionI::unscheduleTimeout(SocketOperation status)
3786
+ {
3787
+ if((status & IceInternal::SocketOperationRead) && _readTimeoutScheduled)
3788
+ {
3789
+ _timer->cancel(_readTimeout);
3790
+ _readTimeoutScheduled = false;
3791
+ }
3792
+ if((status & (IceInternal::SocketOperationWrite | IceInternal::SocketOperationConnect)) &&
3793
+ _writeTimeoutScheduled)
3794
+ {
3795
+ _timer->cancel(_writeTimeout);
3796
+ _writeTimeoutScheduled = false;
3797
+ }
3798
+ }
3799
+
3800
+ Ice::ConnectionInfoPtr
3801
+ Ice::ConnectionI::initConnectionInfo() const
3802
+ {
3803
+ if(_info)
3804
+ {
3805
+ return _info;
3806
+ }
3807
+
3808
+ ConnectionInfoPtr info = _transceiver->getInfo();
3809
+ info->connectionId = _endpoint->connectionId();
3810
+ info->incoming = _connector == 0;
3811
+ info->adapterName = _adapter ? _adapter->getName() : string();
3812
+ if(_state > StateNotInitialized)
3813
+ {
3814
+ _info = info; // Cache the connection information only if initialized.
3815
+ }
3816
+ return info;
3817
+ }
3818
+
3819
+ ConnectionState
3820
+ ConnectionI::toConnectionState(State state) const
3821
+ {
3822
+ return connectionStateMap[static_cast<int>(state)];
3823
+ }
3824
+
3825
+ SocketOperation
3826
+ ConnectionI::read(Buffer& buf)
3827
+ {
3828
+ Buffer::Container::iterator start = buf.i;
3829
+ SocketOperation op = _transceiver->read(buf, _hasMoreData);
3830
+ if(_instance->traceLevels()->network >= 3 && buf.i != start)
3831
+ {
3832
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
3833
+ out << "received ";
3834
+ if(_endpoint->datagram())
3835
+ {
3836
+ out << buf.b.size();
3837
+ }
3838
+ else
3839
+ {
3840
+ out << (buf.i - start) << " of " << (buf.b.end() - start);
3841
+ }
3842
+ out << " bytes via " << _endpoint->protocol() << "\n" << toString();
3843
+ }
3844
+ return op;
3845
+ }
3846
+
3847
+ SocketOperation
3848
+ ConnectionI::write(Buffer& buf)
3849
+ {
3850
+ Buffer::Container::iterator start = buf.i;
3851
+ SocketOperation op = _transceiver->write(buf);
3852
+ if(_instance->traceLevels()->network >= 3 && buf.i != start)
3853
+ {
3854
+ Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
3855
+ out << "sent " << (buf.i - start);
3856
+ if(!_endpoint->datagram())
3857
+ {
3858
+ out << " of " << (buf.b.end() - start);
3859
+ }
3860
+ out << " bytes via " << _endpoint->protocol() << "\n" << toString();
3861
+ }
3862
+ return op;
3863
+ }
3864
+
3865
+ void
3866
+ ConnectionI::reap()
3867
+ {
3868
+ if(_monitor)
3869
+ {
3870
+ _monitor->reap(this);
3871
+ }
3872
+ if(_observer)
3873
+ {
3874
+ _observer.detach();
3875
+ }
3876
+ }