zeroc-ice 3.8.2 → 3.8.3

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Communicator.cpp +26 -9
  3. data/dist/IceRuby/Config.h +0 -12
  4. data/dist/IceRuby/Connection.cpp +18 -9
  5. data/dist/IceRuby/DefaultSliceLoader.h +1 -1
  6. data/dist/IceRuby/Endpoint.cpp +21 -8
  7. data/dist/IceRuby/Operation.cpp +7 -5
  8. data/dist/IceRuby/Properties.cpp +3 -4
  9. data/dist/IceRuby/Proxy.cpp +11 -19
  10. data/dist/IceRuby/RubySliceLoader.cpp +1 -1
  11. data/dist/IceRuby/RubySliceLoader.h +6 -0
  12. data/dist/IceRuby/Types.cpp +162 -138
  13. data/dist/IceRuby/Types.h +68 -28
  14. data/dist/IceRuby/Util.cpp +14 -78
  15. data/dist/IceRuby/Util.h +7 -17
  16. data/dist/ice/cpp/include/Ice/Communicator.h +31 -8
  17. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  18. data/dist/ice/cpp/include/Ice/Connection.h +24 -8
  19. data/dist/ice/cpp/include/Ice/CtrlCHandler.h +1 -1
  20. data/dist/ice/cpp/include/Ice/Demangle.h +1 -1
  21. data/dist/ice/cpp/include/Ice/Endpoint.h +4 -4
  22. data/dist/ice/cpp/include/Ice/Initialize.h +4 -4
  23. data/dist/ice/cpp/include/Ice/InputStream.h +5 -5
  24. data/dist/ice/cpp/include/Ice/Instrumentation.h +13 -7
  25. data/dist/ice/cpp/include/Ice/LocalExceptions.h +5 -5
  26. data/dist/ice/cpp/include/Ice/Logger.h +7 -0
  27. data/dist/ice/cpp/include/Ice/LoggerUtil.h +1 -1
  28. data/dist/ice/cpp/include/Ice/Object.h +10 -8
  29. data/dist/ice/cpp/include/Ice/ObjectAdapter.h +1 -1
  30. data/dist/ice/cpp/include/Ice/OutgoingAsync.h +5 -2
  31. data/dist/ice/cpp/include/Ice/OutgoingResponse.h +2 -1
  32. data/dist/ice/cpp/include/Ice/OutputStream.h +7 -6
  33. data/dist/ice/cpp/include/Ice/PluginFactory.h +1 -1
  34. data/dist/ice/cpp/include/Ice/Properties.h +3 -3
  35. data/dist/ice/cpp/include/Ice/Proxy.h +192 -50
  36. data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +3 -3
  37. data/dist/ice/cpp/include/Ice/SSL/EndpointInfo.h +1 -1
  38. data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +5 -5
  39. data/dist/ice/cpp/include/Ice/ServantLocator.h +1 -1
  40. data/dist/ice/cpp/include/Ice/Service.h +2 -5
  41. data/dist/ice/cpp/include/Ice/SliceLoader.h +1 -1
  42. data/dist/ice/cpp/include/Ice/SlicedData.h +5 -3
  43. data/dist/ice/cpp/include/Ice/StreamHelpers.h +1 -1
  44. data/dist/ice/cpp/include/Ice/StreamableTraits.h +2 -2
  45. data/dist/ice/cpp/include/Ice/StringConverter.h +2 -3
  46. data/dist/ice/cpp/include/Ice/StringUtil.h +2 -7
  47. data/dist/ice/cpp/include/Ice/UUID.h +1 -0
  48. data/dist/ice/cpp/include/Ice/Value.h +2 -2
  49. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  50. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  51. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  52. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  53. data/dist/ice/cpp/include/generated/Ice/Locator.h +50 -14
  54. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +38 -11
  55. data/dist/ice/cpp/include/generated/Ice/Metrics.h +94 -39
  56. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  57. data/dist/ice/cpp/include/generated/Ice/Process.h +34 -8
  58. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +42 -11
  59. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  60. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +93 -40
  61. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +2 -2
  62. data/dist/ice/cpp/include/generated/Ice/Router.h +50 -14
  63. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  64. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  65. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +66 -14
  66. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +34 -8
  67. data/dist/ice/cpp/src/Ice/AddDefaultPluginFactories_all.cpp +1 -1
  68. data/dist/ice/cpp/src/Ice/Base64.cpp +47 -137
  69. data/dist/ice/cpp/src/Ice/Base64.h +2 -2
  70. data/dist/ice/cpp/src/Ice/BatchRequestQueue.cpp +28 -13
  71. data/dist/ice/cpp/src/Ice/BatchRequestQueue.h +5 -1
  72. data/dist/ice/cpp/src/Ice/Buffer.cpp +1 -1
  73. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +1 -1
  74. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.h +1 -1
  75. data/dist/ice/cpp/src/Ice/Communicator.cpp +4 -3
  76. data/dist/ice/cpp/src/Ice/CommunicatorFlushBatchAsync.cpp +8 -0
  77. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.cpp +5 -15
  78. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.h +1 -1
  79. data/dist/ice/cpp/src/Ice/ConnectionFactory.cpp +6 -8
  80. data/dist/ice/cpp/src/Ice/ConnectionFactory.h +0 -3
  81. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +94 -99
  82. data/dist/ice/cpp/src/Ice/ConnectionI.h +11 -8
  83. data/dist/ice/cpp/src/Ice/ConsoleUtil.cpp +1 -1
  84. data/dist/ice/cpp/src/Ice/DefaultsAndOverrides.cpp +10 -14
  85. data/dist/ice/cpp/src/Ice/EndpointI.h +1 -1
  86. data/dist/ice/cpp/src/Ice/FileUtil.cpp +12 -12
  87. data/dist/ice/cpp/src/Ice/FixedRequestHandler.cpp +1 -1
  88. data/dist/ice/cpp/src/Ice/FixedRequestHandler.h +1 -1
  89. data/dist/ice/cpp/src/Ice/HttpParser.h +0 -2
  90. data/dist/ice/cpp/src/Ice/IdleTimeoutTransceiverDecorator.cpp +6 -3
  91. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -3
  92. data/dist/ice/cpp/src/Ice/InputStream.cpp +23 -19
  93. data/dist/ice/cpp/src/Ice/Instance.cpp +73 -50
  94. data/dist/ice/cpp/src/Ice/Instance.h +1 -6
  95. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +1 -1
  96. data/dist/ice/cpp/src/Ice/LocatorInfo.cpp +2 -2
  97. data/dist/ice/cpp/src/Ice/LoggerAdminI.cpp +13 -18
  98. data/dist/ice/cpp/src/Ice/LoggerI.cpp +1 -1
  99. data/dist/ice/cpp/src/Ice/LoggerI.h +2 -2
  100. data/dist/ice/cpp/src/Ice/MetricsAdminI.h +6 -1
  101. data/dist/ice/cpp/src/Ice/MetricsObserverI.h +22 -18
  102. data/dist/ice/cpp/src/Ice/NativePropertiesAdmin.cpp +5 -2
  103. data/dist/ice/cpp/src/Ice/Network.cpp +168 -103
  104. data/dist/ice/cpp/src/Ice/Network.h +12 -7
  105. data/dist/ice/cpp/src/Ice/NetworkProxy.cpp +17 -6
  106. data/dist/ice/cpp/src/Ice/NetworkProxy.h +2 -1
  107. data/dist/ice/cpp/src/Ice/Object.cpp +1 -1
  108. data/dist/ice/cpp/src/Ice/ObjectAdapterI.cpp +56 -19
  109. data/dist/ice/cpp/src/Ice/OpaqueEndpointI.cpp +10 -10
  110. data/dist/ice/cpp/src/Ice/Options.cpp +7 -2
  111. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  112. data/dist/ice/cpp/src/Ice/OutputStream.cpp +4 -4
  113. data/dist/ice/cpp/src/Ice/PluginManagerI.cpp +7 -1
  114. data/dist/ice/cpp/src/Ice/Properties.cpp +26 -16
  115. data/dist/ice/cpp/src/Ice/PropertyUtil.cpp +1 -1
  116. data/dist/ice/cpp/src/Ice/ProtocolInstance.cpp +0 -11
  117. data/dist/ice/cpp/src/Ice/ProtocolInstance.h +1 -2
  118. data/dist/ice/cpp/src/Ice/Proxy.cpp +9 -1
  119. data/dist/ice/cpp/src/Ice/ProxyAsync.cpp +110 -13
  120. data/dist/ice/cpp/src/Ice/Random.cpp +68 -7
  121. data/dist/ice/cpp/src/Ice/Random.h +6 -2
  122. data/dist/ice/cpp/src/Ice/Reference.cpp +22 -11
  123. data/dist/ice/cpp/src/Ice/Reference.h +3 -0
  124. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +10 -0
  125. data/dist/ice/cpp/src/Ice/RequestHandler.h +3 -1
  126. data/dist/ice/cpp/src/Ice/RequestHandlerCache.cpp +1 -1
  127. data/dist/ice/cpp/src/Ice/RequestHandlerCache.h +1 -1
  128. data/dist/ice/cpp/src/Ice/ResourceConfig.h +3 -3
  129. data/dist/ice/cpp/src/Ice/RetryQueue.cpp +8 -12
  130. data/dist/ice/cpp/src/Ice/SHA1.cpp +11 -11
  131. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.cpp +0 -6
  132. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.h +0 -6
  133. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +15 -1
  134. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +77 -27
  135. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.h +2 -1
  136. data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +2 -2
  137. data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +39 -34
  138. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +130 -52
  139. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +64 -33
  140. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.h +0 -1
  141. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +3 -3
  142. data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.cpp +9 -3
  143. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +73 -51
  144. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.h +0 -8
  145. data/dist/ice/cpp/src/Ice/Selector.cpp +13 -11
  146. data/dist/ice/cpp/src/Ice/ServantManager.cpp +3 -3
  147. data/dist/ice/cpp/src/Ice/Service.cpp +33 -115
  148. data/dist/ice/cpp/src/Ice/StreamSocket.cpp +33 -40
  149. data/dist/ice/cpp/src/Ice/StreamSocket.h +4 -4
  150. data/dist/ice/cpp/src/Ice/StringConverter.cpp +1 -1
  151. data/dist/ice/cpp/src/Ice/StringUtil.cpp +12 -21
  152. data/dist/ice/cpp/src/Ice/SysLoggerI.cpp +136 -100
  153. data/dist/ice/cpp/src/Ice/SysLoggerI.h +7 -3
  154. data/dist/ice/cpp/src/Ice/SystemdJournalI.cpp +1 -1
  155. data/dist/ice/cpp/src/Ice/TcpAcceptor.cpp +7 -7
  156. data/dist/ice/cpp/src/Ice/TcpAcceptor.h +2 -1
  157. data/dist/ice/cpp/src/Ice/TcpBufSize.h +40 -0
  158. data/dist/ice/cpp/src/Ice/TcpConnector.cpp +5 -2
  159. data/dist/ice/cpp/src/Ice/TcpConnector.h +2 -0
  160. data/dist/ice/cpp/src/Ice/TcpTransceiver.cpp +6 -2
  161. data/dist/ice/cpp/src/Ice/ThreadPool.cpp +2 -8
  162. data/dist/ice/cpp/src/Ice/ThreadPool.h +0 -2
  163. data/dist/ice/cpp/src/Ice/Timer.cpp +7 -3
  164. data/dist/ice/cpp/src/Ice/UUID.cpp +1 -2
  165. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +4 -1
  166. data/dist/ice/cpp/src/Ice/UdpTransceiver.cpp +136 -123
  167. data/dist/ice/cpp/src/Ice/UdpTransceiver.h +3 -4
  168. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +96 -27
  169. data/dist/ice/cpp/src/Ice/WSTransceiver.h +1 -1
  170. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  171. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  172. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  173. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  174. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  175. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  176. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  177. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  178. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  179. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  180. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  181. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  182. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +2 -2
  183. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  184. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  185. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  186. data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +47 -9
  187. data/dist/ice/cpp/src/IceDiscovery/LookupI.h +8 -3
  188. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  189. data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +43 -14
  190. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  191. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +26 -20
  192. data/dist/ice/cpp/src/Slice/DocCommentParser.h +2 -2
  193. data/dist/ice/cpp/src/Slice/FileTracker.cpp +3 -11
  194. data/dist/ice/cpp/src/Slice/FileTracker.h +0 -2
  195. data/dist/ice/cpp/src/Slice/Grammar.cpp +211 -210
  196. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +10 -9
  197. data/dist/ice/cpp/src/Slice/Parser.cpp +28 -20
  198. data/dist/ice/cpp/src/Slice/Parser.h +3 -4
  199. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +3 -11
  200. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -2
  201. data/dist/ice/cpp/src/Slice/Scanner.cpp +3 -3
  202. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +197 -114
  203. data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +0 -2
  204. data/dist/ice/cpp/src/Slice/Util.h +21 -9
  205. data/dist/ice/cpp/src/slice2rb/Ruby.cpp +7 -3
  206. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +16 -12
  207. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +3 -3
  208. data/dist/ice/slice/Glacier2/Router.ice +3 -3
  209. data/dist/ice/slice/Ice/Metrics.ice +6 -5
  210. data/dist/ice/slice/Ice/RemoteLogger.ice +5 -5
  211. data/dist/ice/slice/IceGrid/Admin.ice +9 -9
  212. data/dist/ice/slice/IceGrid/Descriptor.ice +5 -5
  213. data/dist/ice/slice/IceStorm/Metrics.ice +1 -1
  214. data/dist/lib/Glacier2/Metrics.rb +1 -1
  215. data/dist/lib/Glacier2/PermissionsVerifier.rb +1 -1
  216. data/dist/lib/Glacier2/Router.rb +2 -2
  217. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  218. data/dist/lib/Glacier2/Session.rb +1 -1
  219. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  220. data/dist/lib/Ice/CompressBatch.rb +1 -2
  221. data/dist/lib/Ice/Context.rb +1 -1
  222. data/dist/lib/Ice/EndpointSelectionType.rb +1 -2
  223. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  224. data/dist/lib/Ice/Identity.rb +1 -1
  225. data/dist/lib/Ice/IdentitySpaceship.rb +1 -0
  226. data/dist/lib/Ice/Locator.rb +1 -1
  227. data/dist/lib/Ice/LocatorRegistry.rb +1 -1
  228. data/dist/lib/Ice/Metrics.rb +1 -1
  229. data/dist/lib/Ice/OperationMode.rb +2 -3
  230. data/dist/lib/Ice/Process.rb +1 -1
  231. data/dist/lib/Ice/PropertiesAdmin.rb +1 -1
  232. data/dist/lib/Ice/PropertyDict.rb +1 -1
  233. data/dist/lib/Ice/RemoteLogger.rb +2 -3
  234. data/dist/lib/Ice/ReplyStatus.rb +2 -3
  235. data/dist/lib/Ice/Router.rb +1 -1
  236. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  237. data/dist/lib/Ice/SliceUtil.rb +2 -2
  238. data/dist/lib/Ice/Struct.rb +1 -0
  239. data/dist/lib/Ice/ToStringMode.rb +1 -2
  240. data/dist/lib/Ice/Value.rb +2 -2
  241. data/dist/lib/Ice/Version.rb +1 -1
  242. data/dist/lib/IceBox/ServiceManager.rb +1 -1
  243. data/dist/lib/IceGrid/Admin.rb +3 -4
  244. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  245. data/dist/lib/IceGrid/Exception.rb +1 -1
  246. data/dist/lib/IceGrid/FileParser.rb +1 -1
  247. data/dist/lib/IceGrid/Registry.rb +2 -3
  248. data/dist/lib/IceGrid/Session.rb +2 -2
  249. data/dist/lib/IceGrid/UserAccountMapper.rb +1 -1
  250. data/dist/lib/IceStorm/IceStorm.rb +1 -1
  251. data/dist/lib/IceStorm/Metrics.rb +1 -1
  252. data/extconf.rb +1 -1
  253. data/ice.gemspec +3 -3
  254. metadata +4 -5
  255. data/dist/ice/cpp/src/Ice/DLLMain.cpp +0 -40
  256. data/dist/ice/cpp/src/Ice/UndefSysMacros.h +0 -37
@@ -26,6 +26,7 @@
26
26
  #include <algorithm>
27
27
  #include <iomanip>
28
28
  #include <stdexcept>
29
+ #include <utility>
29
30
 
30
31
  #ifdef ICE_HAS_BZIP2
31
32
  # include <bzlib.h>
@@ -401,7 +402,11 @@ Ice::ConnectionI::startAsync(
401
402
  }
402
403
  catch (const Ice::LocalException&)
403
404
  {
404
- exception(current_exception());
405
+ {
406
+ std::lock_guard lock(_mutex);
407
+ setState(StateClosed, current_exception());
408
+ }
409
+
405
410
  if (connectionStartFailed)
406
411
  {
407
412
  connectionStartFailed(shared_from_this(), current_exception());
@@ -547,14 +552,14 @@ Ice::ConnectionI::close(function<void()> response, function<void(std::exception_
547
552
  {
548
553
  if (response)
549
554
  {
550
- response();
555
+ executeCallback(response);
551
556
  }
552
557
  }
553
558
  else
554
559
  {
555
560
  if (exception)
556
561
  {
557
- exception(closeException);
562
+ executeCallback([&] { exception(closeException); });
558
563
  }
559
564
  }
560
565
  }
@@ -572,30 +577,6 @@ Ice::ConnectionI::isActiveOrHolding() const
572
577
  return _state > StateNotValidated && _state < StateClosing;
573
578
  }
574
579
 
575
- bool
576
- Ice::ConnectionI::isFinished() const
577
- {
578
- //
579
- // We can use trylock here, because as long as there are still
580
- // threads operating in this connection object, connection
581
- // destruction is considered as not yet finished.
582
- //
583
- std::unique_lock<std::mutex> lock(_mutex, std::try_to_lock);
584
-
585
- if (!lock.owns_lock())
586
- {
587
- return false;
588
- }
589
-
590
- if (_state != StateFinished || _upcallCount != 0)
591
- {
592
- return false;
593
- }
594
-
595
- assert(_state == StateFinished);
596
- return true;
597
- }
598
-
599
580
  void
600
581
  Ice::ConnectionI::throwException() const
601
582
  {
@@ -662,7 +643,7 @@ Ice::ConnectionI::sendAsyncRequest(const OutgoingAsyncBasePtr& out, bool compres
662
643
 
663
644
  std::lock_guard lock(_mutex);
664
645
  //
665
- // If the exception is closed before we even have a chance
646
+ // If the connection is closed before we even have a chance
666
647
  // to send our request, we always try to send the request
667
648
  // again.
668
649
  //
@@ -783,18 +764,27 @@ Ice::ConnectionI::flushBatchRequestsAsync(
783
764
  void
784
765
  Ice::ConnectionI::setCloseCallback(CloseCallback callback)
785
766
  {
786
- std::lock_guard lock(_mutex);
787
- if (_state >= StateClosed)
767
+ // Holds the callback this call replaces, so that it is destroyed after the lock is released. Destroying a
768
+ // callback can run arbitrary user code - a language mapping may attach a finalizer to it - and that code can
769
+ // call back into this connection, which would deadlock on the non-recursive _mutex.
770
+ CloseCallback previous;
771
+
788
772
  {
789
- if (callback)
773
+ std::lock_guard lock(_mutex);
774
+ if (_state >= StateClosed)
790
775
  {
791
- auto self = shared_from_this();
792
- _threadPool->execute([self, callback = std::move(callback)]() { self->closeCallback(callback); }, self);
776
+ if (callback)
777
+ {
778
+ auto self = shared_from_this();
779
+ _threadPool->execute(
780
+ [self, callback = std::move(callback)]() { self->executeCallback(callback); },
781
+ self);
782
+ }
783
+ }
784
+ else
785
+ {
786
+ previous = std::exchange(_closeCallback, std::move(callback));
793
787
  }
794
- }
795
- else
796
- {
797
- _closeCallback = std::move(callback);
798
788
  }
799
789
  }
800
790
 
@@ -807,11 +797,17 @@ Ice::ConnectionI::disableInactivityCheck() noexcept
807
797
  }
808
798
 
809
799
  void
810
- Ice::ConnectionI::closeCallback(const CloseCallback& callback)
800
+ Ice::ConnectionI::executeCallback(const CloseCallback& callback) noexcept
801
+ {
802
+ executeCallback([self = shared_from_this(), &callback] { callback(self); });
803
+ }
804
+
805
+ void
806
+ Ice::ConnectionI::executeCallback(const std::function<void()>& callback) noexcept
811
807
  {
812
808
  try
813
809
  {
814
- callback(shared_from_this());
810
+ callback();
815
811
  }
816
812
  catch (const std::exception& ex)
817
813
  {
@@ -1595,7 +1591,7 @@ Ice::ConnectionI::finished(ThreadPoolCurrent& current, bool close)
1595
1591
  }
1596
1592
 
1597
1593
  // If there are no callbacks to call, we don't call ioCompleted() since we're not going to call code that will
1598
- // potentially block (this avoids promoting a new leader and unecessary thread creation, especially if this is
1594
+ // potentially block (this avoids promoting a new leader and unnecessary thread creation, especially if this is
1599
1595
  // called on shutdown).
1600
1596
  if (!_connectionStartCompleted && !_connectionStartFailed && _sendStreams.empty() && _asyncRequests.empty() &&
1601
1597
  !_closeCallback)
@@ -1791,14 +1787,14 @@ Ice::ConnectionI::finish(bool close)
1791
1787
  {
1792
1788
  if (pair.first)
1793
1789
  {
1794
- pair.first();
1790
+ executeCallback(pair.first);
1795
1791
  }
1796
1792
  }
1797
1793
  else
1798
1794
  {
1799
1795
  if (pair.second)
1800
1796
  {
1801
- pair.second(_exception);
1797
+ executeCallback([this, &pair] { pair.second(_exception); });
1802
1798
  }
1803
1799
  }
1804
1800
  }
@@ -1807,7 +1803,7 @@ Ice::ConnectionI::finish(bool close)
1807
1803
 
1808
1804
  if (_closeCallback)
1809
1805
  {
1810
- closeCallback(_closeCallback);
1806
+ executeCallback(_closeCallback);
1811
1807
  _closeCallback = nullptr;
1812
1808
  }
1813
1809
 
@@ -1870,17 +1866,19 @@ Ice::ConnectionI::setBufferSize(int32_t rcvSize, int32_t sndSize)
1870
1866
  {
1871
1867
  rethrow_exception(_exception);
1872
1868
  }
1873
- _transceiver->setBufferSize(rcvSize, sndSize);
1869
+ try
1870
+ {
1871
+ _transceiver->setBufferSize(rcvSize, sndSize);
1872
+ }
1873
+ catch (...)
1874
+ {
1875
+ // The failing call may have closed the socket, so close the connection as well.
1876
+ setState(StateClosed, current_exception());
1877
+ throw;
1878
+ }
1874
1879
  _info = nullptr; // Invalidate the cached connection info
1875
1880
  }
1876
1881
 
1877
- void
1878
- Ice::ConnectionI::exception(std::exception_ptr ex)
1879
- {
1880
- std::lock_guard lock(_mutex);
1881
- setState(StateClosed, ex);
1882
- }
1883
-
1884
1882
  Ice::ConnectionI::ConnectionI(
1885
1883
  CommunicatorPtr communicator,
1886
1884
  const InstancePtr& instance,
@@ -1889,7 +1887,7 @@ Ice::ConnectionI::ConnectionI(
1889
1887
  const EndpointIPtr& endpoint,
1890
1888
  const shared_ptr<ObjectAdapterI>& adapter,
1891
1889
  std::function<void(const ConnectionIPtr&)> removeFromFactory,
1892
- const ConnectionOptions& options) noexcept
1890
+ const ConnectionOptions& options)
1893
1891
  : _communicator(std::move(communicator)),
1894
1892
  _instance(instance),
1895
1893
  _transceiver(transceiver),
@@ -2180,7 +2178,7 @@ Ice::ConnectionI::setState(State state)
2180
2178
 
2181
2179
  //
2182
2180
  // Don't need to close now for connections so only close the transceiver
2183
- // if the selector request it.
2181
+ // if the selector requests it.
2184
2182
  //
2185
2183
  if (_threadPool->finish(shared_from_this(), false))
2186
2184
  {
@@ -2407,7 +2405,7 @@ Ice::ConnectionI::sendHeartbeat() noexcept
2407
2405
  }
2408
2406
 
2409
2407
  // We send a heartbeat to the peer to generate a "write" on the connection. This write in turns creates
2410
- // a read on the peer, and resets the peer's idle check timer. When _sendStream is not empty, there is
2408
+ // a read on the peer, and resets the peer's idle check timer. When _sendStreams is not empty, there is
2411
2409
  // already an outstanding write, so we don't need to send a heartbeat. It's possible the first message
2412
2410
  // of _sendStreams was already sent but not yet removed from _sendStreams: it means the last write
2413
2411
  // occurred very recently, which is good enough with respect to the idle check.
@@ -2442,74 +2440,71 @@ Ice::ConnectionI::sendResponse(OutgoingResponse response, uint8_t compress)
2442
2440
  {
2443
2441
  bool isTwoWay = !_endpoint->datagram() && response.current().requestId != 0;
2444
2442
 
2445
- bool finished = false;
2443
+ // We hold _mutex for the duration of this function, including the catch handler below; hence the lock is not
2444
+ // declared inside the try block.
2445
+ std::unique_lock lock(_mutex);
2446
+ assert(_state > StateNotValidated);
2447
+
2446
2448
  try
2447
2449
  {
2448
- std::unique_lock lock(_mutex);
2449
- assert(_state > StateNotValidated);
2450
+ bool finished = false;
2450
2451
 
2451
- try
2452
+ if (--_upcallCount == 0)
2452
2453
  {
2453
- if (--_upcallCount == 0)
2454
+ if (_state == StateFinished)
2454
2455
  {
2455
- if (_state == StateFinished)
2456
+ finished = true;
2457
+ if (_observer)
2456
2458
  {
2457
- finished = true;
2458
- if (_observer)
2459
- {
2460
- _observer.detach();
2461
- }
2459
+ _observer.detach();
2462
2460
  }
2463
- _conditionVariable.notify_all();
2464
2461
  }
2462
+ _conditionVariable.notify_all();
2463
+ }
2465
2464
 
2466
- if (_state >= StateClosed)
2467
- {
2468
- exception_ptr exception = _exception;
2469
- assert(exception);
2470
-
2471
- if (finished && _removeFromFactory)
2472
- {
2473
- lock.unlock();
2474
- _removeFromFactory(shared_from_this());
2475
- }
2476
-
2477
- rethrow_exception(exception);
2478
- }
2479
- assert(!finished);
2465
+ if (_state >= StateClosed)
2466
+ {
2467
+ // The connection is already closed (or finished): we can't send the response. There is nothing else to
2468
+ // do here since the connection's exception is already set.
2469
+ assert(_exception);
2480
2470
 
2481
- if (isTwoWay)
2471
+ if (finished && _removeFromFactory)
2482
2472
  {
2483
- OutgoingMessage message(&response.outputStream(), compress > 0);
2484
- sendMessage(message);
2473
+ lock.unlock();
2474
+ _removeFromFactory(shared_from_this());
2485
2475
  }
2486
2476
 
2487
- if (_state == StateActive && _maxDispatches > 0 && _dispatchCount == _maxDispatches)
2488
- {
2489
- // Resume reading if the connection is active and the dispatch count is about to be less than
2490
- // _maxDispatches.
2491
- _threadPool->update(shared_from_this(), SocketOperationNone, SocketOperationRead);
2492
- if (_idleTimeoutTransceiver)
2493
- {
2494
- _idleTimeoutTransceiver->enableIdleCheck();
2495
- }
2496
- }
2477
+ return;
2478
+ }
2479
+ assert(!finished);
2497
2480
 
2498
- --_dispatchCount;
2481
+ if (isTwoWay)
2482
+ {
2483
+ OutgoingMessage message(&response.outputStream(), compress > 0);
2484
+ sendMessage(message);
2485
+ }
2499
2486
 
2500
- if (_state == StateClosing && _upcallCount == 0)
2487
+ if (_state == StateActive && _maxDispatches > 0 && _dispatchCount == _maxDispatches)
2488
+ {
2489
+ // Resume reading if the connection is active and the dispatch count is about to be less than
2490
+ // _maxDispatches.
2491
+ _threadPool->update(shared_from_this(), SocketOperationNone, SocketOperationRead);
2492
+ if (_idleTimeoutTransceiver)
2501
2493
  {
2502
- initiateShutdown();
2494
+ _idleTimeoutTransceiver->enableIdleCheck();
2503
2495
  }
2504
2496
  }
2505
- catch (const LocalException&)
2497
+
2498
+ --_dispatchCount;
2499
+
2500
+ if (_state == StateClosing && _upcallCount == 0)
2506
2501
  {
2507
- setState(StateClosed, current_exception());
2502
+ initiateShutdown();
2508
2503
  }
2509
2504
  }
2510
2505
  catch (...)
2511
2506
  {
2512
- dispatchException(current_exception(), 1);
2507
+ setState(StateClosed, current_exception());
2513
2508
  }
2514
2509
  }
2515
2510
 
@@ -146,7 +146,6 @@ namespace Ice
146
146
  void close(std::function<void()> response, std::function<void(std::exception_ptr)> exception) noexcept final;
147
147
 
148
148
  [[nodiscard]] bool isActiveOrHolding() const;
149
- [[nodiscard]] bool isFinished() const;
150
149
 
151
150
  void throwException() const final; // From Connection. Throws the connection exception if destroyed.
152
151
 
@@ -209,8 +208,6 @@ namespace Ice
209
208
 
210
209
  void setBufferSize(std::int32_t rcvSize, std::int32_t sndSize) final; // From Connection
211
210
 
212
- void exception(std::exception_ptr);
213
-
214
211
  // This method is called to execute user code (connection start completion callback, invocation sent callbacks,
215
212
  // or an upcall issued from an incoming message). The invocation sent callbacks and the message upcall might
216
213
  // both be set.
@@ -221,7 +218,13 @@ namespace Ice
221
218
  InputStream& messageStream);
222
219
  void finish(bool);
223
220
 
224
- void closeCallback(const CloseCallback&);
221
+ // Executes a callback provided by the application, catching and logging any exception it throws.
222
+ void executeCallback(const CloseCallback& callback) noexcept;
223
+ void executeCallback(const std::function<void()>& callback) noexcept;
224
+
225
+ /// Gets the thread pool that services this connection: the client thread pool for an outgoing connection,
226
+ /// and the object adapter's thread pool for an incoming connection.
227
+ [[nodiscard]] const IceInternal::ThreadPoolPtr& getThreadPool() const noexcept { return _threadPool; }
225
228
 
226
229
  /// Aborts the connection with a ConnectionAbortedException if the connection is active and did not receive
227
230
  /// a byte for some time. See the IdleTimeoutTransceiverDecorator.
@@ -250,7 +253,7 @@ namespace Ice
250
253
  const IceInternal::EndpointIPtr&,
251
254
  const std::shared_ptr<ObjectAdapterI>&,
252
255
  std::function<void(const ConnectionIPtr&)>,
253
- const ConnectionOptions&) noexcept;
256
+ const ConnectionOptions&);
254
257
 
255
258
  static ConnectionIPtr create(
256
259
  const Ice::CommunicatorPtr&,
@@ -289,12 +292,12 @@ namespace Ice
289
292
  bool validate(IceInternal::SocketOperation = IceInternal::SocketOperationNone);
290
293
 
291
294
  /// Sends the next queued messages. This method is called by message() once the message which is being sent
292
- /// (_sendStreams.First) is fully sent. Before sending the next message, this message is removed from
293
- /// _sendsStream. If any, its sent callback is also queued in given callback queue.
295
+ /// (_sendStreams.front()) is fully sent. Before sending the next message, this message is removed from
296
+ /// _sendStreams. If any, its sent callback is also queued in given callback queue.
294
297
  ///
295
298
  /// @param callbacks The sent callbacks to call for the messages that were sent.
296
299
  /// @return The socket operation to register with the thread pool's selector to send the remainder of the
297
- /// pending message being sent (_sendStreams.First).
300
+ /// pending message being sent (_sendStreams.front()).
298
301
  IceInternal::SocketOperation sendNextMessages(std::vector<OutgoingMessage>& callbacks);
299
302
 
300
303
  /// Sends or queues the given message.
@@ -16,7 +16,7 @@ using namespace std;
16
16
  namespace
17
17
  {
18
18
  mutex consoleMutex;
19
- // We leak consoleUtil object to ensure that is available during static destruction.
19
+ // We leak consoleUtil object to ensure that it is available during static destruction.
20
20
  ConsoleUtil* consoleUtil = 0;
21
21
  }
22
22
 
@@ -52,25 +52,21 @@ IceInternal::DefaultsAndOverrides::DefaultsAndOverrides(const PropertiesPtr& pro
52
52
  throw ParseException(__FILE__, __LINE__, "illegal value '" + value + "'; expected 'Random' or 'Ordered'");
53
53
  }
54
54
 
55
- const_cast<chrono::milliseconds&>(defaultInvocationTimeout) =
56
- chrono::milliseconds(properties->getIcePropertyAsInt("Ice.Default.InvocationTimeout"));
57
- if (defaultInvocationTimeout.count() < 1 && defaultInvocationTimeout.count() != -1)
55
+ auto invocationTimeout = chrono::milliseconds(properties->getIcePropertyAsInt("Ice.Default.InvocationTimeout"));
56
+ if (invocationTimeout <= chrono::milliseconds::zero())
58
57
  {
59
- throw InitializationException{
60
- __FILE__,
61
- __LINE__,
62
- "invalid value for Ice.Default.InvocationTimeout: " + to_string(defaultInvocationTimeout.count())};
58
+ // Zero or any negative timeout means infinite and is normalized to -1.
59
+ invocationTimeout = chrono::milliseconds(-1);
63
60
  }
61
+ const_cast<chrono::milliseconds&>(defaultInvocationTimeout) = invocationTimeout;
64
62
 
65
- const_cast<chrono::seconds&>(defaultLocatorCacheTimeout) =
66
- chrono::seconds(properties->getIcePropertyAsInt("Ice.Default.LocatorCacheTimeout"));
67
- if (defaultLocatorCacheTimeout.count() < -1)
63
+ auto locatorCacheTimeout = chrono::seconds(properties->getIcePropertyAsInt("Ice.Default.LocatorCacheTimeout"));
64
+ if (locatorCacheTimeout < chrono::seconds::zero())
68
65
  {
69
- throw InitializationException{
70
- __FILE__,
71
- __LINE__,
72
- "invalid value for Ice.Default.LocatorCacheTimeout: " + to_string(defaultLocatorCacheTimeout.count())};
66
+ // Any negative timeout means infinite and is normalized to -1; 0 means no caching.
67
+ locatorCacheTimeout = chrono::seconds(-1);
73
68
  }
69
+ const_cast<chrono::seconds&>(defaultLocatorCacheTimeout) = locatorCacheTimeout;
74
70
 
75
71
  value = properties->getIceProperty("Ice.Default.EncodingVersion");
76
72
  defaultEncoding = stringToEncodingVersion(value);
@@ -64,7 +64,7 @@ namespace IceInternal
64
64
  [[nodiscard]] virtual EndpointIPtr connectionId(const std::string&) const = 0;
65
65
 
66
66
  //
67
- // Return true if the endpoints support bzip2 compress, or false
67
+ // Return true if the endpoint supports bzip2 compression, or false
68
68
  // otherwise.
69
69
  //
70
70
  [[nodiscard]] virtual bool compress() const = 0;
@@ -38,8 +38,8 @@ IceInternal::isAbsolutePath(const string& path)
38
38
  }
39
39
 
40
40
  #ifdef _WIN32
41
- // We need at least 3 non whitespace character to have
42
- // and absolute path
41
+ // We need at least 3 non whitespace characters to have
42
+ // an absolute path
43
43
  if (i + 3 > size)
44
44
  {
45
45
  return false;
@@ -199,7 +199,7 @@ int
199
199
  IceInternal::getcwd(string& cwd)
200
200
  {
201
201
  //
202
- // Don't need to use a wide string converter, the wide string come
202
+ // Don't need to use a wide string converter, the wide string comes
203
203
  // from Windows API.
204
204
  //
205
205
  wchar_t cwdbuf[_MAX_PATH];
@@ -242,19 +242,19 @@ IceInternal::FileLock::FileLock(const std::string& path) : _path(path)
242
242
  throw FileLockException(__FILE__, __LINE__, GetLastError(), _path);
243
243
  }
244
244
 
245
- OVERLAPPED overlaped;
246
- overlaped.Internal = 0;
247
- overlaped.InternalHigh = 0;
248
- overlaped.Offset = 0;
249
- overlaped.OffsetHigh = 0;
245
+ OVERLAPPED overlapped;
246
+ overlapped.Internal = 0;
247
+ overlapped.InternalHigh = 0;
248
+ overlapped.Offset = 0;
249
+ overlapped.OffsetHigh = 0;
250
250
 
251
251
  # if defined(_MSC_VER)
252
- overlaped.hEvent = nullptr;
252
+ overlapped.hEvent = nullptr;
253
253
  # else
254
- overlaped.hEvent = 0;
254
+ overlapped.hEvent = 0;
255
255
  # endif
256
256
 
257
- if (::LockFileEx(_fd, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlaped) == 0)
257
+ if (::LockFileEx(_fd, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, 0, 0, &overlapped) == 0)
258
258
  {
259
259
  ::CloseHandle(_fd);
260
260
  throw FileLockException(__FILE__, __LINE__, GetLastError(), _path);
@@ -363,7 +363,7 @@ IceInternal::FileLock::FileLock(const std::string& path) : _path(path)
363
363
  //
364
364
 
365
365
  //
366
- // Now that we have acquire an exclusive write lock,
366
+ // Now that we have acquired an exclusive write lock,
367
367
  // write the process pid there.
368
368
  //
369
369
  ostringstream os;
@@ -28,7 +28,7 @@ FixedRequestHandler::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync,
28
28
  }
29
29
 
30
30
  Ice::ConnectionIPtr
31
- FixedRequestHandler::getConnection()
31
+ FixedRequestHandler::getConnection() noexcept
32
32
  {
33
33
  return _connection;
34
34
  }
@@ -18,7 +18,7 @@ namespace IceInternal
18
18
 
19
19
  void asyncRequestCanceled(const OutgoingAsyncBasePtr&, std::exception_ptr) final;
20
20
 
21
- Ice::ConnectionIPtr getConnection() final;
21
+ Ice::ConnectionIPtr getConnection() noexcept final;
22
22
 
23
23
  private:
24
24
  Ice::ConnectionIPtr _connection;
@@ -12,8 +12,6 @@
12
12
 
13
13
  namespace IceInternal
14
14
  {
15
- std::vector<unsigned char> calcSHA1(const std::vector<unsigned char>&);
16
-
17
15
  using HeaderFields = std::map<std::string, std::pair<std::string, std::string>>;
18
16
 
19
17
  class WebSocketException
@@ -70,15 +70,18 @@ IdleTimeoutTransceiverDecorator::initialize(Buffer& readBuffer, Buffer& writeBuf
70
70
 
71
71
  IdleTimeoutTransceiverDecorator::~IdleTimeoutTransceiverDecorator()
72
72
  {
73
- // Since ConnectionI is noexcept, decoratorInit always sets _heartbeatTimerTask.
74
- assert(_heartbeatTimerTask);
75
- _timer->cancel(_heartbeatTimerTask);
73
+ // _heartbeatTimerTask remains null when the connection creation fails before decoratorInit is called.
74
+ if (_heartbeatTimerTask)
75
+ {
76
+ _timer->cancel(_heartbeatTimerTask);
77
+ }
76
78
  disableIdleCheck();
77
79
  }
78
80
 
79
81
  void
80
82
  IdleTimeoutTransceiverDecorator::close()
81
83
  {
84
+ assert(_heartbeatTimerTask); // close is only called on a connection that completed decoratorInit.
82
85
  _timer->cancel(_heartbeatTimerTask);
83
86
  disableIdleCheck();
84
87
  _decoratee->close();
@@ -38,9 +38,7 @@ IncomingRequest::IncomingRequest(
38
38
 
39
39
  inputStream.read(_current.operation, false);
40
40
 
41
- uint8_t mode;
42
- inputStream.read(mode);
43
- _current.mode = static_cast<OperationMode>(mode);
41
+ inputStream.read(_current.mode);
44
42
 
45
43
  int32_t sz = inputStream.readSize();
46
44
  while (sz--)