amps-python-client 5.3.4.1__zip
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.
- amps-python-client-5.3.4.1/HISTORY +7 -0
- amps-python-client-5.3.4.1/LICENSE +157 -0
- amps-python-client-5.3.4.1/PKG-INFO +112 -0
- amps-python-client-5.3.4.1/README.md +96 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/ack-messages.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/content-messages.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/intro.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/logon.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/protocol-reference.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/publishing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/query-delimiters.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/query-subscribe.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/removing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/ack-messages.rst.txt +32 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/content-messages.rst.txt +27 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/intro.rst.txt +43 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/logon.rst.txt +231 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/protocol-reference.rst.txt +1474 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/publishing.rst.txt +25 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/query-delimiters.rst.txt +12 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/query-subscribe.rst.txt +23 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/removing.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/chapters/utilities.rst.txt +13 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_sources/index.rst.txt +56 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/ack-messages.html +417 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/content-messages.html +417 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/intro.html +126 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/logon.html +295 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/protocol-reference.html +1190 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/publishing.html +436 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/query-delimiters.html +173 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/query-subscribe.html +2123 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/removing.html +299 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/chapters/utilities.html +287 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/genindex.html +97 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/index.html +138 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/command-reference/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/html/_sources/code.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/html/_sources/index.rst.txt +29 -0
- amps-python-client-5.3.4.1/docs/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/html/_static/classic.css +261 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/default.css +1 -0
- amps-python-client-5.3.4.1/docs/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/html/_static/sidebar.js +159 -0
- amps-python-client-5.3.4.1/docs/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/html/code.html +6503 -0
- amps-python-client-5.3.4.1/docs/html/genindex.html +1361 -0
- amps-python-client-5.3.4.1/docs/html/index.html +131 -0
- amps-python-client-5.3.4.1/docs/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/html/py-modindex.html +111 -0
- amps-python-client-5.3.4.1/docs/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/advanced-topics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/cpp-compiler-list.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/cpp-feature-table.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/creating-commands.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/deltas.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/error-handling.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/exceptions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/first-program.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/high-availability.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/installing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/introduction.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/moving-from-python-lite.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/performance-tips.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/queues.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/sow.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/subscriptions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/python/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/caution.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/connection_string.svg +461 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/important.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/important.svg +25 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/tip.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/tip.svg +31 -0
- amps-python-client-5.3.4.1/docs/python/html/_images/warning.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/advanced-topics.rst.txt +398 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/cpp-compiler-list.rst.txt +6 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/cpp-feature-table.rst.txt +26 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/creating-commands.rst.txt +159 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/deltas.rst.txt +79 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/error-handling.rst.txt +482 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/exceptions.rst.txt +128 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/first-program.rst.txt +142 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/high-availability.rst.txt +876 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/installing.rst.txt +184 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/introduction.rst.txt +50 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/moving-from-python-lite.rst.txt +32 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/performance-tips.rst.txt +434 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/queues.rst.txt +282 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/sow.rst.txt +292 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/subscriptions.rst.txt +374 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/chapters/utilities.rst.txt +214 -0
- amps-python-client-5.3.4.1/docs/python/html/_sources/index.rst.txt +44 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/python/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/advanced-topics.html +447 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/cpp-compiler-list.html +92 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/cpp-feature-table.html +156 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/creating-commands.html +2837 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/deltas.html +169 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/error-handling.html +746 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/exceptions.html +272 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/first-program.html +499 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/high-availability.html +1014 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/installing.html +264 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/introduction.html +245 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/moving-from-python-lite.html +118 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/performance-tips.html +499 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/queues.html +352 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/sow.html +381 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/subscriptions.html +535 -0
- amps-python-client-5.3.4.1/docs/python/html/chapters/utilities.html +302 -0
- amps-python-client-5.3.4.1/docs/python/html/genindex.html +351 -0
- amps-python-client-5.3.4.1/docs/python/html/index.html +380 -0
- amps-python-client-5.3.4.1/docs/python/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/python/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/python/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/chapters/crankitup.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/chapters/equipment.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/chapters/crankitup.rst.txt +155 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/chapters/equipment.rst.txt +19 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_sources/index.rst.txt +20 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/alabaster.css +699 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/chapters/crankitup.html +271 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/chapters/equipment.html +105 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/genindex.html +97 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/index.html +382 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/search.html +107 -0
- amps-python-client-5.3.4.1/docs/python-quickstart/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/docs/resources/custom.css +9 -0
- amps-python-client-5.3.4.1/docs/resources/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/acks.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/actions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps-statistics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps_expressions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/amps_functions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/auxiliary_modules.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/config-file-shortcuts.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/conflated_topics.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/constructing-fields.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/daemon.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/delta.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/distribution.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/enrichment.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/events.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/file_format_versions.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/glossary.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/ha.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/installing_and_starting.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/intro.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/logging.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/messageTypes.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/monitoring.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/oof.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/operation.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/pub_sub.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/queues.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/replication.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/securing.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/sow.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/sow_queries.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/spark.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/transports.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/troubleshooting.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/txlog.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/usecases.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/utilities.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/chapters/views.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/environment.pickle +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/doctrees/index.doctree +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/.buildinfo +4 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/AMPS-Queues-Intro.svg +1330 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/GeoRepl.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/HA_async_ack.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/HA_sync_ack.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/Hot-Hot-Replication.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/MessageOrdering.svg +235 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF5.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF6.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF7.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/OOF8.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/PubSub1.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/PubSub2.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWAndSubscribeAndReplace.svg +684 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWQuery1.svg +402 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/SOWQuery2.svg +505 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig1.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig2.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig3.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/UseCaseFig4.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/caution.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/caution.svg +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/chicago_group.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/delta_original_messages.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/delta_update_message.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/important.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/important.svg +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/inline_view_conflation.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/paginated_subs_pub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/paginated_subs_sub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/queue_usage_overview.svg +627 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/replication_hub.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/replication_scenario_with_ha.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_overview_1.svg +248 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_overview_2.svg +183 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/sow_update_sequence.svg +1 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/tip.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/tip.svg +31 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/warning.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_images/warning.svg +23 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/acks.rst.txt +232 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/actions.rst.txt +111 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps-statistics.rst.txt +358 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps_expressions.rst.txt +83 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/amps_functions.rst.txt +11 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/auxiliary_modules.rst.txt +86 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/config-file-shortcuts.rst.txt +9 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/conflated_topics.rst.txt +111 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/constructing-fields.rst.txt +269 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/daemon.rst.txt +232 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/delta.rst.txt +556 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/distribution.rst.txt +186 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/enrichment.rst.txt +191 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/events.rst.txt +39 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/file_format_versions.rst.txt +203 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/glossary.rst.txt +101 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/ha.rst.txt +465 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/installing_and_starting.rst.txt +23 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/intro.rst.txt +116 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/logging.rst.txt +34 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/messageTypes.rst.txt +1398 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/monitoring.rst.txt +326 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/oof.rst.txt +312 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/operation.rst.txt +27 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/pub_sub.rst.txt +49 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/queues.rst.txt +1351 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/replication.rst.txt +1228 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/securing.rst.txt +657 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/sow.rst.txt +57 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/sow_queries.rst.txt +25 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/spark.rst.txt +824 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/transports.rst.txt +291 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/troubleshooting.rst.txt +517 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/txlog.rst.txt +62 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/usecases.rst.txt +21 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/utilities.rst.txt +62 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/chapters/views.rst.txt +175 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_sources/index.rst.txt +110 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/ajax-loader.gif +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/alabaster.css +695 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/basic.css +632 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment-bright.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment-close.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/comment.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/custom.css +192 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/custom.css.backup +161 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/doctools.js +287 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/down-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/down.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/file.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/flag_logo.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/flag_logo.svg +153 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/jquery-3.1.0.js +10074 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/jquery.js +4 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/minus.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/plus.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/pygments.css +74 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/searchtools.js +758 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/underscore-1.3.1.js +999 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/underscore.js +31 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/up-pressed.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/up.png +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/_static/websupport.js +808 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/acks.html +289 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/actions.html +3782 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps-statistics.html +439 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps_expressions.html +1552 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/amps_functions.html +1626 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/auxiliary_modules.html +2548 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/config-file-shortcuts.html +508 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/conflated_topics.html +328 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/constructing-fields.html +447 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/daemon.html +295 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/delta.html +609 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/distribution.html +246 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/enrichment.html +264 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/events.html +449 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/file_format_versions.html +229 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/glossary.html +215 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/ha.html +978 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/installing_and_starting.html +357 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/intro.html +572 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/logging.html +972 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/messageTypes.html +1280 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/monitoring.html +718 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/oof.html +341 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/operation.html +1515 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/pub_sub.html +934 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/queues.html +1767 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/replication.html +1777 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/securing.html +697 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/sow.html +1038 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/sow_queries.html +621 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/spark.html +819 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/transports.html +352 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/troubleshooting.html +530 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/txlog.html +1013 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/usecases.html +288 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/utilities.html +133 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/chapters/views.html +1120 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/genindex.html +1261 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/index.html +163 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/objects.inv +0 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/search.html +106 -0
- amps-python-client-5.3.4.1/docs/user-guide/html/searchindex.js +1 -0
- amps-python-client-5.3.4.1/include/ampspy_bookmarkstore.hpp +63 -0
- amps-python-client-5.3.4.1/include/ampspy_compat.h +63 -0
- amps-python-client-5.3.4.1/include/ampspy_defs.hpp +181 -0
- amps-python-client-5.3.4.1/include/ampspy_recoverypointadapter.hpp +52 -0
- amps-python-client-5.3.4.1/include/ampspy_shims.hpp +113 -0
- amps-python-client-5.3.4.1/include/ampspy_type_object.hpp +242 -0
- amps-python-client-5.3.4.1/include/ampspy_types.hpp +1139 -0
- amps-python-client-5.3.4.1/include/ampspyver.h +30 -0
- amps-python-client-5.3.4.1/index.html +66 -0
- amps-python-client-5.3.4.1/samples/AMPSConsolePublisher.py +59 -0
- amps-python-client-5.3.4.1/samples/AMPSConsoleSubscriber.py +63 -0
- amps-python-client-5.3.4.1/samples/AMPSFIXBuilderPublisher.py +71 -0
- amps-python-client-5.3.4.1/samples/AMPSFIXShredderSubscriber.py +69 -0
- amps-python-client-5.3.4.1/samples/AMPSNVFIXBuilderPublisher.py +71 -0
- amps-python-client-5.3.4.1/samples/AMPSNVFIXShredderSubscriber.py +67 -0
- amps-python-client-5.3.4.1/samples/AMPSPublishForReplay.py +81 -0
- amps-python-client-5.3.4.1/samples/AMPSQueueConsumer.py +69 -0
- amps-python-client-5.3.4.1/samples/AMPSQueuePublisher.py +59 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWConsolePublisher.py +67 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWConsoleSubscriber.py +77 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWandSubscribeConsoleSubscriber.py +79 -0
- amps-python-client-5.3.4.1/samples/AMPSSOWandSubscribeWithOOF.py +108 -0
- amps-python-client-5.3.4.1/samples/AMPSSubscribeForReplay.py +128 -0
- amps-python-client-5.3.4.1/samples/AMPSUpdateForOOF.py +123 -0
- amps-python-client-5.3.4.1/samples/CompositeMessagePublisher.py +84 -0
- amps-python-client-5.3.4.1/samples/CompositeMessageSubscriber.py +87 -0
- amps-python-client-5.3.4.1/samples/RandomServerChooser.py +41 -0
- amps-python-client-5.3.4.1/samples/sample.xml +335 -0
- amps-python-client-5.3.4.1/setup.py +209 -0
- amps-python-client-5.3.4.1/setup_amps.py +94 -0
- amps-python-client-5.3.4.1/src/ampspy_shims.cpp +203 -0
- amps-python-client-5.3.4.1/src/ampspy_type_object.cpp +484 -0
- amps-python-client-5.3.4.1/src/authenticator.cpp +128 -0
- amps-python-client-5.3.4.1/src/bookmarkstore.cpp +238 -0
- amps-python-client-5.3.4.1/src/client.cpp +2430 -0
- amps-python-client-5.3.4.1/src/client_docs.h +956 -0
- amps-python-client-5.3.4.1/src/cmessagehandler.cpp +151 -0
- amps-python-client-5.3.4.1/src/command.cpp +164 -0
- amps-python-client-5.3.4.1/src/command_docs.h +194 -0
- amps-python-client-5.3.4.1/src/compositemessagebuilder.cpp +111 -0
- amps-python-client-5.3.4.1/src/compositemessageparser.cpp +146 -0
- amps-python-client-5.3.4.1/src/conflatingrecoverypointadapter.cpp +194 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BlockPublishStore.hpp +2053 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BlockStore.hpp +677 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/BookmarkStore.hpp +542 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Buffer.hpp +214 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/CompositeMessageBuilder.hpp +174 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/CompositeMessageParser.hpp +151 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/DefaultServerChooser.hpp +162 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Field.hpp +719 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HAClient.hpp +370 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HAClientImpl.hpp +460 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/HybridPublishStore.hpp +481 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/LoggedBookmarkStore.hpp +1255 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MMapBookmarkStore.hpp +1283 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MMapStoreBuffer.hpp +290 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryBookmarkStore.hpp +1622 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryPublishStore.hpp +66 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemoryStoreBuffer.hpp +244 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MemorySubscriptionManager.hpp +850 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/Message.hpp +1819 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/MessageRouter.hpp +618 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/PublishStore.hpp +158 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ReconnectDelayStrategy.hpp +106 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ReconnectDelayStrategyImpl.hpp +317 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RecoveryPoint.hpp +323 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RecoveryPointAdapter.hpp +501 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/RingBookmarkStore.hpp +669 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/SOWRecoveryPointAdapter.hpp +490 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ServerChooser.hpp +145 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ServerChooserImpl.hpp +95 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps.h +775 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_generated.h +46 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_impl.h +204 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/amps_ssl.h +78 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampscrc.hpp +210 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsplusplus.hpp +8817 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsuri.h +84 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsver.h +41 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/ampsver.h.in +41 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/constants.hpp +194 -0
- amps-python-client-5.3.4.1/src/cpp/include/amps/util.hpp +1692 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_protocol.c +688 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_protocol_generated.h +80 -0
- amps-python-client-5.3.4.1/src/cpp/src/amps_ssl.c +489 -0
- amps-python-client-5.3.4.1/src/cpp/src/atfork.c +446 -0
- amps-python-client-5.3.4.1/src/cpp/src/client.c +483 -0
- amps-python-client-5.3.4.1/src/cpp/src/makefile +92 -0
- amps-python-client-5.3.4.1/src/cpp/src/message.c +837 -0
- amps-python-client-5.3.4.1/src/cpp/src/message_generated.h +611 -0
- amps-python-client-5.3.4.1/src/cpp/src/tcp.c +1489 -0
- amps-python-client-5.3.4.1/src/cpp/src/tcps.c +1894 -0
- amps-python-client-5.3.4.1/src/cpp/src/transports.c +123 -0
- amps-python-client-5.3.4.1/src/cpp/src/unix.c +984 -0
- amps-python-client-5.3.4.1/src/cpp/src/uri.c +301 -0
- amps-python-client-5.3.4.1/src/exponentialdelaystrategy.cpp +137 -0
- amps-python-client-5.3.4.1/src/failedwritehandler.cpp +116 -0
- amps-python-client-5.3.4.1/src/fixbuilder.cpp +146 -0
- amps-python-client-5.3.4.1/src/fixeddelaystrategy.cpp +114 -0
- amps-python-client-5.3.4.1/src/fixshredder.cpp +105 -0
- amps-python-client-5.3.4.1/src/fixshredder_docs.h +38 -0
- amps-python-client-5.3.4.1/src/haclient.cpp +691 -0
- amps-python-client-5.3.4.1/src/haclient_docs.h +132 -0
- amps-python-client-5.3.4.1/src/hybridpublishstore.cpp +137 -0
- amps-python-client-5.3.4.1/src/hybridpublishstore_docs.h +31 -0
- amps-python-client-5.3.4.1/src/memorybookmarkstore.cpp +373 -0
- amps-python-client-5.3.4.1/src/memorybookmarkstore_docs.h +39 -0
- amps-python-client-5.3.4.1/src/memorypublishstore.cpp +160 -0
- amps-python-client-5.3.4.1/src/memorypublishstore_docs.h +32 -0
- amps-python-client-5.3.4.1/src/message.cpp +765 -0
- amps-python-client-5.3.4.1/src/message_docs.h +306 -0
- amps-python-client-5.3.4.1/src/messagestream.cpp +623 -0
- amps-python-client-5.3.4.1/src/messagestream_docs.h +45 -0
- amps-python-client-5.3.4.1/src/mmapbookmarkstore.cpp +422 -0
- amps-python-client-5.3.4.1/src/nvfixbuilder.cpp +160 -0
- amps-python-client-5.3.4.1/src/nvfixbuilder_docs.h +33 -0
- amps-python-client-5.3.4.1/src/nvfixshredder.cpp +99 -0
- amps-python-client-5.3.4.1/src/nvfixshredder_docs.h +39 -0
- amps-python-client-5.3.4.1/src/publishstore.cpp +183 -0
- amps-python-client-5.3.4.1/src/raw_wrapper.cpp +756 -0
- amps-python-client-5.3.4.1/src/reason.cpp +71 -0
- amps-python-client-5.3.4.1/src/recoverypoint.cpp +135 -0
- amps-python-client-5.3.4.1/src/recoverypointadapter.cpp +171 -0
- amps-python-client-5.3.4.1/src/ringbookmarkstore.cpp +360 -0
- amps-python-client-5.3.4.1/src/serverchooser.cpp +245 -0
- amps-python-client-5.3.4.1/src/serverchooser_docs.h +39 -0
- amps-python-client-5.3.4.1/src/sowrecoverypointadapter.cpp +248 -0
- amps-python-client-5.3.4.1/src/store.cpp +62 -0
- amps-python-client-5.3.4.1/src/versioninfo.cpp +175 -0
|
@@ -0,0 +1,1489 @@
|
|
|
1
|
+
/*//////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2010-2023 60East Technologies Inc., All Rights Reserved.
|
|
4
|
+
//
|
|
5
|
+
// This computer software is owned by 60East Technologies Inc. and is
|
|
6
|
+
// protected by U.S. copyright laws and other laws and by international
|
|
7
|
+
// treaties. This computer software is furnished by 60East Technologies
|
|
8
|
+
// Inc. pursuant to a written license agreement and may be used, copied,
|
|
9
|
+
// transmitted, and stored only in accordance with the terms of such
|
|
10
|
+
// license agreement and with the inclusion of the above copyright notice.
|
|
11
|
+
// This computer software or any other copies thereof may not be provided
|
|
12
|
+
// or otherwise made available to any other person.
|
|
13
|
+
//
|
|
14
|
+
// U.S. Government Restricted Rights. This computer software: (a) was
|
|
15
|
+
// developed at private expense and is in all respects the proprietary
|
|
16
|
+
// information of 60East Technologies Inc.; (b) was not developed with
|
|
17
|
+
// government funds; (c) is a trade secret of 60East Technologies Inc.
|
|
18
|
+
// for all purposes of the Freedom of Information Act; and (d) is a
|
|
19
|
+
// commercial item and thus, pursuant to Section 12.212 of the Federal
|
|
20
|
+
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
|
|
21
|
+
// Government's use, duplication or disclosure of the computer software
|
|
22
|
+
// is subject to the restrictions set forth by 60East Technologies Inc..
|
|
23
|
+
//
|
|
24
|
+
///////////////////////////////////////////////////////////////////////// */
|
|
25
|
+
#if _MSC_VER < 1400
|
|
26
|
+
/*support for visual c++ 2003 */
|
|
27
|
+
#define _WIN32_WINNT 0x0400
|
|
28
|
+
#endif
|
|
29
|
+
#include <amps/amps_impl.h>
|
|
30
|
+
#include <amps/ampsuri.h>
|
|
31
|
+
#include <stdarg.h>
|
|
32
|
+
#include <sys/types.h>
|
|
33
|
+
|
|
34
|
+
#if __STDC_VERSION__ >= 201100
|
|
35
|
+
#include <stdatomic.h>
|
|
36
|
+
#include <stdbool.h>
|
|
37
|
+
#define AMPS_IEX(ptr, value) atomic_exchange_explicit((ptr), (value), memory_order_acq_rel)
|
|
38
|
+
#define AMPS_IEX_GET(ptr, value) atomic_exchange_explicit((ptr), (value), memory_order_acq_rel)
|
|
39
|
+
#define AMPS_IEX_LONG(ptr, value) atomic_exchange_explicit((ptr), (value), memory_order_acq_rel)
|
|
40
|
+
#define AMPS_FETCH_ADD(ptr, value) atomic_fetch_add_explicit((ptr), (value), memory_order_acq_rel)
|
|
41
|
+
#define AMPS_FETCH_SUB(ptr, value) atomic_fetch_sub_explicit((ptr), (value), memory_order_acq_rel)
|
|
42
|
+
#elif defined(_WIN32)
|
|
43
|
+
#ifdef _WIN64
|
|
44
|
+
#define AMPS_IEX(ptr,value) _InterlockedExchange64((LONG64*)(ptr), (LONG64)(value))
|
|
45
|
+
#define AMPS_IEX_GET(ptr,value) _InterlockedExchange64((LONG64*)(ptr), (LONG64)(value))
|
|
46
|
+
#define AMPS_IEX_LONG(ptr,value) _InterlockedExchange((ptr), (value))
|
|
47
|
+
#define AMPS_FETCH_ADD(ptr, value) InterlockedExchangeAdd64((LONGLONG volatile*)(ptr), (LONGLONG)(value))
|
|
48
|
+
#define AMPS_FETCH_SUB(ptr, value) InterlockedExchangeAdd64((LONGLONG volatile*)(ptr), (LONGLONG)(-1 * (value)))
|
|
49
|
+
#else
|
|
50
|
+
#define AMPS_IEX(ptr,value) _InterlockedExchange((long*)(ptr), (LONG)(value))
|
|
51
|
+
#define AMPS_IEX_GET(ptr,value) _InterlockedExchange((long*)(ptr), (LONG)(value))
|
|
52
|
+
#define AMPS_IEX_LONG(ptr,value) _InterlockedExchange((ptr), (LONG)(value))
|
|
53
|
+
#define AMPS_FETCH_ADD(ptr, value) InterlockedExchangeAdd((LONG volatile*)(ptr), (LONG)(value))
|
|
54
|
+
#define AMPS_FETCH_SUB(ptr, value) InterlockedExchangeAdd((LONG volatile*)(ptr), (LONG)(-1 * (value)))
|
|
55
|
+
#endif
|
|
56
|
+
#else
|
|
57
|
+
#define AMPS_IEX(ptr, value) (void)__sync_lock_test_and_set((ptr), (value))
|
|
58
|
+
#define AMPS_IEX_GET(ptr, value) __sync_lock_test_and_set((ptr), (value))
|
|
59
|
+
#define AMPS_IEX_LONG(ptr, value) (void)__sync_lock_test_and_set((ptr), (value))
|
|
60
|
+
#define AMPS_FETCH_ADD(ptr, value) __sync_fetch_and_add((ptr), (value))
|
|
61
|
+
#define AMPS_FETCH_SUB(ptr, value) __sync_fetch_and_sub((ptr), (value))
|
|
62
|
+
#endif
|
|
63
|
+
|
|
64
|
+
#ifdef _WIN32
|
|
65
|
+
|
|
66
|
+
/* Causes linked programs to add ws2_32.lib which is required by
|
|
67
|
+
* this module. If you'd like to turn this off, define the macro
|
|
68
|
+
* AMPS_WINDOWS_NO_DEFAULT_LIBS.
|
|
69
|
+
*/
|
|
70
|
+
#ifndef AMPS_WINDOWS_NO_DEFAULT_LIBS
|
|
71
|
+
#pragma comment(lib,"ws2_32.lib")
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
#include <Ws2tcpip.h>
|
|
75
|
+
#define GET_ERRNO (WSAGetLastError())
|
|
76
|
+
#define SOCK_ERRORCODE(x) WSA##x
|
|
77
|
+
#define AMPS_INITLOCK(x) InitializeCriticalSection(x)
|
|
78
|
+
#define AMPS_LOCK(x) EnterCriticalSection(x)
|
|
79
|
+
BOOL amps_win_spin_lock(LPCRITICAL_SECTION x)
|
|
80
|
+
{
|
|
81
|
+
BOOL ret = FALSE;
|
|
82
|
+
int tries = 100;
|
|
83
|
+
while (!ret && --tries > 0)
|
|
84
|
+
{
|
|
85
|
+
ret = TryEnterCriticalSection(x);
|
|
86
|
+
Sleep(1);
|
|
87
|
+
}
|
|
88
|
+
return ret;
|
|
89
|
+
}
|
|
90
|
+
#define AMPS_SPIN_LOCK(x) amps_win_spin_lock(x)
|
|
91
|
+
#define AMPS_SPIN_LOCK_UNLIMITED(x) EnterCriticalSection(x)
|
|
92
|
+
#define AMPS_UNLOCK(x) LeaveCriticalSection(x)
|
|
93
|
+
#define AMPS_KILLLOCK(x) DeleteCriticalSection(x)
|
|
94
|
+
int tcpThreadTimeoutMillis = 10000;
|
|
95
|
+
#define AMPS_JOIN_DECLARE() \
|
|
96
|
+
DWORD tid = (DWORD)0; \
|
|
97
|
+
HANDLE tidH = (HANDLE)0
|
|
98
|
+
|
|
99
|
+
#define AMPS_JOIN(x) \
|
|
100
|
+
tid = (DWORD)AMPS_IEX(&x, 0); \
|
|
101
|
+
tidH = (HANDLE)AMPS_IEX(&x##H, 0); \
|
|
102
|
+
if (tid != 0 && tid != GetCurrentThreadId()) \
|
|
103
|
+
{ \
|
|
104
|
+
WaitForSingleObject(tidH, tcpThreadTimeoutMillis); \
|
|
105
|
+
}
|
|
106
|
+
#define AMPS_SLEEP(x) \
|
|
107
|
+
Sleep(x)
|
|
108
|
+
#define SHUT_RDWR SD_BOTH
|
|
109
|
+
#else
|
|
110
|
+
#define GET_ERRNO (errno)
|
|
111
|
+
#define SOCK_ERRORCODE(x) x
|
|
112
|
+
#include <pthread.h>
|
|
113
|
+
|
|
114
|
+
static pthread_mutexattr_t _mutexattr_recursive;
|
|
115
|
+
#define AMPS_INITLOCK(x) { \
|
|
116
|
+
pthread_mutexattr_init(&_mutexattr_recursive); \
|
|
117
|
+
pthread_mutexattr_settype(&_mutexattr_recursive, PTHREAD_MUTEX_RECURSIVE);\
|
|
118
|
+
pthread_mutex_init(x, &_mutexattr_recursive); }
|
|
119
|
+
#define AMPS_LOCK(x) pthread_mutex_lock(x)
|
|
120
|
+
int amps_spin_lock_counted(pthread_mutex_t* lock_)
|
|
121
|
+
{
|
|
122
|
+
static const struct timespec spin_ts = { 0, 100 * 1000 };
|
|
123
|
+
int tries = 1000;
|
|
124
|
+
int ret = pthread_mutex_trylock(lock_);
|
|
125
|
+
while (ret != 0 && --tries > 0)
|
|
126
|
+
{
|
|
127
|
+
nanosleep(&spin_ts, NULL);
|
|
128
|
+
ret = pthread_mutex_trylock(lock_);
|
|
129
|
+
}
|
|
130
|
+
/* Windows-like return, 1 for TRUE (acquired) 0 for FALSE */
|
|
131
|
+
return (ret == 0) ? 1 : 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
void amps_spin_lock_unlimited(pthread_mutex_t* lock_)
|
|
135
|
+
{
|
|
136
|
+
static const struct timespec spin_ts = { 0, 100 * 1000 };
|
|
137
|
+
int ret = pthread_mutex_trylock(lock_);
|
|
138
|
+
while (ret != 0)
|
|
139
|
+
{
|
|
140
|
+
nanosleep(&spin_ts, NULL);
|
|
141
|
+
amps_invoke_waiting_function();
|
|
142
|
+
ret = pthread_mutex_trylock(lock_);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
#define AMPS_SPIN_LOCK(x) amps_spin_lock_counted(x)
|
|
146
|
+
#define AMPS_SPIN_LOCK_UNLIMITED(x) amps_spin_lock_unlimited(x)
|
|
147
|
+
|
|
148
|
+
void amps_cleanup_unlock_mutex(void* m)
|
|
149
|
+
{
|
|
150
|
+
pthread_mutex_unlock((pthread_mutex_t*)m);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
void amps_cleanup_free_buffer(void* data)
|
|
154
|
+
{
|
|
155
|
+
char* buffer = NULL;
|
|
156
|
+
if (data)
|
|
157
|
+
{
|
|
158
|
+
buffer = (char*)(*(char**)data);
|
|
159
|
+
free(buffer);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
#define AMPS_UNLOCK(x) pthread_mutex_unlock(x)
|
|
164
|
+
#define AMPS_KILLLOCK(x) pthread_mutex_destroy(x)
|
|
165
|
+
#define AMPS_JOIN_DECLARE() \
|
|
166
|
+
pthread_t tid = 0;
|
|
167
|
+
|
|
168
|
+
#if __STDC_VERSION__ >= 201100
|
|
169
|
+
#define AMPS_JOIN(x) \
|
|
170
|
+
tid = atomic_exchange((&x), (pthread_t)0); \
|
|
171
|
+
if(tid!=(pthread_t)0 && tid!=pthread_self()) \
|
|
172
|
+
{ \
|
|
173
|
+
pthread_join(tid, NULL); \
|
|
174
|
+
}
|
|
175
|
+
#else
|
|
176
|
+
#define AMPS_JOIN(x) \
|
|
177
|
+
tid = AMPS_FETCH_ADD(&x, 0); \
|
|
178
|
+
if(tid!=0 && tid!=pthread_self()) \
|
|
179
|
+
{ \
|
|
180
|
+
if(__sync_bool_compare_and_swap(&x, tid, 0)) \
|
|
181
|
+
{ \
|
|
182
|
+
pthread_join(tid, NULL); \
|
|
183
|
+
} \
|
|
184
|
+
}
|
|
185
|
+
#endif
|
|
186
|
+
|
|
187
|
+
#define AMPS_SLEEP(x) { \
|
|
188
|
+
static struct timespec ts = { x/1000, (x%1000) * 1000000 }; \
|
|
189
|
+
nanosleep(&ts, NULL); }
|
|
190
|
+
#endif
|
|
191
|
+
|
|
192
|
+
typedef struct
|
|
193
|
+
{
|
|
194
|
+
amps_thread_created_callback threadCreatedCallback;
|
|
195
|
+
void* threadCreatedCallbackUserData;
|
|
196
|
+
char* buf;
|
|
197
|
+
amps_int64_t serializer;
|
|
198
|
+
amps_handler messageHandler;
|
|
199
|
+
void* messageHandlerUserData;
|
|
200
|
+
amps_transport_filter_function filterFunction;
|
|
201
|
+
void* filterUserData;
|
|
202
|
+
|
|
203
|
+
amps_predisconnect_handler predisconnectHandler;
|
|
204
|
+
void* predisconnectHandlerUserData;
|
|
205
|
+
amps_handler disconnectHandler;
|
|
206
|
+
void* disconnectHandlerUserData;
|
|
207
|
+
amps_uint64_t readTimeoutMillis;
|
|
208
|
+
amps_uint64_t idleTimeMillis;
|
|
209
|
+
#if __STDC_VERSION__ >= 201100
|
|
210
|
+
atomic_int_fast64_t threadCreatedCallbackResult;
|
|
211
|
+
_Atomic unsigned connectionVersion;
|
|
212
|
+
#else
|
|
213
|
+
#if defined(_WIN32) && !defined(_WIN64)
|
|
214
|
+
volatile long threadCreatedCallbackResult;
|
|
215
|
+
#else
|
|
216
|
+
volatile amps_int64_t threadCreatedCallbackResult;
|
|
217
|
+
#endif
|
|
218
|
+
volatile unsigned connectionVersion;
|
|
219
|
+
#endif
|
|
220
|
+
|
|
221
|
+
size_t capacity;
|
|
222
|
+
#if __STDC_VERSION__ >= 201100
|
|
223
|
+
_Atomic AMPS_SOCKET fd;
|
|
224
|
+
atomic_bool disconnecting;
|
|
225
|
+
atomic_bool destroying;
|
|
226
|
+
#else
|
|
227
|
+
volatile AMPS_SOCKET fd;
|
|
228
|
+
volatile long disconnecting;
|
|
229
|
+
volatile long destroying;
|
|
230
|
+
#endif
|
|
231
|
+
#ifdef _WIN32
|
|
232
|
+
CRITICAL_SECTION lock;
|
|
233
|
+
CRITICAL_SECTION sendLock;
|
|
234
|
+
#if __STDC_VERSION__ >= 201100
|
|
235
|
+
_Atomic DWORD thread;
|
|
236
|
+
_Atomic HANDLE threadH;
|
|
237
|
+
#else
|
|
238
|
+
volatile DWORD thread;
|
|
239
|
+
volatile HANDLE threadH;
|
|
240
|
+
#endif
|
|
241
|
+
#else
|
|
242
|
+
pthread_mutex_t lock;
|
|
243
|
+
pthread_mutex_t sendLock;
|
|
244
|
+
#if __STDC_VERSION__ >= 201100
|
|
245
|
+
_Atomic pthread_t thread;
|
|
246
|
+
#else
|
|
247
|
+
volatile pthread_t thread;
|
|
248
|
+
#endif
|
|
249
|
+
#endif
|
|
250
|
+
char lastErrorBuf[1024];
|
|
251
|
+
}
|
|
252
|
+
amps_tcp_t;
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
const amps_char* amps_tcp_get_last_error(
|
|
256
|
+
amps_handle transport)
|
|
257
|
+
{
|
|
258
|
+
return ((amps_tcp_t*)transport)->lastErrorBuf;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
void amps_tcp_set_error(
|
|
262
|
+
amps_tcp_t* transport,
|
|
263
|
+
amps_char* buffer)
|
|
264
|
+
{
|
|
265
|
+
_AMPS_SNPRINTF(transport->lastErrorBuf, sizeof(transport->lastErrorBuf), "%s", buffer);
|
|
266
|
+
transport->lastErrorBuf[sizeof(transport->lastErrorBuf) - 1] = '\0';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
void amps_tcp_set_socket_error(
|
|
270
|
+
amps_tcp_t* transport)
|
|
271
|
+
{
|
|
272
|
+
int errorCode;
|
|
273
|
+
|
|
274
|
+
#ifdef _WIN32
|
|
275
|
+
char localBuf[256];
|
|
276
|
+
errorCode = GetLastError();
|
|
277
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, 0, localBuf, sizeof(localBuf), NULL);
|
|
278
|
+
amps_tcp_set_error(transport, localBuf);
|
|
279
|
+
#else
|
|
280
|
+
errorCode = errno;
|
|
281
|
+
amps_tcp_set_error(transport, strerror(errorCode));
|
|
282
|
+
#endif
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
void amps_tcp_set_hostname_error(
|
|
286
|
+
amps_tcp_t* transport,
|
|
287
|
+
int rc)
|
|
288
|
+
{
|
|
289
|
+
#ifdef _WIN32
|
|
290
|
+
amps_tcp_set_socket_error(transport);
|
|
291
|
+
#else
|
|
292
|
+
strncpy(transport->lastErrorBuf, gai_strerror(rc), sizeof(transport->lastErrorBuf));
|
|
293
|
+
transport->lastErrorBuf[sizeof(transport->lastErrorBuf) - 1] = '\0';
|
|
294
|
+
#endif
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
void
|
|
298
|
+
amps_tcp_noop_filter_function(const unsigned char* data, size_t length, short direction, void* userdata)
|
|
299
|
+
{;}
|
|
300
|
+
|
|
301
|
+
void amps_tcp_atfork_handler(amps_tcp_t* transport_, int code_)
|
|
302
|
+
{
|
|
303
|
+
switch (code_)
|
|
304
|
+
{
|
|
305
|
+
case 0:
|
|
306
|
+
break;
|
|
307
|
+
case 1:
|
|
308
|
+
break;
|
|
309
|
+
case 2:
|
|
310
|
+
/* Reinitialize the transport lock in the forked child */
|
|
311
|
+
AMPS_INITLOCK(&transport_->lock);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
amps_handle amps_tcp_create(void)
|
|
317
|
+
{
|
|
318
|
+
amps_tcp_t* transport = (amps_tcp_t*)malloc(sizeof(amps_tcp_t));
|
|
319
|
+
|
|
320
|
+
if (transport != NULL)
|
|
321
|
+
{
|
|
322
|
+
memset(transport, 0, sizeof(amps_tcp_t));
|
|
323
|
+
transport->fd = AMPS_INVALID_SOCKET;
|
|
324
|
+
AMPS_INITLOCK(&transport->lock);
|
|
325
|
+
AMPS_INITLOCK(&transport->sendLock);
|
|
326
|
+
transport->filterFunction = &s_tcp_noop_filter_function;
|
|
327
|
+
#if __STDC_VERSION__ >= 201100
|
|
328
|
+
transport->destroying = false;
|
|
329
|
+
transport->disconnecting = false;
|
|
330
|
+
#endif
|
|
331
|
+
amps_atfork_add(transport, (_amps_atfork_callback_function)amps_tcp_atfork_handler);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return transport;
|
|
335
|
+
}
|
|
336
|
+
#ifdef _WIN32
|
|
337
|
+
DWORD amps_tcp_threaded_reader(void* userData);
|
|
338
|
+
#else
|
|
339
|
+
void* amps_tcp_threaded_reader(void* userData);
|
|
340
|
+
#endif
|
|
341
|
+
|
|
342
|
+
int
|
|
343
|
+
amps_tcp_opt_parse(const char* val, size_t valLen, int* parsed)
|
|
344
|
+
{
|
|
345
|
+
size_t i;
|
|
346
|
+
if (valLen == 4 && memcmp(val, "true", 4) == 0)
|
|
347
|
+
{
|
|
348
|
+
*parsed = 1;
|
|
349
|
+
return 1;
|
|
350
|
+
}
|
|
351
|
+
else if (valLen == 5 && memcmp(val, "false", 5) == 0)
|
|
352
|
+
{
|
|
353
|
+
*parsed = 0;
|
|
354
|
+
return 1;
|
|
355
|
+
}
|
|
356
|
+
else
|
|
357
|
+
{
|
|
358
|
+
*parsed = 0;
|
|
359
|
+
for (i = 0; i < valLen ; i++)
|
|
360
|
+
{
|
|
361
|
+
*parsed *= 10;
|
|
362
|
+
if (val[i] >= '0' && val[i] <= '9')
|
|
363
|
+
{
|
|
364
|
+
*parsed += val[i] - '0';
|
|
365
|
+
}
|
|
366
|
+
else
|
|
367
|
+
{
|
|
368
|
+
return 0;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return 1;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
amps_result
|
|
376
|
+
amps_tcp_apply_socket_property(AMPS_SOCKET fd, const char* key, size_t keyLen, const
|
|
377
|
+
char* val, size_t valLen)
|
|
378
|
+
{
|
|
379
|
+
int value = 0, level = SOL_SOCKET, optname;
|
|
380
|
+
unsigned int optValueSize = sizeof(int);
|
|
381
|
+
char* optValuePtr = (char*)&value;
|
|
382
|
+
struct linger lingerStruct;
|
|
383
|
+
if (keyLen == 4 && memcmp(key, "bind", keyLen) == 0)
|
|
384
|
+
{
|
|
385
|
+
struct addrinfo* pAddrInfo = NULL, addrhints;
|
|
386
|
+
char addr[256] = { 0 };
|
|
387
|
+
char port[256] = { 0 };
|
|
388
|
+
size_t addrLen = valLen, portLen = 0;
|
|
389
|
+
char* portStr = (char*)(memchr((void*)val, ':', valLen));
|
|
390
|
+
char* ipv6Str = (char*)(memchr((void*)val, '[', valLen));
|
|
391
|
+
|
|
392
|
+
#ifdef _WIN32
|
|
393
|
+
int addrFamily = 0;
|
|
394
|
+
WSAPROTOCOL_INFOW localProto;
|
|
395
|
+
int localProtoLen = sizeof(WSAPROTOCOL_INFO);
|
|
396
|
+
if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&localProto, &localProtoLen) == SOCKET_ERROR)
|
|
397
|
+
{
|
|
398
|
+
return AMPS_E_URI;
|
|
399
|
+
}
|
|
400
|
+
addrFamily = localProto.iAddressFamily;
|
|
401
|
+
#elif !defined(__APPLE__)
|
|
402
|
+
int addrFamily = 0;
|
|
403
|
+
socklen_t addrFamilyLen = sizeof(addrFamily);
|
|
404
|
+
if(getsockopt(fd, SOL_SOCKET, AMPS_SO_DOMAIN, (void *)&addrFamily, &addrFamilyLen) < 0)
|
|
405
|
+
{
|
|
406
|
+
return AMPS_E_URI;
|
|
407
|
+
}
|
|
408
|
+
#endif
|
|
409
|
+
|
|
410
|
+
if (ipv6Str)
|
|
411
|
+
{
|
|
412
|
+
++ipv6Str;
|
|
413
|
+
char* ipv6StrEnd = (char*)(memchr((void*)ipv6Str, ']', (size_t)(val + valLen - ipv6Str)));
|
|
414
|
+
if (!ipv6StrEnd)
|
|
415
|
+
{
|
|
416
|
+
return AMPS_E_URI;
|
|
417
|
+
}
|
|
418
|
+
addrLen = (size_t)(ipv6StrEnd - ipv6Str);
|
|
419
|
+
memcpy(addr, ipv6Str, addrLen);
|
|
420
|
+
addr[addrLen] = '\0';
|
|
421
|
+
|
|
422
|
+
if ((size_t)(val + valLen - ++ipv6StrEnd) < valLen && *ipv6StrEnd == ':')
|
|
423
|
+
{
|
|
424
|
+
portLen = (size_t)(val + valLen - ++ipv6StrEnd);
|
|
425
|
+
memcpy(port, ipv6StrEnd, portLen);
|
|
426
|
+
port[portLen] = '\0';
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else if (portStr)
|
|
430
|
+
{
|
|
431
|
+
addrLen = (size_t)(portStr - val);
|
|
432
|
+
portLen = (size_t)(val + valLen - ++portStr);
|
|
433
|
+
memcpy(addr, val, addrLen);
|
|
434
|
+
addr[addrLen] = '\0';
|
|
435
|
+
memcpy(port, portStr, portLen);
|
|
436
|
+
port[portLen] = '\0';
|
|
437
|
+
}
|
|
438
|
+
else
|
|
439
|
+
{
|
|
440
|
+
memcpy(addr, val, addrLen);
|
|
441
|
+
addr[addrLen] = '\0';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/* use getaddrinfo() to find an appropriate address */
|
|
445
|
+
memset(&addrhints, 0, sizeof(struct addrinfo));
|
|
446
|
+
addrhints.ai_socktype = SOCK_STREAM;
|
|
447
|
+
addrhints.ai_protocol = 0;
|
|
448
|
+
#ifndef __APPLE__
|
|
449
|
+
addrhints.ai_family = addrFamily; // match the family of the socket
|
|
450
|
+
#else
|
|
451
|
+
if (ipv6Str)
|
|
452
|
+
{
|
|
453
|
+
addrhints.ai_family = AF_INET6;
|
|
454
|
+
}
|
|
455
|
+
else
|
|
456
|
+
{
|
|
457
|
+
addrhints.ai_family = AF_INET;
|
|
458
|
+
}
|
|
459
|
+
#endif
|
|
460
|
+
addrhints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_PASSIVE);
|
|
461
|
+
|
|
462
|
+
int rc = getaddrinfo(addr, port, &addrhints, &pAddrInfo);
|
|
463
|
+
if (rc != 0 || pAddrInfo == NULL)
|
|
464
|
+
{
|
|
465
|
+
if (pAddrInfo)
|
|
466
|
+
{
|
|
467
|
+
freeaddrinfo(pAddrInfo);
|
|
468
|
+
}
|
|
469
|
+
return AMPS_E_URI;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
rc = bind(fd, pAddrInfo->ai_addr, (socklen_t)pAddrInfo->ai_addrlen);
|
|
473
|
+
if (rc != 0)
|
|
474
|
+
{
|
|
475
|
+
freeaddrinfo(pAddrInfo);
|
|
476
|
+
return AMPS_E_URI;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
freeaddrinfo(pAddrInfo);
|
|
480
|
+
return AMPS_E_OK;
|
|
481
|
+
}
|
|
482
|
+
else if (keyLen == 18 && memcmp(key, "ip_protocol_prefer", keyLen) == 0)
|
|
483
|
+
{
|
|
484
|
+
// no-op; handled in the connect function
|
|
485
|
+
return AMPS_E_OK;
|
|
486
|
+
}
|
|
487
|
+
// properties after this point must only be boolean or numeric
|
|
488
|
+
if (!amps_tcp_opt_parse(val, valLen, &value))
|
|
489
|
+
{
|
|
490
|
+
return AMPS_E_URI;
|
|
491
|
+
}
|
|
492
|
+
if (keyLen == 10 && memcmp(key, "tcp_rcvbuf", keyLen) == 0)
|
|
493
|
+
{
|
|
494
|
+
optname = SO_RCVBUF;
|
|
495
|
+
}
|
|
496
|
+
else if (keyLen == 13 && memcmp(key, "tcp_keepalive", keyLen) == 0 )
|
|
497
|
+
{
|
|
498
|
+
optname = SO_KEEPALIVE;
|
|
499
|
+
}
|
|
500
|
+
else if (keyLen == 10 && memcmp(key, "tcp_sndbuf", keyLen) == 0)
|
|
501
|
+
{
|
|
502
|
+
optname = SO_SNDBUF;
|
|
503
|
+
}
|
|
504
|
+
else if (keyLen == 11 && memcmp(key, "tcp_nodelay", keyLen) == 0)
|
|
505
|
+
{
|
|
506
|
+
optname = TCP_NODELAY;
|
|
507
|
+
level = IPPROTO_TCP;
|
|
508
|
+
}
|
|
509
|
+
else if (keyLen == 10 && memcmp(key, "tcp_linger", keyLen) == 0)
|
|
510
|
+
{
|
|
511
|
+
optname = SO_LINGER;
|
|
512
|
+
lingerStruct.l_onoff = value != 0;
|
|
513
|
+
lingerStruct.l_linger = (u_short)value;
|
|
514
|
+
optValuePtr = (char*)&lingerStruct;
|
|
515
|
+
optValueSize = sizeof(struct linger);
|
|
516
|
+
}
|
|
517
|
+
else if (keyLen == 6 && memcmp(key, "pretty", keyLen) == 0)
|
|
518
|
+
{
|
|
519
|
+
// no-op; handled in C++ layer
|
|
520
|
+
return AMPS_E_OK;
|
|
521
|
+
}
|
|
522
|
+
else
|
|
523
|
+
{
|
|
524
|
+
return AMPS_E_URI;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* set it */
|
|
528
|
+
if (setsockopt(fd, level, optname, optValuePtr, optValueSize))
|
|
529
|
+
{
|
|
530
|
+
return AMPS_E_URI;
|
|
531
|
+
}
|
|
532
|
+
return AMPS_E_OK;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
amps_result
|
|
536
|
+
amps_tcp_apply_socket_properties(AMPS_SOCKET fd, const char* uri,
|
|
537
|
+
size_t uriLength, amps_uri_state* uriState)
|
|
538
|
+
{
|
|
539
|
+
const char* key = NULL;
|
|
540
|
+
size_t keyLength = 0;
|
|
541
|
+
/* First, enable tcp_keepalive by default */
|
|
542
|
+
int value = 1;
|
|
543
|
+
unsigned int optValueSize = sizeof(int);
|
|
544
|
+
char* optValuePtr = (char*)&value;
|
|
545
|
+
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, optValuePtr, optValueSize))
|
|
546
|
+
{
|
|
547
|
+
return AMPS_E_URI;
|
|
548
|
+
}
|
|
549
|
+
/* Now, parse the rest of the URI */
|
|
550
|
+
while (uriState->part_id < AMPS_URI_ERROR)
|
|
551
|
+
{
|
|
552
|
+
amps_uri_parse(uri, uriLength, uriState);
|
|
553
|
+
if (uriState->part_id == AMPS_URI_OPTION_KEY)
|
|
554
|
+
{
|
|
555
|
+
key = uriState->part;
|
|
556
|
+
keyLength = uriState->part_length;
|
|
557
|
+
}
|
|
558
|
+
else if (uriState->part_id == AMPS_URI_OPTION_VALUE)
|
|
559
|
+
{
|
|
560
|
+
if (amps_tcp_apply_socket_property(fd, key, keyLength,
|
|
561
|
+
uriState->part, uriState->part_length) != AMPS_E_OK)
|
|
562
|
+
{
|
|
563
|
+
return AMPS_E_URI;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (uriState->part_id == AMPS_URI_ERROR)
|
|
568
|
+
{
|
|
569
|
+
return AMPS_E_URI;
|
|
570
|
+
}
|
|
571
|
+
return AMPS_E_OK;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
amps_result amps_tcp_connect(amps_handle transport, const amps_char* address)
|
|
575
|
+
{
|
|
576
|
+
AMPS_JOIN_DECLARE();
|
|
577
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
578
|
+
char* host = NULL, *port = NULL, *protocol = NULL;
|
|
579
|
+
amps_uri_state uri_state_socket_props, uri_state_addr_props;
|
|
580
|
+
amps_ip_protocol_preference ip_proto_prefer = AMPS_DEFAULT_IP_PROTOCOL_PREFERENCE;
|
|
581
|
+
int ip_proto_pref_override = 0;
|
|
582
|
+
int rc;
|
|
583
|
+
amps_result result = AMPS_E_OK;
|
|
584
|
+
struct addrinfo* pAddrInfo = NULL, addrhints;
|
|
585
|
+
size_t address_length = 0;
|
|
586
|
+
AMPS_SOCKET fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
587
|
+
int i;
|
|
588
|
+
|
|
589
|
+
#ifdef _WIN32
|
|
590
|
+
WSADATA wsaData;
|
|
591
|
+
rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
592
|
+
if (rc != 0)
|
|
593
|
+
{
|
|
594
|
+
amps_tcp_set_error(me, "Windows Sockets could not be started.");
|
|
595
|
+
return AMPS_E_MEMORY;
|
|
596
|
+
}
|
|
597
|
+
#endif
|
|
598
|
+
AMPS_LOCK(&me->lock);
|
|
599
|
+
#ifndef _WIN32
|
|
600
|
+
pthread_cleanup_push(amps_cleanup_unlock_mutex, (void*)&me->lock);
|
|
601
|
+
#endif
|
|
602
|
+
/* if we were previously marked as disconnecting, forget that. */
|
|
603
|
+
#if __STDC_VERSION__ >= 201100
|
|
604
|
+
me->disconnecting = false;
|
|
605
|
+
#else
|
|
606
|
+
AMPS_IEX_LONG(&me->disconnecting, 0);
|
|
607
|
+
#endif
|
|
608
|
+
|
|
609
|
+
/* were we previously connected? go ahead and shut that down. */
|
|
610
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
611
|
+
{
|
|
612
|
+
/* this is a reconnect */
|
|
613
|
+
shutdown(fd, SHUT_RDWR);
|
|
614
|
+
closesocket(fd);
|
|
615
|
+
fd = AMPS_INVALID_SOCKET;
|
|
616
|
+
}
|
|
617
|
+
AMPS_JOIN(me->thread);
|
|
618
|
+
|
|
619
|
+
/* parse out the address */
|
|
620
|
+
memset(&uri_state_socket_props, 0, sizeof(amps_uri_state));
|
|
621
|
+
memset(&uri_state_addr_props, 0, sizeof(amps_uri_state));
|
|
622
|
+
address_length = strlen(address);
|
|
623
|
+
while (uri_state_addr_props.part_id < AMPS_URI_ERROR)
|
|
624
|
+
{
|
|
625
|
+
amps_uri_parse(address, address_length, &uri_state_addr_props);
|
|
626
|
+
switch (uri_state_addr_props.part_id)
|
|
627
|
+
{
|
|
628
|
+
case AMPS_URI_PROTOCOL:
|
|
629
|
+
protocol = _AMPS_STRNDUP(uri_state_addr_props.part, uri_state_addr_props.part_length);
|
|
630
|
+
me->serializer = amps_message_get_protocol(protocol);
|
|
631
|
+
if (me->serializer == -1)
|
|
632
|
+
{
|
|
633
|
+
amps_tcp_set_error(me,
|
|
634
|
+
"The URI specified an unavailable protocol.");
|
|
635
|
+
result = AMPS_E_URI;
|
|
636
|
+
goto error;
|
|
637
|
+
}
|
|
638
|
+
memcpy(&uri_state_socket_props, &uri_state_addr_props, sizeof(amps_uri_state));
|
|
639
|
+
break;
|
|
640
|
+
case AMPS_URI_HOST:
|
|
641
|
+
host = _AMPS_STRNDUP(uri_state_addr_props.part, uri_state_addr_props.part_length);
|
|
642
|
+
break;
|
|
643
|
+
case AMPS_URI_PORT:
|
|
644
|
+
port = _AMPS_STRNDUP(uri_state_addr_props.part, uri_state_addr_props.part_length);
|
|
645
|
+
break;
|
|
646
|
+
case AMPS_URI_OPTION_KEY:
|
|
647
|
+
if (uri_state_addr_props.part_length == 18 && memcmp(uri_state_addr_props.part, "ip_protocol_prefer", uri_state_addr_props.part_length) == 0)
|
|
648
|
+
{
|
|
649
|
+
ip_proto_pref_override = 1;
|
|
650
|
+
}
|
|
651
|
+
break;
|
|
652
|
+
case AMPS_URI_OPTION_VALUE:
|
|
653
|
+
if (ip_proto_pref_override)
|
|
654
|
+
{
|
|
655
|
+
if (uri_state_addr_props.part_length == 4 && memcmp(uri_state_addr_props.part, "ipv4", uri_state_addr_props.part_length) == 0)
|
|
656
|
+
{
|
|
657
|
+
ip_proto_prefer = AMPS_PREFER_IPV4;
|
|
658
|
+
}
|
|
659
|
+
else if (uri_state_addr_props.part_length == 4 && memcmp(uri_state_addr_props.part, "ipv6", uri_state_addr_props.part_length) == 0)
|
|
660
|
+
{
|
|
661
|
+
ip_proto_prefer = AMPS_PREFER_IPV6;
|
|
662
|
+
}
|
|
663
|
+
else
|
|
664
|
+
{
|
|
665
|
+
amps_tcp_set_error(me,
|
|
666
|
+
"The URI specified an invalid ip protocol preference.");
|
|
667
|
+
result = AMPS_E_URI;
|
|
668
|
+
goto error;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
break;
|
|
672
|
+
default:
|
|
673
|
+
break;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
if (uri_state_addr_props.part_id == AMPS_URI_ERROR)
|
|
677
|
+
{
|
|
678
|
+
amps_tcp_set_error(me, "URI format invalid.");
|
|
679
|
+
result = AMPS_E_URI;
|
|
680
|
+
goto error;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* use getaddrinfo() to find an appropriate address */
|
|
684
|
+
memset(&addrhints, 0, sizeof(struct addrinfo));
|
|
685
|
+
addrhints.ai_socktype = SOCK_STREAM;
|
|
686
|
+
addrhints.ai_protocol = 0;
|
|
687
|
+
addrhints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
|
|
688
|
+
addrhints.ai_family = ip_proto_prefer == AMPS_PREFER_IPV6 ? AF_INET6 : AF_INET; /* Try the preferred protocol first */
|
|
689
|
+
|
|
690
|
+
rc = getaddrinfo(host, port, &addrhints, &pAddrInfo);
|
|
691
|
+
#ifdef _WIN32
|
|
692
|
+
if (rc == EAI_FAMILY || rc == EAI_NONAME || rc == EAI_AGAIN || rc == EAI_SERVICE)
|
|
693
|
+
#else
|
|
694
|
+
if (rc == EAI_ADDRFAMILY || rc == EAI_NONAME || rc == EAI_AGAIN || rc == EAI_SERVICE)
|
|
695
|
+
#endif
|
|
696
|
+
{
|
|
697
|
+
// didn't find any addresses of the preferred protocol, try the other one.
|
|
698
|
+
addrhints.ai_family = ip_proto_prefer == AMPS_PREFER_IPV6 ? AF_INET : AF_INET6;
|
|
699
|
+
rc = getaddrinfo(host, port, &addrhints, &pAddrInfo);
|
|
700
|
+
if (rc != 0)
|
|
701
|
+
{
|
|
702
|
+
/* Try preferred protocol again without AI_ADDRCONFIG */
|
|
703
|
+
addrhints.ai_flags = AI_V4MAPPED;
|
|
704
|
+
addrhints.ai_family = ip_proto_prefer == AMPS_PREFER_IPV6 ? AF_INET6 : AF_INET;
|
|
705
|
+
rc = getaddrinfo(host, port, &addrhints, &pAddrInfo);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
if (rc != 0)
|
|
709
|
+
{
|
|
710
|
+
result = AMPS_E_CONNECTION_REFUSED;
|
|
711
|
+
amps_tcp_set_hostname_error(me, rc);
|
|
712
|
+
freeaddrinfo(pAddrInfo);
|
|
713
|
+
goto error;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
me->fd = socket(pAddrInfo->ai_family, pAddrInfo->ai_socktype, pAddrInfo->ai_protocol);
|
|
717
|
+
if (me->fd == AMPS_INVALID_SOCKET)
|
|
718
|
+
{
|
|
719
|
+
freeaddrinfo(pAddrInfo);
|
|
720
|
+
amps_tcp_set_socket_error(me);
|
|
721
|
+
result = AMPS_E_CONNECTION_REFUSED;
|
|
722
|
+
goto error;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
/* apply socket properties */
|
|
727
|
+
if (amps_tcp_apply_socket_properties(me->fd, address, address_length, &uri_state_socket_props) != AMPS_E_OK)
|
|
728
|
+
{
|
|
729
|
+
freeaddrinfo(pAddrInfo);
|
|
730
|
+
fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
731
|
+
amps_tcp_set_error(me, "The URI specified invalid properties.");
|
|
732
|
+
result = AMPS_E_URI;
|
|
733
|
+
goto error;
|
|
734
|
+
}
|
|
735
|
+
#ifdef __APPLE__
|
|
736
|
+
rc = 1; /* Set NOSIGPIPE to ON */
|
|
737
|
+
if (setsockopt(me->fd, SOL_SOCKET, SO_NOSIGPIPE, &rc, sizeof(rc)) < 0)
|
|
738
|
+
{
|
|
739
|
+
perror ("setsockopt(,,SO_NOSIGPIPE)");
|
|
740
|
+
freeaddrinfo(pAddrInfo);
|
|
741
|
+
fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
742
|
+
amps_tcp_set_error(me, "Failed to set no SIGPIPE.");
|
|
743
|
+
result = AMPS_E_CONNECTION;
|
|
744
|
+
goto error;
|
|
745
|
+
}
|
|
746
|
+
#endif
|
|
747
|
+
|
|
748
|
+
rc = connect(me->fd, pAddrInfo->ai_addr,
|
|
749
|
+
(socklen_t)pAddrInfo->ai_addrlen);
|
|
750
|
+
freeaddrinfo(pAddrInfo);
|
|
751
|
+
#ifdef _WIN32
|
|
752
|
+
if (rc == SOCKET_ERROR)
|
|
753
|
+
#else
|
|
754
|
+
if (rc == -1)
|
|
755
|
+
#endif
|
|
756
|
+
{
|
|
757
|
+
fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
758
|
+
amps_tcp_set_socket_error(me);
|
|
759
|
+
result = AMPS_E_CONNECTION_REFUSED;
|
|
760
|
+
goto error;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/* Increase the connection version now, so that anyone else attempting a
|
|
764
|
+
* reconnect knows that they may not need to. */
|
|
765
|
+
me->connectionVersion++;
|
|
766
|
+
result = AMPS_E_OK;
|
|
767
|
+
|
|
768
|
+
/* and, start up a new reader thread */
|
|
769
|
+
if (me->threadCreatedCallback)
|
|
770
|
+
{
|
|
771
|
+
AMPS_IEX(&me->threadCreatedCallbackResult, -1L);
|
|
772
|
+
}
|
|
773
|
+
#ifdef _WIN32
|
|
774
|
+
me->threadH = CreateThread(NULL, 0,
|
|
775
|
+
(LPTHREAD_START_ROUTINE)amps_tcp_threaded_reader,
|
|
776
|
+
me, CREATE_SUSPENDED, (LPDWORD)&me->thread);
|
|
777
|
+
/* Now that me->thread is populated, we can start the thread.
|
|
778
|
+
* important to do it in two steps, since we use me->thread as a poor-man's cancellation mechanism */
|
|
779
|
+
if (me->threadH)
|
|
780
|
+
{
|
|
781
|
+
ResumeThread(me->threadH);
|
|
782
|
+
}
|
|
783
|
+
else
|
|
784
|
+
{
|
|
785
|
+
fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
786
|
+
amps_tcp_set_error(me, "Failed to create thread for receive");
|
|
787
|
+
result = AMPS_E_MEMORY;
|
|
788
|
+
goto error;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
#else
|
|
792
|
+
rc = pthread_create((pthread_t*)(&me->thread), NULL,
|
|
793
|
+
&s_tcp_threaded_reader, me);
|
|
794
|
+
if (rc != 0)
|
|
795
|
+
{
|
|
796
|
+
fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
797
|
+
amps_tcp_set_error(me, "Failed to create thread for receive");
|
|
798
|
+
result = AMPS_E_MEMORY;
|
|
799
|
+
goto error;
|
|
800
|
+
}
|
|
801
|
+
#endif
|
|
802
|
+
for (i = 0 ; i < AMPS_THREAD_START_TIMEOUT && me->threadCreatedCallbackResult == -1L; ++i)
|
|
803
|
+
{
|
|
804
|
+
AMPS_SLEEP(10);
|
|
805
|
+
}
|
|
806
|
+
result = (amps_result)me->threadCreatedCallbackResult;
|
|
807
|
+
if (me->threadCreatedCallbackResult == -1L)
|
|
808
|
+
{
|
|
809
|
+
amps_tcp_set_error(me, "Thread created callback failed to return in a timely manner or returned -1.");
|
|
810
|
+
result = AMPS_E_MEMORY;
|
|
811
|
+
}
|
|
812
|
+
error:
|
|
813
|
+
if (result != AMPS_E_OK)
|
|
814
|
+
{
|
|
815
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
816
|
+
{
|
|
817
|
+
shutdown(fd, SHUT_RDWR);
|
|
818
|
+
closesocket(fd);
|
|
819
|
+
}
|
|
820
|
+
#ifdef _WIN32
|
|
821
|
+
me->thread = 0;
|
|
822
|
+
#else
|
|
823
|
+
me->thread = (pthread_t)0;
|
|
824
|
+
#endif
|
|
825
|
+
}
|
|
826
|
+
free(host);
|
|
827
|
+
free(port);
|
|
828
|
+
free(protocol);
|
|
829
|
+
AMPS_UNLOCK(&me->lock);
|
|
830
|
+
#ifndef _WIN32
|
|
831
|
+
pthread_cleanup_pop(0);
|
|
832
|
+
#endif
|
|
833
|
+
return result;
|
|
834
|
+
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
amps_result amps_tcp_set_receiver(amps_handle transport, amps_handler receiver, void* userData)
|
|
838
|
+
{
|
|
839
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
840
|
+
me->messageHandlerUserData = userData;
|
|
841
|
+
me->messageHandler = receiver;
|
|
842
|
+
return AMPS_E_OK;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
amps_result amps_tcp_set_predisconnect(amps_handle transport,
|
|
846
|
+
amps_predisconnect_handler receiver,
|
|
847
|
+
void* userData)
|
|
848
|
+
{
|
|
849
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
850
|
+
me->predisconnectHandlerUserData = userData;
|
|
851
|
+
me->predisconnectHandler = receiver;
|
|
852
|
+
return AMPS_E_OK;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
amps_result amps_tcp_set_disconnect(amps_handle transport, amps_handler receiver, void* userData)
|
|
856
|
+
{
|
|
857
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
858
|
+
me->disconnectHandlerUserData = userData;
|
|
859
|
+
me->disconnectHandler = receiver;
|
|
860
|
+
return AMPS_E_OK;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
void amps_tcp_close(amps_handle transport)
|
|
864
|
+
{
|
|
865
|
+
AMPS_JOIN_DECLARE();
|
|
866
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
867
|
+
AMPS_SOCKET fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
868
|
+
#if __STDC_VERSION__ >= 201100
|
|
869
|
+
me->disconnecting = true;
|
|
870
|
+
#else
|
|
871
|
+
AMPS_IEX_LONG(&me->disconnecting, 1);
|
|
872
|
+
#endif
|
|
873
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
874
|
+
{
|
|
875
|
+
shutdown(fd, SHUT_RDWR);
|
|
876
|
+
}
|
|
877
|
+
AMPS_SPIN_LOCK_UNLIMITED(&me->lock);
|
|
878
|
+
#ifndef _WIN32
|
|
879
|
+
pthread_cleanup_push(amps_cleanup_unlock_mutex, (void*)&me->lock);
|
|
880
|
+
#endif
|
|
881
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
882
|
+
{
|
|
883
|
+
closesocket(fd);
|
|
884
|
+
}
|
|
885
|
+
AMPS_UNLOCK(&me->lock);
|
|
886
|
+
#ifndef _WIN32
|
|
887
|
+
pthread_cleanup_pop(0);
|
|
888
|
+
#endif
|
|
889
|
+
AMPS_JOIN(me->thread);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
void amps_tcp_destroy(amps_handle transport)
|
|
893
|
+
{
|
|
894
|
+
AMPS_JOIN_DECLARE();
|
|
895
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
896
|
+
AMPS_SOCKET fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
897
|
+
amps_atfork_remove(me, (_amps_atfork_callback_function)amps_tcp_atfork_handler);
|
|
898
|
+
|
|
899
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
900
|
+
{
|
|
901
|
+
shutdown(fd, SHUT_RDWR);
|
|
902
|
+
}
|
|
903
|
+
AMPS_LOCK(&me->lock);
|
|
904
|
+
#ifndef _WIN32
|
|
905
|
+
pthread_cleanup_push(amps_cleanup_unlock_mutex, (void*)&me->lock);
|
|
906
|
+
#endif
|
|
907
|
+
#if __STDC_VERSION__ >= 201100
|
|
908
|
+
me->destroying = true;
|
|
909
|
+
me->disconnecting = true;
|
|
910
|
+
#else
|
|
911
|
+
AMPS_IEX_LONG(&me->destroying, 1);
|
|
912
|
+
AMPS_IEX_LONG(&me->disconnecting, 1);
|
|
913
|
+
#endif
|
|
914
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
915
|
+
{
|
|
916
|
+
closesocket(fd);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
AMPS_UNLOCK(&me->lock);
|
|
920
|
+
#ifndef _WIN32
|
|
921
|
+
pthread_cleanup_pop(0);
|
|
922
|
+
#endif
|
|
923
|
+
AMPS_JOIN(me->thread);
|
|
924
|
+
AMPS_SLEEP(1);
|
|
925
|
+
free(me->buf);
|
|
926
|
+
/* Hopefully, nobody else is using me right now. */
|
|
927
|
+
AMPS_KILLLOCK(&me->lock);
|
|
928
|
+
AMPS_KILLLOCK(&me->sendLock);
|
|
929
|
+
free(me);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/* called with me->lock not already taken */
|
|
933
|
+
amps_result amps_tcp_handle_disconnect(
|
|
934
|
+
amps_tcp_t* me, unsigned failedConnectionVersion)
|
|
935
|
+
{
|
|
936
|
+
#ifndef _WIN32
|
|
937
|
+
int cancelState = 0;
|
|
938
|
+
int unusedCancelState = 0;
|
|
939
|
+
#endif
|
|
940
|
+
amps_result result = AMPS_E_OK;
|
|
941
|
+
AMPS_SOCKET fd = AMPS_IEX_GET(&me->fd, AMPS_INVALID_SOCKET);
|
|
942
|
+
if (fd != AMPS_INVALID_SOCKET)
|
|
943
|
+
{
|
|
944
|
+
shutdown(fd, SHUT_RDWR);
|
|
945
|
+
closesocket(fd);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/* first let waiters know that we've failed. */
|
|
949
|
+
me->predisconnectHandler(me, failedConnectionVersion, me->predisconnectHandlerUserData);
|
|
950
|
+
|
|
951
|
+
/* Now take the lock on self.
|
|
952
|
+
* Use a spin, the only case where it might fail should be if a recv
|
|
953
|
+
* thread ends up here while a send thread is already handling disconnect
|
|
954
|
+
* and it is trying to join this thread in disconnect. */
|
|
955
|
+
if (AMPS_SPIN_LOCK(&me->lock) == 0)
|
|
956
|
+
{
|
|
957
|
+
return AMPS_E_RETRY;
|
|
958
|
+
}
|
|
959
|
+
#ifndef _WIN32
|
|
960
|
+
pthread_cleanup_push(amps_cleanup_unlock_mutex, (void*)&me->lock);
|
|
961
|
+
#endif
|
|
962
|
+
|
|
963
|
+
if (me->destroying)
|
|
964
|
+
{
|
|
965
|
+
result = AMPS_E_DISCONNECTED;
|
|
966
|
+
goto error;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/* a new connection is available. let someone else try. */
|
|
970
|
+
if (failedConnectionVersion != me->connectionVersion)
|
|
971
|
+
{
|
|
972
|
+
result = AMPS_E_RETRY;
|
|
973
|
+
goto error;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/* if we're disconnecting, get out of here; don't reconnect */
|
|
977
|
+
if (me->disconnecting)
|
|
978
|
+
{
|
|
979
|
+
result = AMPS_E_DISCONNECTED;
|
|
980
|
+
goto error;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
#ifndef _WIN32
|
|
984
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
985
|
+
#endif
|
|
986
|
+
/* Call the disconect handler. */
|
|
987
|
+
result = me->disconnectHandler(me, me->disconnectHandlerUserData);
|
|
988
|
+
#ifndef _WIN32
|
|
989
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
990
|
+
#endif
|
|
991
|
+
if (result == AMPS_E_OK)
|
|
992
|
+
{
|
|
993
|
+
result = AMPS_E_RETRY;
|
|
994
|
+
}
|
|
995
|
+
error:
|
|
996
|
+
#ifndef _WIN32
|
|
997
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
998
|
+
#endif
|
|
999
|
+
AMPS_UNLOCK(&me->lock);
|
|
1000
|
+
#ifndef _WIN32
|
|
1001
|
+
pthread_cleanup_pop(0);
|
|
1002
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
1003
|
+
#endif
|
|
1004
|
+
|
|
1005
|
+
return result;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
void amps_tcp_handle_stream_corruption(
|
|
1009
|
+
amps_tcp_t* me, unsigned failedConnectionVersion)
|
|
1010
|
+
{
|
|
1011
|
+
shutdown(me->fd, SHUT_RDWR);
|
|
1012
|
+
amps_tcp_set_error(me, "The connection appears corrupt. Disconnecting.");
|
|
1013
|
+
amps_tcp_handle_disconnect(me, failedConnectionVersion);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
amps_result
|
|
1018
|
+
amps_tcp_send_with_version(amps_handle transport,
|
|
1019
|
+
amps_handle message,
|
|
1020
|
+
unsigned* version_out)
|
|
1021
|
+
{
|
|
1022
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1023
|
+
size_t len = 16 * 1024;
|
|
1024
|
+
int bytesWritten = -1;
|
|
1025
|
+
unsigned int bytesWrittenN = 0;
|
|
1026
|
+
int bytesSent = 0;
|
|
1027
|
+
|
|
1028
|
+
*version_out = me->connectionVersion;
|
|
1029
|
+
|
|
1030
|
+
if (me->disconnecting)
|
|
1031
|
+
{
|
|
1032
|
+
amps_tcp_set_error(me, "Disconnecting.");
|
|
1033
|
+
return AMPS_E_DISCONNECTED;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
if (me->fd == AMPS_INVALID_SOCKET)
|
|
1037
|
+
{
|
|
1038
|
+
amps_tcp_set_error(me, "Not connected.");
|
|
1039
|
+
return AMPS_E_DISCONNECTED;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/* serialize */
|
|
1043
|
+
AMPS_LOCK(&me->sendLock);
|
|
1044
|
+
while (bytesWritten < 0)
|
|
1045
|
+
{
|
|
1046
|
+
if (me->buf == NULL)
|
|
1047
|
+
{
|
|
1048
|
+
me->buf = (char*)malloc(len);
|
|
1049
|
+
if (me->buf == NULL)
|
|
1050
|
+
{
|
|
1051
|
+
amps_tcp_set_error(me, "Unable to allocate memory to send message.");
|
|
1052
|
+
AMPS_UNLOCK(&me->sendLock);
|
|
1053
|
+
return AMPS_E_MEMORY;
|
|
1054
|
+
}
|
|
1055
|
+
me->capacity = len;
|
|
1056
|
+
}
|
|
1057
|
+
else
|
|
1058
|
+
{
|
|
1059
|
+
len = me->capacity;
|
|
1060
|
+
}
|
|
1061
|
+
/* reserve 4 bytes for the length of the message */
|
|
1062
|
+
bytesWritten = amps_message_serialize(message, me->serializer, (me->buf) + 4, len - 4);
|
|
1063
|
+
/* amps_message_serialize could have written 0 bytes.
|
|
1064
|
+
* who are we to judge? If it returns less than 0,
|
|
1065
|
+
* there wasn't enough room. */
|
|
1066
|
+
if (bytesWritten >= 0)
|
|
1067
|
+
{
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
/* free this buffer, allocate a larger buffer next time */
|
|
1071
|
+
free(me->buf);
|
|
1072
|
+
me->capacity = 0;
|
|
1073
|
+
me->buf = NULL;
|
|
1074
|
+
len = (size_t)((double)len * 1.5);
|
|
1075
|
+
}
|
|
1076
|
+
/* once we're done, we don't free buf -- it hangs around until we need it next time.
|
|
1077
|
+
* record the message length all up in the first 4 bytes. */
|
|
1078
|
+
bytesWrittenN = htonl((unsigned int)bytesWritten);
|
|
1079
|
+
me->filterFunction((const unsigned char*)(me->buf + 4), (size_t)bytesWritten, 0, me->filterUserData);
|
|
1080
|
+
*((unsigned int*)(me->buf)) = bytesWrittenN;
|
|
1081
|
+
bytesWritten += 4;
|
|
1082
|
+
/*now, send */
|
|
1083
|
+
while (bytesSent < bytesWritten)
|
|
1084
|
+
{
|
|
1085
|
+
int bytesWrittenThisTime;
|
|
1086
|
+
#ifdef _WIN32
|
|
1087
|
+
bytesWrittenThisTime = send(me->fd, (me->buf) + bytesSent, bytesWritten - bytesSent, 0);
|
|
1088
|
+
#else
|
|
1089
|
+
bytesWrittenThisTime = (int)send(me->fd, (me->buf) + bytesSent, (size_t)(bytesWritten - bytesSent), MSG_NOSIGNAL);
|
|
1090
|
+
#endif
|
|
1091
|
+
if (bytesWrittenThisTime <= 0)
|
|
1092
|
+
{
|
|
1093
|
+
/* record the error */
|
|
1094
|
+
amps_tcp_set_error(me, "The connection is closed.");
|
|
1095
|
+
AMPS_UNLOCK(&me->sendLock);
|
|
1096
|
+
return AMPS_E_DISCONNECTED;
|
|
1097
|
+
}
|
|
1098
|
+
bytesSent += bytesWrittenThisTime;
|
|
1099
|
+
}
|
|
1100
|
+
AMPS_UNLOCK(&me->sendLock);
|
|
1101
|
+
|
|
1102
|
+
return AMPS_E_OK;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
amps_result
|
|
1106
|
+
amps_tcp_send(amps_handle transport,
|
|
1107
|
+
amps_handle message)
|
|
1108
|
+
{
|
|
1109
|
+
unsigned version_out;
|
|
1110
|
+
return amps_tcp_send_with_version(transport, message, &version_out);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
#ifdef _WIN32
|
|
1115
|
+
DWORD amps_tcp_threaded_reader(void* userData)
|
|
1116
|
+
{
|
|
1117
|
+
amps_tcp_t* me = (amps_tcp_t*)userData;
|
|
1118
|
+
DWORD self = GetCurrentThreadId();
|
|
1119
|
+
HANDLE selfH = GetCurrentThread();
|
|
1120
|
+
if (me->threadCreatedCallback)
|
|
1121
|
+
{
|
|
1122
|
+
amps_result result = me->threadCreatedCallback(selfH,
|
|
1123
|
+
me->threadCreatedCallbackUserData);
|
|
1124
|
+
AMPS_IEX(&me->threadCreatedCallbackResult, (long)result);
|
|
1125
|
+
if (result != AMPS_E_OK)
|
|
1126
|
+
{
|
|
1127
|
+
return (DWORD)0;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
else
|
|
1131
|
+
{
|
|
1132
|
+
AMPS_IEX(&me->threadCreatedCallbackResult, (long)AMPS_E_OK);
|
|
1133
|
+
}
|
|
1134
|
+
#else
|
|
1135
|
+
void* amps_tcp_threaded_reader(void* userData)
|
|
1136
|
+
{
|
|
1137
|
+
amps_tcp_t* me = (amps_tcp_t*)userData;
|
|
1138
|
+
/* Wait for pthread_create to set me->thread */
|
|
1139
|
+
while (me->thread != pthread_self()
|
|
1140
|
+
&& !me->disconnecting
|
|
1141
|
+
&& !me->destroying)
|
|
1142
|
+
{
|
|
1143
|
+
AMPS_SLEEP(5);
|
|
1144
|
+
}
|
|
1145
|
+
if (me->threadCreatedCallback)
|
|
1146
|
+
{
|
|
1147
|
+
amps_result result = me->threadCreatedCallback(me->thread,
|
|
1148
|
+
me->threadCreatedCallbackUserData);
|
|
1149
|
+
AMPS_IEX(&me->threadCreatedCallbackResult, (long)result);
|
|
1150
|
+
if (result != AMPS_E_OK)
|
|
1151
|
+
{
|
|
1152
|
+
return NULL;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
else
|
|
1156
|
+
{
|
|
1157
|
+
AMPS_IEX(&me->threadCreatedCallbackResult, (long)AMPS_E_OK);
|
|
1158
|
+
}
|
|
1159
|
+
int unusedCancelState = 0;
|
|
1160
|
+
#endif
|
|
1161
|
+
unsigned char* buffer, *newBuffer, *end, *readPoint, *parsePoint;
|
|
1162
|
+
|
|
1163
|
+
unsigned int msglenN;
|
|
1164
|
+
unsigned long msglen, currentPosition, bytesRead = 0;
|
|
1165
|
+
#ifdef _WIN32
|
|
1166
|
+
int received;
|
|
1167
|
+
#else
|
|
1168
|
+
ssize_t received;
|
|
1169
|
+
#endif
|
|
1170
|
+
int cancelState = 0;
|
|
1171
|
+
const size_t BUFFER_SIZE = 16 * 1024;
|
|
1172
|
+
const unsigned MAX_MESSAGE_SIZE = 1024 * 1024 * 1024;
|
|
1173
|
+
amps_uint64_t lastReadTime = 0;
|
|
1174
|
+
amps_uint64_t lastIdleTime = 0;
|
|
1175
|
+
amps_handle message;
|
|
1176
|
+
|
|
1177
|
+
/* capture the connection version we are using now. */
|
|
1178
|
+
unsigned connectionVersion = me->connectionVersion;
|
|
1179
|
+
AMPS_SOCKET fd = me->fd;
|
|
1180
|
+
|
|
1181
|
+
lastReadTime = amps_now();
|
|
1182
|
+
lastIdleTime = lastReadTime;
|
|
1183
|
+
|
|
1184
|
+
#ifndef _WIN32
|
|
1185
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
1186
|
+
#endif
|
|
1187
|
+
message = amps_message_create(NULL);
|
|
1188
|
+
buffer = (unsigned char*)malloc(BUFFER_SIZE);
|
|
1189
|
+
#ifndef _WIN32
|
|
1190
|
+
pthread_cleanup_push(amps_message_destroy, (void*)message);
|
|
1191
|
+
pthread_cleanup_push(amps_cleanup_free_buffer, (void*)(&buffer));
|
|
1192
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
1193
|
+
#endif
|
|
1194
|
+
if (!buffer)
|
|
1195
|
+
{
|
|
1196
|
+
amps_tcp_handle_disconnect(me, connectionVersion);
|
|
1197
|
+
goto cleanup;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
end = buffer + BUFFER_SIZE;
|
|
1201
|
+
readPoint = buffer;
|
|
1202
|
+
parsePoint = buffer;
|
|
1203
|
+
|
|
1204
|
+
/* while we're open and not disconnecting */
|
|
1205
|
+
while (connectionVersion == me->connectionVersion
|
|
1206
|
+
&& !me->disconnecting
|
|
1207
|
+
&& fd == me->fd
|
|
1208
|
+
#ifdef _WIN32
|
|
1209
|
+
&& me->thread == GetCurrentThreadId() /* our cancellation mechanism on win32 */
|
|
1210
|
+
#else
|
|
1211
|
+
&& me->thread == pthread_self()
|
|
1212
|
+
#endif
|
|
1213
|
+
)
|
|
1214
|
+
{
|
|
1215
|
+
if (me->destroying)
|
|
1216
|
+
{
|
|
1217
|
+
goto cleanup;
|
|
1218
|
+
}
|
|
1219
|
+
if (me->idleTimeMillis > 0 &&
|
|
1220
|
+
(amps_now() - lastIdleTime) > me->idleTimeMillis)
|
|
1221
|
+
{
|
|
1222
|
+
lastIdleTime = amps_now();
|
|
1223
|
+
#ifndef _WIN32
|
|
1224
|
+
cancelState = 0;
|
|
1225
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
1226
|
+
#endif
|
|
1227
|
+
me->messageHandler(0L,
|
|
1228
|
+
me->messageHandlerUserData);
|
|
1229
|
+
#ifndef _WIN32
|
|
1230
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
1231
|
+
#endif
|
|
1232
|
+
}
|
|
1233
|
+
#ifdef _WIN32
|
|
1234
|
+
received = recv(me->fd, (char*)readPoint, (int)(end - readPoint), 0);
|
|
1235
|
+
#else
|
|
1236
|
+
received = recv(me->fd, (char*)readPoint, (size_t)(end - readPoint), 0);
|
|
1237
|
+
#endif
|
|
1238
|
+
if (received > 0)
|
|
1239
|
+
{
|
|
1240
|
+
/* Call filter function without the 4 byte size */
|
|
1241
|
+
me->filterFunction(readPoint, (size_t)received, 1, me->filterUserData);
|
|
1242
|
+
readPoint += received;
|
|
1243
|
+
lastReadTime = amps_now();
|
|
1244
|
+
}
|
|
1245
|
+
#ifdef _WIN32
|
|
1246
|
+
else if (received == SOCKET_ERROR)
|
|
1247
|
+
#else
|
|
1248
|
+
else if (received < 0)
|
|
1249
|
+
#endif
|
|
1250
|
+
{
|
|
1251
|
+
int errorcode = GET_ERRNO;
|
|
1252
|
+
if (errorcode == SOCK_ERRORCODE(EINTR))
|
|
1253
|
+
{
|
|
1254
|
+
continue;
|
|
1255
|
+
}
|
|
1256
|
+
/* disconnect if not a timeout error, or the user only set a read timeout, or the
|
|
1257
|
+
* read timeout has been exceeded. */
|
|
1258
|
+
if ( (errorcode != SOCK_ERRORCODE(ETIMEDOUT) && errorcode != SOCK_ERRORCODE(EWOULDBLOCK))
|
|
1259
|
+
|| me->idleTimeMillis == 0
|
|
1260
|
+
|| (me->readTimeoutMillis && amps_now() - lastReadTime > me->readTimeoutMillis))
|
|
1261
|
+
{
|
|
1262
|
+
if (fd != AMPS_INVALID_SOCKET && !me->disconnecting)
|
|
1263
|
+
{
|
|
1264
|
+
shutdown(fd, SHUT_RDWR);
|
|
1265
|
+
amps_tcp_handle_disconnect(me, connectionVersion);
|
|
1266
|
+
}
|
|
1267
|
+
goto cleanup;
|
|
1268
|
+
}
|
|
1269
|
+
continue;
|
|
1270
|
+
}
|
|
1271
|
+
else // received == 0
|
|
1272
|
+
{
|
|
1273
|
+
if (fd != AMPS_INVALID_SOCKET && !me->disconnecting)
|
|
1274
|
+
{
|
|
1275
|
+
shutdown(fd, SHUT_RDWR);
|
|
1276
|
+
amps_tcp_handle_disconnect(me, connectionVersion);
|
|
1277
|
+
}
|
|
1278
|
+
goto cleanup;
|
|
1279
|
+
}
|
|
1280
|
+
while (readPoint >= parsePoint + 4
|
|
1281
|
+
&& fd == me->fd
|
|
1282
|
+
&& me->connectionVersion == connectionVersion)
|
|
1283
|
+
{
|
|
1284
|
+
msglenN = *(unsigned int*)parsePoint;
|
|
1285
|
+
msglen = ntohl(msglenN);
|
|
1286
|
+
if (msglen > MAX_MESSAGE_SIZE)
|
|
1287
|
+
{
|
|
1288
|
+
amps_tcp_handle_stream_corruption(me, connectionVersion);
|
|
1289
|
+
goto cleanup;
|
|
1290
|
+
}
|
|
1291
|
+
if (readPoint >= (parsePoint + msglen + 4))
|
|
1292
|
+
{
|
|
1293
|
+
/* there are enough bytes to parse this guy. */
|
|
1294
|
+
parsePoint += 4;
|
|
1295
|
+
if (amps_message_pre_deserialize(message, me->serializer,
|
|
1296
|
+
(amps_char*)parsePoint, msglen) == AMPS_E_OK)
|
|
1297
|
+
{
|
|
1298
|
+
currentPosition = 0;
|
|
1299
|
+
while (currentPosition < msglen &&
|
|
1300
|
+
me->fd != AMPS_INVALID_SOCKET &&
|
|
1301
|
+
me->connectionVersion == connectionVersion)
|
|
1302
|
+
{
|
|
1303
|
+
if (amps_message_deserialize(message, me->serializer,
|
|
1304
|
+
currentPosition,
|
|
1305
|
+
&bytesRead) != AMPS_E_OK)
|
|
1306
|
+
{
|
|
1307
|
+
amps_tcp_handle_stream_corruption(me, connectionVersion);
|
|
1308
|
+
goto cleanup;
|
|
1309
|
+
}
|
|
1310
|
+
if (me->messageHandler)
|
|
1311
|
+
{
|
|
1312
|
+
#ifndef _WIN32
|
|
1313
|
+
cancelState = 0;
|
|
1314
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
1315
|
+
#endif
|
|
1316
|
+
me->messageHandler(message,
|
|
1317
|
+
me->messageHandlerUserData);
|
|
1318
|
+
#ifndef _WIN32
|
|
1319
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
1320
|
+
#endif
|
|
1321
|
+
}
|
|
1322
|
+
currentPosition += (unsigned int)bytesRead;
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
else
|
|
1326
|
+
{
|
|
1327
|
+
amps_tcp_handle_stream_corruption(me, connectionVersion);
|
|
1328
|
+
goto cleanup;
|
|
1329
|
+
}
|
|
1330
|
+
parsePoint += msglen;
|
|
1331
|
+
}
|
|
1332
|
+
else if (end < buffer + msglen + 4)
|
|
1333
|
+
{
|
|
1334
|
+
/* this message is larger than the buffer
|
|
1335
|
+
* resize to 2* larger of this message or current buffer size */
|
|
1336
|
+
size_t newLength = end < buffer + (msglen * 2) ?
|
|
1337
|
+
msglen * 2 : (size_t)(end - buffer);
|
|
1338
|
+
newBuffer = (unsigned char*)malloc( newLength );
|
|
1339
|
+
if (newBuffer == NULL)
|
|
1340
|
+
{
|
|
1341
|
+
assert(readPoint >= parsePoint);
|
|
1342
|
+
/* stream broken */
|
|
1343
|
+
shutdown(fd, SHUT_RDWR);
|
|
1344
|
+
amps_tcp_handle_disconnect(me, connectionVersion);
|
|
1345
|
+
goto cleanup;
|
|
1346
|
+
}
|
|
1347
|
+
memcpy(newBuffer, parsePoint, (size_t)(readPoint - parsePoint));
|
|
1348
|
+
readPoint = newBuffer + (readPoint - parsePoint);
|
|
1349
|
+
parsePoint = newBuffer;
|
|
1350
|
+
#ifndef _WIN32
|
|
1351
|
+
cancelState = 0;
|
|
1352
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
1353
|
+
#endif
|
|
1354
|
+
free(buffer);
|
|
1355
|
+
buffer = newBuffer;
|
|
1356
|
+
#ifndef _WIN32
|
|
1357
|
+
pthread_setcancelstate(cancelState, &unusedCancelState);
|
|
1358
|
+
#endif
|
|
1359
|
+
end = newBuffer + newLength;
|
|
1360
|
+
assert(readPoint >= parsePoint);
|
|
1361
|
+
break;
|
|
1362
|
+
}
|
|
1363
|
+
else
|
|
1364
|
+
{
|
|
1365
|
+
/* Need to read more data to finish this message
|
|
1366
|
+
* Move what we have to the front of the buffer. */
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
} /*while(readPoint >= parsePoint + 4) */
|
|
1370
|
+
if (readPoint > parsePoint)
|
|
1371
|
+
{
|
|
1372
|
+
memmove(buffer, parsePoint, (size_t)(readPoint - parsePoint));
|
|
1373
|
+
}
|
|
1374
|
+
readPoint = buffer + (readPoint - parsePoint);
|
|
1375
|
+
parsePoint = buffer;
|
|
1376
|
+
} /* while(me->fd != AMPS_INVALID_SOCKET) */
|
|
1377
|
+
cleanup:
|
|
1378
|
+
#ifndef _WIN32
|
|
1379
|
+
cancelState = 0;
|
|
1380
|
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
|
|
1381
|
+
pthread_cleanup_pop(0);
|
|
1382
|
+
pthread_cleanup_pop(0);
|
|
1383
|
+
#endif
|
|
1384
|
+
amps_message_destroy(message);
|
|
1385
|
+
free(buffer);
|
|
1386
|
+
if (me->destroying)
|
|
1387
|
+
{
|
|
1388
|
+
return 0;
|
|
1389
|
+
}
|
|
1390
|
+
#if !defined(_WIN32)
|
|
1391
|
+
pthread_t tid = pthread_self();
|
|
1392
|
+
#if __STDC_VERSION__ >= 201100
|
|
1393
|
+
if (atomic_compare_exchange_strong(&(me->thread), &tid, (pthread_t)0))
|
|
1394
|
+
{
|
|
1395
|
+
pthread_detach(tid);
|
|
1396
|
+
}
|
|
1397
|
+
#else
|
|
1398
|
+
if (__sync_bool_compare_and_swap(&(me->thread), tid, 0))
|
|
1399
|
+
{
|
|
1400
|
+
pthread_detach(tid);
|
|
1401
|
+
}
|
|
1402
|
+
#endif
|
|
1403
|
+
#endif
|
|
1404
|
+
|
|
1405
|
+
return 0;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
amps_result
|
|
1409
|
+
amps_tcp_attempt_reconnect(amps_handle transport, unsigned version)
|
|
1410
|
+
{
|
|
1411
|
+
amps_result res;
|
|
1412
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1413
|
+
if (version == 0)
|
|
1414
|
+
{
|
|
1415
|
+
version = me->connectionVersion;
|
|
1416
|
+
}
|
|
1417
|
+
res = amps_tcp_handle_disconnect(me, version);
|
|
1418
|
+
return res;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/* public-api -- get a socket */
|
|
1422
|
+
AMPS_SOCKET
|
|
1423
|
+
amps_tcp_get_socket(amps_handle transport)
|
|
1424
|
+
{
|
|
1425
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1426
|
+
return me->fd;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
amps_result
|
|
1430
|
+
amps_tcp_update_read_timeout(amps_tcp_t* me)
|
|
1431
|
+
{
|
|
1432
|
+
int timeout = (int)((me->readTimeoutMillis && me->idleTimeMillis) ?
|
|
1433
|
+
AMPS_MIN(me->readTimeoutMillis, me->idleTimeMillis) :
|
|
1434
|
+
AMPS_MAX(me->readTimeoutMillis, me->idleTimeMillis));
|
|
1435
|
+
int rc = 0;
|
|
1436
|
+
#ifdef _WIN32
|
|
1437
|
+
DWORD timeoutMillis = timeout;
|
|
1438
|
+
rc = setsockopt(me->fd, SOL_SOCKET, SO_RCVTIMEO,
|
|
1439
|
+
(const char*)&timeoutMillis, sizeof(DWORD));
|
|
1440
|
+
#else
|
|
1441
|
+
struct timeval tv;
|
|
1442
|
+
tv.tv_sec = timeout / 1000;
|
|
1443
|
+
tv.tv_usec = (timeout % 1000) * 1000;
|
|
1444
|
+
rc = setsockopt(me->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
|
|
1445
|
+
#endif
|
|
1446
|
+
|
|
1447
|
+
#ifdef _WIN32
|
|
1448
|
+
if (rc == SOCKET_ERROR)
|
|
1449
|
+
#else
|
|
1450
|
+
if (rc == -1)
|
|
1451
|
+
#endif
|
|
1452
|
+
{
|
|
1453
|
+
amps_tcp_set_socket_error(me);
|
|
1454
|
+
return AMPS_E_USAGE;
|
|
1455
|
+
}
|
|
1456
|
+
return AMPS_E_OK;
|
|
1457
|
+
}
|
|
1458
|
+
amps_result
|
|
1459
|
+
amps_tcp_set_read_timeout(amps_handle transport, int readTimeout)
|
|
1460
|
+
{
|
|
1461
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1462
|
+
me->readTimeoutMillis = (amps_uint64_t)readTimeout * 1000;
|
|
1463
|
+
return amps_tcp_update_read_timeout(me);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
void
|
|
1468
|
+
amps_tcp_set_filter_function(amps_handle transport, amps_transport_filter_function filterFunction_, void* userdata_)
|
|
1469
|
+
{
|
|
1470
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1471
|
+
me->filterUserData = userdata_;
|
|
1472
|
+
me->filterFunction = filterFunction_ ? filterFunction_ : amps_tcp_noop_filter_function;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
void
|
|
1476
|
+
amps_tcp_set_thread_created_callback(amps_handle transport_, amps_thread_created_callback threadCreatedCallback_, void* userdata_)
|
|
1477
|
+
{
|
|
1478
|
+
amps_tcp_t* me = (amps_tcp_t*)transport_;
|
|
1479
|
+
me->threadCreatedCallbackUserData = userdata_;
|
|
1480
|
+
me->threadCreatedCallback = threadCreatedCallback_;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
amps_result
|
|
1484
|
+
amps_tcp_set_idle_time(amps_handle transport, int millis)
|
|
1485
|
+
{
|
|
1486
|
+
amps_tcp_t* me = (amps_tcp_t*)transport;
|
|
1487
|
+
me->idleTimeMillis = (amps_uint64_t)millis;
|
|
1488
|
+
return amps_tcp_update_read_timeout(me);
|
|
1489
|
+
}
|