You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/09/01 15:03:29 UTC

[01/50] qpid-proton git commit: PROTON-1400: [C++ example] Use multiple threads in broker example if available

Repository: qpid-proton
Updated Branches:
  refs/heads/go1 847a83cc6 -> 3d8368b2e


PROTON-1400: [C++ example] Use multiple threads in broker example if available


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b17671ee
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b17671ee
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b17671ee

Branch: refs/heads/go1
Commit: b17671eefa3a13579f858cd7a72df4231058a429
Parents: 2a60653
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri May 26 17:01:00 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Jul 21 12:50:06 2017 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b17671ee/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index 2cb2b36..01dab36 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -44,11 +44,19 @@
 #include <map>
 #include <string>
 
+#if PN_CPP_SUPPORTS_THREADS
+#include <thread>
+#endif
+
 #include "fake_cpp11.hpp"
 
 // This is a simplified model for a message broker, that only allows for messages to go to a
 // single receiver.
 //
+// This broker is multithread safe and if compiled with C++11 with a multithreaded Proton
+// binding library will use as many threads as there are thread resources available (usually
+// cores)
+//
 // Queues are only created and never destroyed
 //
 // Broker Entities (that need to be individually serialised)
@@ -387,7 +395,12 @@ class broker {
     }
 
     void run() {
-        container_.run(/* std::thread::hardware_concurrency() */);
+#if PN_CPP_SUPPORTS_THREADS
+        std::cout << "starting " << std::thread::hardware_concurrency() << " listening threads\n";
+        container_.run(std::thread::hardware_concurrency());
+#else
+        container_.run();
+#endif
     }
 
   private:


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[06/50] qpid-proton git commit: PROTON-1326: Add standard TLS extensions to CA cert and regenerate dependent certificates

Posted by ac...@apache.org.
PROTON-1326: Add standard TLS extensions to CA cert and regenerate dependent certificates


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/62fee105
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/62fee105
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/62fee105

Branch: refs/heads/go1
Commit: 62fee105ed7d301a1c912bcb7f3a27ae86cc6077
Parents: 5c88566
Author: Cliff Jansen <cj...@redhat.com>
Authored: Wed Aug 2 15:36:44 2017 -0700
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 12:47:44 2017 -0400

----------------------------------------------------------------------
 tests/python/proton_tests/ssl.py                |  16 +++----
 tests/python/proton_tests/ssl_db/README.txt     |  14 +++---
 .../ssl_db/bad-server-certificate.p12           | Bin 1490 -> 1490 bytes
 .../ssl_db/bad-server-certificate.pem           |  22 ++++-----
 .../ssl_db/bad-server-private-key.pem           |  28 +++++------
 .../proton_tests/ssl_db/bad-server.pkcs12       | Bin 1524 -> 1524 bytes
 .../proton_tests/ssl_db/ca-certificate.p12      | Bin 920 -> 992 bytes
 .../proton_tests/ssl_db/ca-certificate.pem      |  20 ++++----
 tests/python/proton_tests/ssl_db/ca.pkcs12      | Bin 1500 -> 1572 bytes
 .../proton_tests/ssl_db/client-certificate.p12  | Bin 1554 -> 1546 bytes
 .../proton_tests/ssl_db/client-certificate.pem  |  29 +++++++-----
 .../proton_tests/ssl_db/client-certificate1.p12 | Bin 1612 -> 1604 bytes
 .../proton_tests/ssl_db/client-certificate1.pem |  31 ++++++------
 .../proton_tests/ssl_db/client-private-key.pem  |  28 +++++------
 .../proton_tests/ssl_db/client-private-key1.pem |  35 ++++----------
 .../proton_tests/ssl_db/client-request.pem      |  24 +++++-----
 .../proton_tests/ssl_db/client-request1.pem     |  26 +++++-----
 tests/python/proton_tests/ssl_db/client.pkcs12  | Bin 2975 -> 1532 bytes
 tests/python/proton_tests/ssl_db/client1.pkcs12 | Bin 0 -> 1646 bytes
 .../proton_tests/ssl_db/server-certificate.p12  | Bin 1562 -> 1562 bytes
 .../proton_tests/ssl_db/server-certificate.pem  |  30 ++++++------
 .../proton_tests/ssl_db/server-private-key.pem  |  28 +++++------
 .../proton_tests/ssl_db/server-request.pem      |  24 +++++-----
 .../ssl_db/server-wc-certificate.p12            | Bin 1632 -> 1624 bytes
 .../ssl_db/server-wc-certificate.pem            |  31 ++++++------
 .../ssl_db/server-wc-private-key.pem            |  47 +++++--------------
 .../proton_tests/ssl_db/server-wc-request.pem   |  26 +++++-----
 .../python/proton_tests/ssl_db/server-wc.pkcs12 | Bin 0 -> 1626 bytes
 tests/python/proton_tests/ssl_db/server.pkcs12  | Bin 2979 -> 1572 bytes
 29 files changed, 215 insertions(+), 244 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl.py b/tests/python/proton_tests/ssl.py
index 566fefa..a8fe837 100644
--- a/tests/python/proton_tests/ssl.py
+++ b/tests/python/proton_tests/ssl.py
@@ -217,18 +217,18 @@ class SslTest(common.Test):
         self.assertEqual("O=Server,CN=A1.Good.Server.domain.com", client.ssl.get_cert_subject())
         self.assertEqual("O=Client,CN=127.0.0.1,C=US,ST=ST,L=City,OU=Dev", server.ssl.get_cert_subject())
 
-        self.assertEqual("03c97341abafe5861d6969c66a190d2846d905d6", server.ssl.get_cert_fingerprint_sha1())
-        self.assertEqual("ad86cc76278e69aef3a5c0dda13fc49831622f92d1364ce1ed361ff842b0143a", server.ssl.get_cert_fingerprint_sha256())
-        self.assertEqual("9fb3340ecee4471534d60be025358cae33ef2cc9442ca8bb7703a68db68d9ffb7963678292996011fa55a9a2524b84a40a11a2778f25797e78e23cf05623218d",
+        self.assertEqual("f78f03ec31317c213dcf607c095242adbf067824", server.ssl.get_cert_fingerprint_sha1())
+        self.assertEqual("3836fd0d7bbc155158997ff336de29545cc1ce4137f8419062ceb8b50fd7a6f9", server.ssl.get_cert_fingerprint_sha256())
+        self.assertEqual("a8390634eb10c7a12ba3ce0837001bc6ae78c7690984f4788cf4430acdb496d5d9e02c8ec39219f5c4dcd908c34861d09481c2faf53b4ccc95dac60e623165c4",
                          server.ssl.get_cert_fingerprint_sha512())
-        self.assertEqual("0d4faa84a0bb6846eaec6b7493916b30", server.ssl.get_cert_fingerprint_md5())
+        self.assertEqual("32b7bc119f61c71d368caaf9a6bf58b2", server.ssl.get_cert_fingerprint_md5())
 
         # Test the various fingerprint algorithms
-        self.assertEqual("f390ddb4dc8a90bcf3528774b622a7f87f7322b5", client.ssl.get_cert_fingerprint_sha1())
-        self.assertEqual("c116e902345c99bc01dda14b7a5f1b8ae6a451eddb23e5336c996ba4d12bc122", client.ssl.get_cert_fingerprint_sha256())
-        self.assertEqual("8941c8ce00824ab7196bb1952787c90ef7f9bd837cbb0bb4823f57fc89e80033c75adc98b78801928d0035bcd6db6ddc9ab6da026c6548a66ede5c4f43f7e166",
+        self.assertEqual("0aab5922c8657a7fb78402b79379506d3d7806ce", client.ssl.get_cert_fingerprint_sha1())
+        self.assertEqual("de5e0c4097f841815a769ce1a30dbe912b83711438a5aaf50001da23cee5a8a8", client.ssl.get_cert_fingerprint_sha256())
+        self.assertEqual("d0aceeb68ab9de57c9e1c21a43a4511c54ec94011e770a523a6352b1374f59c8b58adc93d5cad6f25aa125b5934309a61a25e74a5d5e0cb40b07c7468615944c",
                          client.ssl.get_cert_fingerprint_sha512())
-        self.assertEqual("d008bf05afbc983a3f98ae56e3eba643", client.ssl.get_cert_fingerprint_md5())
+        self.assertEqual("ae0ebcebc1f970fb696ef9f56e3235da", client.ssl.get_cert_fingerprint_md5())
 
         self.assertEqual(None, client.ssl.get_cert_fingerprint(21, SSL.SHA1)) # Should be at least 41
         self.assertEqual(None, client.ssl.get_cert_fingerprint(50, SSL.SHA256)) # Should be at least 65

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/README.txt
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/README.txt b/tests/python/proton_tests/ssl_db/README.txt
index f2ce482..20c92b2 100644
--- a/tests/python/proton_tests/ssl_db/README.txt
+++ b/tests/python/proton_tests/ssl_db/README.txt
@@ -33,7 +33,7 @@ The following bash script can be used to create these certificates (requires key
 rm -f *.pem *.pkcs12
 
 # Create a self-signed certificate for the CA, and a private key to sign certificate requests:
-keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -genkey -dname "O=Trust Me Inc.,CN=Trusted.CA.com" -validity 99999
+keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -genkey -dname "O=Trust Me Inc.,CN=Trusted.CA.com" -validity 99999 -ext bc:c=ca:true,pathlen:0 -ext ku:c=digitalSignature,keyCertSign -ext ExtendedkeyUsage=serverAuth,clientAuth
 openssl pkcs12 -nokeys -passin pass:ca-password -in ca.pkcs12 -passout pass:ca-password -out ca-certificate.pem
 
 # Create a certificate request for the server certificate.  Use the CA's certificate to sign it:
@@ -49,10 +49,10 @@ keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -
 openssl pkcs12 -nocerts -passin pass:client-password -in client.pkcs12 -passout pass:client-password -out client-private-key.pem
 
 # Create another client certificate with a different subject line
-keytool -storetype pkcs12 -keystore client.pkcs12 -storepass client-password -alias client-certificate1 -keypass client-password -genkey  -dname "O=Client,CN=127.0.0.1,C=US,ST=ST,L=City,OU=Dev" -validity 99999
-keytool -storetype pkcs12 -keystore client.pkcs12 -storepass client-password -alias client-certificate1 -keypass client-password -certreq -file client-request1.pem
+keytool -storetype pkcs12 -keystore client1.pkcs12 -storepass client-password -alias client-certificate1 -keypass client-password -genkey  -dname "O=Client,CN=127.0.0.1,C=US,ST=ST,L=City,OU=Dev" -validity 99999
+keytool -storetype pkcs12 -keystore client1.pkcs12 -storepass client-password -alias client-certificate1 -keypass client-password -certreq -file client-request1.pem
 keytool -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile client-request1.pem -outfile client-certificate1.pem
-openssl pkcs12 -nocerts -passin pass:client-password -in client.pkcs12 -passout pass:client-password -out client-private-key1.pem
+openssl pkcs12 -nocerts -passin pass:client-password -in client1.pkcs12 -passout pass:client-password -out client-private-key1.pem
 
 # Create a "bad" certificate - not signed by a trusted authority
 keytool -storetype pkcs12 -keystore bad-server.pkcs12 -storepass server-password -alias bad-server -keypass server-password -genkey -dname "O=Not Trusted Inc,CN=127.0.0.1" -validity 99999
@@ -60,10 +60,10 @@ openssl pkcs12 -nocerts -passin pass:server-password -in bad-server.pkcs12 -pass
 openssl pkcs12 -nokeys  -passin pass:server-password -in bad-server.pkcs12 -passout pass:server-password -out bad-server-certificate.pem
 
 # Create a server certificate with several alternate names, including a wildcarded common name:
-keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs12 -keystore server.pkcs12 -storepass server-password -alias server-wc-certificate -keypass server-password -genkeypair -dname "O=Server,CN=*.prefix*.domain.com" -validity 99999
-keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs12 -keystore server.pkcs12 -storepass server-password -alias server-wc-certificate -keypass server-password -certreq -file server-wc-request.pem
+keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs12 -keystore server-wc.pkcs12 -storepass server-password -alias server-wc-certificate -keypass server-password -genkeypair -dname "O=Server,CN=*.prefix*.domain.com" -validity 99999
+keytool -ext san=dns:alternate.name.one.com,dns:another.name.com -storetype pkcs12 -keystore server-wc.pkcs12 -storepass server-password -alias server-wc-certificate -keypass server-password -certreq -file server-wc-request.pem
 keytool -ext san=dns:alternate.name.one.com,dns:another.name.com  -storetype pkcs12 -keystore ca.pkcs12 -storepass ca-password -alias ca -keypass ca-password -gencert -rfc -validity 99999 -infile server-wc-request.pem -outfile server-wc-certificate.pem
-openssl pkcs12 -nocerts -passin pass:server-password -in server.pkcs12 -passout pass:server-password -out server-wc-private-key.pem
+openssl pkcs12 -nocerts -passin pass:server-password -in server-wc.pkcs12 -passout pass:server-password -out server-wc-private-key.pem
 
 # Create pkcs12 versions of the above certificates (for Windows SChannel)
 # The CA certificate store/DB is created without public keys.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/bad-server-certificate.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/bad-server-certificate.p12 b/tests/python/proton_tests/ssl_db/bad-server-certificate.p12
index 6044350..7906831 100644
Binary files a/tests/python/proton_tests/ssl_db/bad-server-certificate.p12 and b/tests/python/proton_tests/ssl_db/bad-server-certificate.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/bad-server-certificate.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/bad-server-certificate.pem b/tests/python/proton_tests/ssl_db/bad-server-certificate.pem
index 40be354..0aacfa2 100644
--- a/tests/python/proton_tests/ssl_db/bad-server-certificate.pem
+++ b/tests/python/proton_tests/ssl_db/bad-server-certificate.pem
@@ -1,22 +1,22 @@
 Bag Attributes
     friendlyName: bad-server
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 34 36 30 34 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 38 32 39 36 
 subject=/CN=127.0.0.1/O=Not Trusted Inc
 issuer=/CN=127.0.0.1/O=Not Trusted Inc
 -----BEGIN CERTIFICATE-----
-MIICujCCAnigAwIBAgIEfWGDZDALBgcqhkjOOAQDBQAwLjESMBAGA1UEAxMJMTI3
-LjAuMC4xMRgwFgYDVQQKEw9Ob3QgVHJ1c3RlZCBJbmMwIBcNMTMwMzIwMTU0NzA0
-WhgPMjI4NzAxMDIxNTQ3MDRaMC4xEjAQBgNVBAMTCTEyNy4wLjAuMTEYMBYGA1UE
-ChMPTm90IFRydXN0ZWQgSW5jMIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4Ed
+MIICuzCCAnmgAwIBAgIELMpW4jALBgcqhkjOOAQDBQAwLjESMBAGA1UEAxMJMTI3
+LjAuMC4xMRgwFgYDVQQKEw9Ob3QgVHJ1c3RlZCBJbmMwIBcNMTcwODAyMjE1MzM4
+WhgPMjI5MTA1MTcyMTUzMzhaMC4xEjAQBgNVBAMTCTEyNy4wLjAuMTEYMBYGA1UE
+ChMPTm90IFRydXN0ZWQgSW5jMIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4Ed
 dRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs
 14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208Ue
 wwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BY
 HPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+Zx
 BxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx
-+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGATqLV
-argkIbJ0kfQxODtbtouvBPjA2n7VMbmC+YrKQj/YUOjtW/AtD+9lfFy3aekHAMcS
-HFYmo3U6rUCF6sFnnesq6eGi5F5oGVWCI1trUMVx6zFx2zMg+47RpbD0K2JEwzUg
-WJmMgu+ZFvzt76lrlS06K33I260dcbUDECWjKNSjITAfMB0GA1UdDgQWBBTSy0ab
-MCPY1+u0078oxrvoZYwnAzALBgcqhkjOOAQDBQADLwAwLAIUYOCVrWN5+KrdFD6F
-HDAMD/MQ7OkCFByiloyK+lFrZI+AYo/xEdbJLqcH
++2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAK3E
+5j/UaiVHJYAf3DAIl5hjTZcChTp57GjODdfDteHeDh85HFyW0kxmXyhpUdODzAgG
+THhpxy/+Kkd8jmUBVFnU1EXByvGORBfnJkMTkuhmk9veytxlskQ0tQV8gmRNb0Xe
+hie7T9UT8TQJy9mPS74pSuviFSx0Hz0dKGi0eVUYoyEwHzAdBgNVHQ4EFgQUg2PE
+qycdV1oxVaA33ULDrVdSjhkwCwYHKoZIzjgEAwUAAy8AMCwCFGybqSwG3TauRJVw
+XA/xeSxpYbcBAhQ6ylf9XZAvM7tMyQQTcDAkmt+YWQ==
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/bad-server-private-key.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/bad-server-private-key.pem b/tests/python/proton_tests/ssl_db/bad-server-private-key.pem
index 3cd8f71..3a30d41 100644
--- a/tests/python/proton_tests/ssl_db/bad-server-private-key.pem
+++ b/tests/python/proton_tests/ssl_db/bad-server-private-key.pem
@@ -1,19 +1,15 @@
 Bag Attributes
     friendlyName: bad-server
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 34 36 30 34 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 38 32 39 36 
 Key Attributes: <No Attributes>
------BEGIN DSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,AB078D4A74BE8031
-
-iEW6u5kMfaX9SIynirmIQk6EvqrGjl8uhGC5k1UHBoQRnYUy/wrz9Ufcw4JLXXmo
-8CoX1JCwo/gvlqV3KSszujgkCvCndhlLoe5PwbhMsSSiruTkt9b70bOHxG5AHp/m
-sr/0cFgs+O1USt9IVmAXj6+ALndWfOBSVH7J40BTDHCGbizB/QRnAk6+VWW2tQRZ
-mU2xL1drY7n9bvF4O9faDe5C2C0v1+asswXnJmZnQVsTnA5+kwQok6uLfJjVWt7j
-WS9ME5nIJSOi/ZkIyr2cr4m4TPbPw/UB+funT1/OKg8iyMyUvjwV3fopjo/9Sz/S
-Tpt+sjUJelL7VBBkuppiZDHjPQ/g0IAc7+HEbc1or8h15AIiSWxEg/HRUtZqbsgC
-UyW+5qvKyYrPzZYkkJIeRLwkMEAU1sdmHBVutALc9xUyVR8jXJtXNu3V82NQ7otv
-pRlLpAs4Fn6SOIKAJvL6YdxgSiZFdta/Ory2VXqopJad+EEPPprf8ndk3Mv38l7M
-gIMQdZD8hhWaPw8zhXfhfnjz7ejPhtgQznkyzJPIFtbrq2HUZKuKpOBkCFfu/E4s
-k6PC6aW9pNGQW0PqdKuHPA==
------END DSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIqgLLe7iT+1wCAggA
+MBQGCCqGSIb3DQMHBAhg98ZJQMtngwSCAVCdhdOMr+VVTNaIPSy4nSwdRTlXIuRa
+4wPi+07mToJmEtGfpJ4MPjDF9yRptVQI4RoN/RrLl0WX/HNZ5U4JluL0j68+JB1d
+MoeSRiRc+Yd2vxey8reBrvx1m1mB3LXvm38oZVDFrQ9FNGK09EtTLN1rqckr1fxQ
+Imcvb63nu5UZB8WMCVfKqe9Zm9dQlsSlp3M5OCRm296Xsr0eWwe2W1/rJiKMZN7x
+eJMf4pWVrBHoi6VJHAEA7ZvhRfcHkSbyze5ouDpKbMZS9gq38Hs4d+wkxe9x3emx
+6OvppcpBolZhntF1vJXUXMc6D5Pw3mGEsRGwcMJqWCc8XJTkyP0ylNFNyaHaz0oC
+jSWmUu0s5628K+m8nGY4X7msfOddTA16W6mODjE2ddlTqwTFu2CYBk3WbprBRXo0
+ionZQTPTqcM0UR3KyF9CHRZbnQ/d7bk57/w=
+-----END ENCRYPTED PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/bad-server.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/bad-server.pkcs12 b/tests/python/proton_tests/ssl_db/bad-server.pkcs12
index b5e0cbc..dea2143 100644
Binary files a/tests/python/proton_tests/ssl_db/bad-server.pkcs12 and b/tests/python/proton_tests/ssl_db/bad-server.pkcs12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/ca-certificate.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/ca-certificate.p12 b/tests/python/proton_tests/ssl_db/ca-certificate.p12
index 539b278..767b24d 100644
Binary files a/tests/python/proton_tests/ssl_db/ca-certificate.p12 and b/tests/python/proton_tests/ssl_db/ca-certificate.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/ca-certificate.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/ca-certificate.pem b/tests/python/proton_tests/ssl_db/ca-certificate.pem
index ce545d8..1461f25 100644
--- a/tests/python/proton_tests/ssl_db/ca-certificate.pem
+++ b/tests/python/proton_tests/ssl_db/ca-certificate.pem
@@ -1,12 +1,12 @@
 Bag Attributes
     friendlyName: ca
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 31 39 32 35 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 36 34 37 32 
 subject=/CN=Trusted.CA.com/O=Trust Me Inc.
 issuer=/CN=Trusted.CA.com/O=Trust Me Inc.
 -----BEGIN CERTIFICATE-----
-MIICwTCCAn+gAwIBAgIEe/AadjALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
-c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTMwMzIwMTU0
-NzAxWhgPMjI4NzAxMDIxNTQ3MDFaMDExFzAVBgNVBAMTDlRydXN0ZWQuQ0EuY29t
+MIIDBDCCAsKgAwIBAgIEBGGY1zALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
+c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTcwODAyMjE1
+MzM2WhgPMjI5MTA1MTcyMTUzMzZaMDExFzAVBgNVBAMTDlRydXN0ZWQuQ0EuY29t
 MRYwFAYDVQQKEw1UcnVzdCBNZSBJbmMuMIIBuDCCASwGByqGSM44BAEwggEfAoGB
 AP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6
 MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E
@@ -14,9 +14,11 @@ MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E
 ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeO
 utRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/
 C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUA
-AoGBAOAw2uKAz6k56DRzZBjSJ/W8OfYg6LV64IliFhE93hhseHF7iOaCycuVocQA
-fJVO0DDtssf0CM3uCxPNiEbDrdfUu75BCvX6h/CT/Qzgf+eLldJSHtAJjU1zSxN+
-GtIBB8cQhCdh5sQL6sEJYgOiIxdW1jKf3/n0MuD6qTXi/9f1oyEwHzAdBgNVHQ4E
-FgQUqxC+jvigfpiR6M3fb6XppgGxFJYwCwYHKoZIzjgEAwUAAy8AMCwCFD2ikCZi
-8V4H+LuqCBD4Vz0ug0ntAhQ4kE+VGY7YK++kDZ8jHcfyDUNVAw==
+AoGBALsRT+tH1c+TC78EYtPh+KQ0DosKKtxeSRos4eQ49erdI+tYhzeqN3Ebmeky
+TWfGjjU64PGRFDNGjpf9l7Yo22jk9U5zIFkFp5gP9DVBHrOrh8mdT+/oBhhVHxI5
+rWLqSjI/zXhRzRwueR81p0D3XJlV3g/xlOlWALoRnUWpDAo3o2QwYjASBgNVHRMB
+Af8ECDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV
+HQ8BAf8EBAMCAoQwHQYDVR0OBBYEFLI2ezwilYHGS5MRPMWlifHH+Y5qMAsGByqG
+SM44BAMFAAMvADAsAhRxomjEvDfhe1p+D6KLc0IGjDNgtgIUIZXb0/Fpzy6dpCwe
+Ay+soxvpfMU=
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/ca.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/ca.pkcs12 b/tests/python/proton_tests/ssl_db/ca.pkcs12
index 4f69505..d9ca00c 100644
Binary files a/tests/python/proton_tests/ssl_db/ca.pkcs12 and b/tests/python/proton_tests/ssl_db/ca.pkcs12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-certificate.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-certificate.p12 b/tests/python/proton_tests/ssl_db/client-certificate.p12
index be820ed..82271f9 100644
Binary files a/tests/python/proton_tests/ssl_db/client-certificate.p12 and b/tests/python/proton_tests/ssl_db/client-certificate.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-certificate.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-certificate.pem b/tests/python/proton_tests/ssl_db/client-certificate.pem
index ab70472..5b4aa86 100644
--- a/tests/python/proton_tests/ssl_db/client-certificate.pem
+++ b/tests/python/proton_tests/ssl_db/client-certificate.pem
@@ -1,15 +1,18 @@
 -----BEGIN CERTIFICATE-----
-MIIC2DCCApSgAwIBAgIETM/4+TALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1c3RlZC5DQS5j
-b20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTMwMzIwMTU0NzA0WhgPMjI4NzAxMDIxNTQ3
-MDRaMCUxEjAQBgNVBAMTCTEyNy4wLjAuMTEPMA0GA1UEChMGQ2xpZW50MIIBuDCCASwGByqGSM44
-BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6
-MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1
-VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+Gghdab
-Pd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim
-4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1Ul
-ZAFMO/7PSSoDgYUAAoGBAPYvFAX9tcVv9T+rsbF3pD3++ji8PD6sPFmH5RQ8RyZXDzs5jdku4AVb
-BtmLp+swmQ/NnQRvoR6lLvfB5gOzykPU/LrtEELEbp1ScXqNwTQky2OkX7+YGSKnliWZm5v72rtt
-gGL9j+c/jKcDAj7Z+v2kHugbTuZ09AxXLQ9cPxWxo0IwQDAdBgNVHQ4EFgQUaLUIuA06KCstRynf
-6L6X8+A+/ygwHwYDVR0jBBgwFoAUqxC+jvigfpiR6M3fb6XppgGxFJYwCwYHKoZIzjgEAwUAAzEA
-MC4CFQCWcpy1LVRqK+Udtq4qCpIKDZwTdwIVAJS+GitAJeY2L1ltlgi+cpRLIgGU
+MIIC1jCCApOgAwIBAgIEeg2f8DALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
+c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTcwODAyMjE1
+MzM3WhgPMjI5MTA1MTcyMTUzMzdaMCUxEjAQBgNVBAMTCTEyNy4wLjAuMTEPMA0G
+A1UEChMGQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9K
+nC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00
+b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNa
+FpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA
+9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJ
+FnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
+zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAJ3g1ohpHgoxH
+3Yj0SIfiPcUaM5FIszemFwQ2FZoG/J7MiVIw442JheTR/iEB3LYheHBp7ToqhaMY
+NYidcxxUzgZJs3worXqAuUgDdbDcW6AjQ4olyGVt7sX9OL2amMq9BFCIt7SlyDKW
+8Accx46H+8BffMdCu56yw5WQtZ3cPD2jQjBAMB8GA1UdIwQYMBaAFLI2ezwilYHG
+S5MRPMWlifHH+Y5qMB0GA1UdDgQWBBQg7FbClmtrSAHA9lR8E7uexl5p1jALBgcq
+hkjOOAQDBQADMAAwLQIVAIpUbUYyA3DisZyENQwcN0rDQ+FyAhRPcfg9Slb6MfO4
+SBFqOiesk+cpqw==
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-certificate1.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-certificate1.p12 b/tests/python/proton_tests/ssl_db/client-certificate1.p12
index bb5c567..d35f88f 100644
Binary files a/tests/python/proton_tests/ssl_db/client-certificate1.p12 and b/tests/python/proton_tests/ssl_db/client-certificate1.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-certificate1.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-certificate1.pem b/tests/python/proton_tests/ssl_db/client-certificate1.pem
index 9b136ac..f4549a4 100644
--- a/tests/python/proton_tests/ssl_db/client-certificate1.pem
+++ b/tests/python/proton_tests/ssl_db/client-certificate1.pem
@@ -1,16 +1,19 @@
 -----BEGIN CERTIFICATE-----
-MIIDDDCCAsqgAwIBAgIEGzO0QTALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1c3RlZC5DQS5j
-b20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTYwMTEzMjIxOTE4WhgPMjI4OTEwMjcyMjE5
-MThaMFwxDDAKBgNVBAsTA0RldjENMAsGA1UEBxMEQ2l0eTELMAkGA1UECBMCU1QxCzAJBgNVBAYT
-AlVTMRIwEAYDVQQDEwkxMjcuMC4wLjExDzANBgNVBAoTBkNsaWVudDCCAbcwggEsBgcqhkjOOAQB
-MIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2
-y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQT
-WhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3e
-y7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8
-FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB
-TDv+z0kqA4GEAAKBgAsLC8PBAEzv2Vl4Ji1k3mVI49YzWsz6Yh/HPCjy1s9aueNRM0ZlhQWv3TIw
-gOcbIoUp10y4Rc4fsVIrjpoC4tmZCZmkimnoa+Lp0whDUlwWrEFZ971NqkQsmagfpuXVYeE4hB1Y
-OoETBpybd+liDaikymLWFqwd9XmuQlysEhWCo0IwQDAfBgNVHSMEGDAWgBSrEL6O+KB+mJHozd9v
-pemmAbEUljAdBgNVHQ4EFgQUBlPIzSsmgK6IwNtZitN/NrQEztMwCwYHKoZIzjgEAwUAAy8AMCwC
-FGxlMH0zwjoCJMfntSRAwxM+4JK7AhR6Y/CgFBrJCgDFAYkFH8ucHoii6w==
+MIIDDDCCAsqgAwIBAgIEBmzTzzALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
+c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTcwODAyMjE1
+MzM4WhgPMjI5MTA1MTcyMTUzMzhaMFwxDDAKBgNVBAsTA0RldjENMAsGA1UEBxME
+Q2l0eTELMAkGA1UECBMCU1QxCzAJBgNVBAYTAlVTMRIwEAYDVQQDEwkxMjcuMC4w
+LjExDzANBgNVBAoTBkNsaWVudDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OB
+HXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tV
+bNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPF
+HsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvw
+WBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/m
+cQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi
+8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GEAAKBgHVu
+urVq1FFws/JN+I3yfA2RVmFwlYJID8yyO9lkHBPBDE0dqfFBF6F3nwsCiZF0n/v4
+od6MuuRSplV4kZH0jOOVw7e9cF2RNd/KahsIpm/Oq5aosm6W7KDK/xIwNyW+3DFt
+TGDTOZ6ejVMgGR2rAD+FEp2yycJACQBP1GtTSFXTo0IwQDAfBgNVHSMEGDAWgBSy
+Nns8IpWBxkuTETzFpYnxx/mOajAdBgNVHQ4EFgQUz4cx+zNqsCmWpBU2dw8GHO33
++eEwCwYHKoZIzjgEAwUAAy8AMCwCFCsfHJPB4Tq6qX5U+DZBc3jmLBiXAhRF17Dz
+fq+AxqyQ9PvTtH3UbFh1hQ==
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-private-key.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-private-key.pem b/tests/python/proton_tests/ssl_db/client-private-key.pem
index 6be5166..b6256e7 100644
--- a/tests/python/proton_tests/ssl_db/client-private-key.pem
+++ b/tests/python/proton_tests/ssl_db/client-private-key.pem
@@ -1,19 +1,15 @@
 Bag Attributes
     friendlyName: client-certificate
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 33 34 36 33 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 37 32 33 39 
 Key Attributes: <No Attributes>
------BEGIN DSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,357362201C460FE9
-
-L7ubHRpBWVYpCicB5srjF7AFpTDN/faMbz9FuvFmA/8HBhwOrlbKau0ASoDqvGbq
-Gcx4BqXvNx22gJbu4S8224elyov7beI58VQ4/k1kJROa7Gyi84RpqxmdScCaYrNE
-2beGa+AshN2vgwtRzeUDHxjKj/vPlDjdBq3cT88W7zrfm7J2E4HuNtwTwQ+EhBh9
-c5P+yxOmF93AxQzywGQPkmhXfhSHkoUWX/7NNtdhL07m4CY8nWwrGfHm828/d20Y
-eaGhyuxiC9hN5mhSct0THIyLSTz6fm7sJLZzDM1poqEKVdZQyytfUkpzCjDik3em
-y1Pjymve8QcrWEN4SLO7V7J8Zkv2N9AjJt/XiZWAdn13Gj+qLs/DI//AtlthqntJ
-qH0rZeV0DPf6tKZmj3sTegOdmvv8hAVX/DkEwC9wkxhKU7xHmBzX+uMqIauL70GH
-F4w9dVGOCSFNFP3bwoDCotJbLHx/vMpu/1AMibXUnPVQkZaWf3xlmz7ufJZh3Vhq
-buAuLw6t2ji8wnpOfOOB9hm2cGBcPlw2s3AHiM66vhLgOvtKQbGxMTni6g/kya5u
-BuWOjFk54PyY1DM54VK0FHoBxcvMmLo5
------END DSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIHmVKa1dEtm4CAggA
+MBQGCCqGSIb3DQMHBAgpc0Ay33xL9ASCAVBJ8D5DVRd0d6t3gSvTFBAflpUROv2/
+pQlMLGbGlJIoEPyMIc9/GcgS7U19nMdoJjI1TuT/hGwObualnRRjY6KL5cbK2oUQ
+371yUs6jGIQxtCeb1WgKpA/FKw9jRO7Tg5ztObItPiSQvkOcssfdRJYI1+W+ovj+
+j1BKMkJu197twIChYaz+3ppJzrh3qlqFgdRdE9H04ffWpNaZ6aOIIJHPMuZ8FScu
+bQyvD9JjI+JWJUaCyp/3dxxxVrZ3vu8i6LmrL6Nm9IkJtFMZOfgPkoRLML2DWKqB
+1qLk/Z45/THXDAxrPggFfqMvuctwJmtAGvo3MIbfCi+aewJE6/DjlSHDv6wGvOGB
+T5golvZ5siahHqwmufSQG8ZTsGcpu/jCA5ipIvcTVgWIxscNc2Yx9FDNWVNzUcTy
+ctRX6DS+s7rAy9ISjch4BbAtI7yALFt63eU=
+-----END ENCRYPTED PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-private-key1.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-private-key1.pem b/tests/python/proton_tests/ssl_db/client-private-key1.pem
index b847a30..544d2ae 100644
--- a/tests/python/proton_tests/ssl_db/client-private-key1.pem
+++ b/tests/python/proton_tests/ssl_db/client-private-key1.pem
@@ -1,30 +1,15 @@
 Bag Attributes
     friendlyName: client-certificate1
-    localKeyID: 54 69 6D 65 20 31 34 35 32 37 32 33 35 33 33 32 36 32 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 37 37 37 32 
 Key Attributes: <No Attributes>
 -----BEGIN ENCRYPTED PRIVATE KEY-----
-MIIBnjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIY3SXzWdZ9g8CAggA
-MBQGCCqGSIb3DQMHBAgNjO/Glke9hgSCAVgtzKi1oXuMXuv2D7H2Mn4OQIevpn7S
-WMvJmFSNiNvIAmKhJjPyaPKYYgCMALYi+mvFWfv/EaQuiovX45GTMrCFM4MdUuo0
-YCTEOB8ehrHEoyy76U61wN+EfdEYlS3/KfnbdnhHD342jdV+yO5T5pgpacu+5Inz
-IzvcBrGFehqTI9fq3Zkl1dOEpfrfahrO/8rq+UZQzqjIaiWi6irSFihQNsvVKUkd
-TLUDmSX591+dUblMlH8g/V3pY9EAEjdxGuY2mEqEe/B2WH74s3xyOb0UljkC6AmE
-MYGGXR8XK1RYrKQp3SwUMlisz72JhrfzvUlYEMRuclNKNNjyEPBO85iXLPFmSNQ5
-4H/N/P3lO6WXny1Ea46kc5+ulC2CQkvetZhWcOtHvf4WRVt6wx2xQDhZwcUM7zDk
-uUV8pFqT1iUmx8k4Zasp1hNi0zSLnf3mKVPF3EFDTbU8qQ==
------END ENCRYPTED PRIVATE KEY-----
-Bag Attributes
-    friendlyName: client-certificate
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 33 34 36 33 
-Key Attributes: <No Attributes>
------BEGIN ENCRYPTED PRIVATE KEY-----
-MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIFcxTKG24KKICAggA
-MBQGCCqGSIb3DQMHBAh/2ViSC9U9qQSCAVCM9V+dw+CnGKguFH5LYpCtoepRaDvC
-yTsGPmmJOh+wDObU8U+4kEYdGLCJgqblXWJEt9uAVOwg3EK30mSCT33N/VIbSbgv
-LadI7WjqtMKU5xJGscb71uGUdmiJrXLtp/1TnwNZM48QGpzuj+Eegn7j3BRX7bSS
-EwrUxqSm67ahi1/R2driAuZQxdvotBQNUq7ADZQVAISKMhblJs3Z7mX4EBxveS/f
-YIwDQ+ZfBfOnEhSNFxk6/zIxWqA0/3gFY2/M1uI3TvXuuOHags6+QuHHnpgrV7J+
-1Oaq5cAD1OlGd/fqerTxRdIUQMVixFVqMYZUEnqeiWOY/CxkynHh7MUT1/LaUN2d
-7QVvpVXHvTvG4BPlApxIVV4/LoeYd4+jEkr/w7sq0msuMRP1qu1aNnl4XRtrvFOY
-hDpaYO/Lp7tv9r9geUszmWvlqkHm2nPocJo=
+MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIg1n9vdGttqoCAggA
+MBQGCCqGSIb3DQMHBAgRjlrRQfGcLQSCAVChui/M+36/e0WzeM79aJV7YZds/OJY
+gprtJ2g5Cxb1L9hymwgxJtOAaRUqLUcfLHcKSxA+MaB+Ij+/8TH+miq0zZ9q0jZV
+BAm56FNgUjW0nPLueTNhWzVVfQU6H9Tj33OuKm1PQo84Af3OPMtE03pvGDPEAPbH
+a72HUgZyI7WTux4wpxfvUEVkT5OXgBHrFlqXiHHCI+9kqBXMCV3oHgZBcO+dqPKS
+rlaTY7xoQWLenB6EQeYopMA2GNUVtzB3y6/nX2z0Yp5oHqKPBNOyFlVmwCrENN1/
+qnrFfzVbnksWLKhg9O+TPsId1UIZVvBh67y5N5IZRrpuE03qd2BScKM/Tn6vkWNB
+Eus74Vba5vw9prauRC45FVgDe2YYYoULYPfhXWSiiWHDNKOBlz3l3hGlZsC8wKe5
+QlV5bVcOTfGIaBkD7SQyfRjMr8SWj4WMw1M=
 -----END ENCRYPTED PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-request.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-request.pem b/tests/python/proton_tests/ssl_db/client-request.pem
index 9aa3c00..1265153 100644
--- a/tests/python/proton_tests/ssl_db/client-request.pem
+++ b/tests/python/proton_tests/ssl_db/client-request.pem
@@ -1,13 +1,15 @@
 -----BEGIN NEW CERTIFICATE REQUEST-----
-MIICWjCCAhgCAQAwJTESMBAGA1UEAxMJMTI3LjAuMC4xMQ8wDQYDVQQKEwZDbGllbnQwggG4MIIB
-LAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZ
-PY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7
-g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKB
-gQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgW
-E7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8G
-kotmXoB7VSVkAUw7/s9JKgOBhQACgYEA9i8UBf21xW/1P6uxsXekPf76OLw8Pqw8WYflFDxHJlcP
-OzmN2S7gBVsG2Yun6zCZD82dBG+hHqUu98HmA7PKQ9T8uu0QQsRunVJxeo3BNCTLY6Rfv5gZIqeW
-JZmbm/vau22AYv2P5z+MpwMCPtn6/aQe6BtO5nT0DFctD1w/FbGgMDAuBgkqhkiG9w0BCQ4xITAf
-MB0GA1UdDgQWBBRotQi4DTooKy1HKd/ovpfz4D7/KDALBgcqhkjOOAQDBQADLwAwLAIUWRqolXje
-1mMzoode9hn5ngboHpsCFBIGJt8s5WYcW3j4JVCaoqUypJB/
+MIICWTCCAhcCAQAwJTESMBAGA1UEAxMJMTI3LjAuMC4xMQ8wDQYDVQQKEwZDbGll
+bnQwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I8
+70QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWk
+n5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HX
+Ku/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8
+q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fP
+CTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD
+3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhAACgYAneDWiGkeCjEfdiPRIh+I9xRoz
+kUizN6YXBDYVmgb8nsyJUjDjjYmF5NH+IQHctiF4cGntOiqFoxg1iJ1zHFTOBkmz
+fCiteoC5SAN1sNxboCNDiiXIZW3uxf04vZqYyr0EUIi3tKXIMpbwBxzHjof7wF98
+x0K7nrLDlZC1ndw8PaAwMC4GCSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFCDsVsKW
+a2tIAcD2VHwTu57GXmnWMAsGByqGSM44BAMFAAMvADAsAhQY5Zy4fQcy/SZOJ2Ix
+cl3/QfimvQIUVvSdet7NKWzMQoBDhlJTdTzJvE8=
 -----END NEW CERTIFICATE REQUEST-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client-request1.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client-request1.pem b/tests/python/proton_tests/ssl_db/client-request1.pem
index 2bafb09..c73275f 100644
--- a/tests/python/proton_tests/ssl_db/client-request1.pem
+++ b/tests/python/proton_tests/ssl_db/client-request1.pem
@@ -1,14 +1,16 @@
 -----BEGIN NEW CERTIFICATE REQUEST-----
-MIICkDCCAk4CAQAwXDEMMAoGA1UECxMDRGV2MQ0wCwYDVQQHEwRDaXR5MQswCQYDVQQIEwJTVDEL
-MAkGA1UEBhMCVVMxEjAQBgNVBAMTCTEyNy4wLjAuMTEPMA0GA1UEChMGQ2xpZW50MIIBtzCCASwG
-ByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2N
-WPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P2
-08UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA
-9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
-zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL
-Zl6Ae1UlZAFMO/7PSSoDgYQAAoGACwsLw8EATO/ZWXgmLWTeZUjj1jNazPpiH8c8KPLWz1q541Ez
-RmWFBa/dMjCA5xsihSnXTLhFzh+xUiuOmgLi2ZkJmaSKaehr4unTCENSXBasQVn3vU2qRCyZqB+m
-5dVh4TiEHVg6gRMGnJt36WINqKTKYtYWrB31ea5CXKwSFYKgMDAuBgkqhkiG9w0BCQ4xITAfMB0G
-A1UdDgQWBBQGU8jNKyaArojA21mK0382tATO0zALBgcqhkjOOAQDBQADLwAwLAIUIH29x1jT3akD
-Y1rLTr6o5z5c++cCFAG+rzzJYzmBAhwTQsKtoQPtVCwA
+MIICkTCCAk4CAQAwXDEMMAoGA1UECxMDRGV2MQ0wCwYDVQQHEwRDaXR5MQswCQYD
+VQQIEwJTVDELMAkGA1UEBhMCVVMxEjAQBgNVBAMTCTEyNy4wLjAuMTEPMA0GA1UE
+ChMGQ2xpZW50MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s
+5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/Jm
+YLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy
+9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+Gg
+hdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj
+6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTx
+vqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAdW66tWrUUXCz8k34
+jfJ8DZFWYXCVgkgPzLI72WQcE8EMTR2p8UEXoXefCwKJkXSf+/ih3oy65FKmVXiR
+kfSM45XDt71wXZE138pqGwimb86rlqiybpbsoMr/EjA3Jb7cMW1MYNM5np6NUyAZ
+HasAP4USnbLJwkAJAE/Ua1NIVdOgMDAuBgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQW
+BBTPhzH7M2qwKZakFTZ3DwYc7ff54TALBgcqhkjOOAQDBQADMAAwLQIUFs17HaTm
+vest72/4Caoo1sH39n0CFQCR680PPwr3lZ5jjEOp+n4htQNUvw==
 -----END NEW CERTIFICATE REQUEST-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client.pkcs12 b/tests/python/proton_tests/ssl_db/client.pkcs12
index 87d6690..575a551 100644
Binary files a/tests/python/proton_tests/ssl_db/client.pkcs12 and b/tests/python/proton_tests/ssl_db/client.pkcs12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/client1.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/client1.pkcs12 b/tests/python/proton_tests/ssl_db/client1.pkcs12
new file mode 100644
index 0000000..0e7c888
Binary files /dev/null and b/tests/python/proton_tests/ssl_db/client1.pkcs12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-certificate.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-certificate.p12 b/tests/python/proton_tests/ssl_db/server-certificate.p12
index d470366..cacfa89 100644
Binary files a/tests/python/proton_tests/ssl_db/server-certificate.p12 and b/tests/python/proton_tests/ssl_db/server-certificate.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-certificate.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-certificate.pem b/tests/python/proton_tests/ssl_db/server-certificate.pem
index 512055f..e324df5 100644
--- a/tests/python/proton_tests/ssl_db/server-certificate.pem
+++ b/tests/python/proton_tests/ssl_db/server-certificate.pem
@@ -1,16 +1,18 @@
 -----BEGIN CERTIFICATE-----
-MIIC5TCCAqOgAwIBAgIEGK67vDALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1c3RlZC5DQS5j
-b20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTMwMzIwMTU0NzAzWhgPMjI4NzAxMDIxNTQ3
-MDNaMDUxIjAgBgNVBAMTGUExLkdvb2QuU2VydmVyLmRvbWFpbi5jb20xDzANBgNVBAoTBlNlcnZl
-cjCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEm
-aUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX
-58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLr
-hAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0
-SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJ
-qIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GEAAKBgGd51fWwKIVM6wIsVk0vo86Hq3q2gxlP0STl
-/EzEBew9buSMXPCqQvQIhw/Ud6/f/Q0KxctPn8MqO++jCCSYMYH5d1ME85X9QM2mh4/xejYWQdUl
-qJKkHPo6MbLgEfQY7UxXxMq9Ekij/T6MyS1Rd9xwCCf2wJhjV6Jq35KplnWMo0IwQDAdBgNVHQ4E
-FgQUlZgov7xbp4kcuwMI7d7AAz4DH8YwHwYDVR0jBBgwFoAUqxC+jvigfpiR6M3fb6XppgGxFJYw
-CwYHKoZIzjgEAwUAAy8AMCwCFBTG8MXcRKCTW6gBKIjp23BGWJfIAhRLFMZ4oYLsdCImFOl7/Hi3
-NdK9cw==
+MIIC5jCCAqSgAwIBAgIEX8z6MDALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
+c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTcwODAyMjE1
+MzM3WhgPMjI5MTA1MTcyMTUzMzdaMDUxIjAgBgNVBAMTGUExLkdvb2QuU2VydmVy
+LmRvbWFpbi5jb20xDzANBgNVBAoTBlNlcnZlcjCCAbgwggEsBgcqhkjOOAQBMIIB
+HwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6
+v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58ao
+phUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM
+spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4Jn
+UVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1
+kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kq
+A4GFAAKBgQCERpy6RrkNHpgXT/uL9gN/IgwY7kp3Iwzr1lrqo+HqmydE+Cz9uqPH
+VyxjX7nHVrdwl7xgsoki3QyoKcrZfTL1oS79kodWG7t6CyOtj2L3KGMUdIlqWepZ
+wzCKTWrb07VjpqhMh0Qh8+IqEmvfC/4UVOec9alX0NO/ckDbIBhITqNCMEAwHwYD
+VR0jBBgwFoAUsjZ7PCKVgcZLkxE8xaWJ8cf5jmowHQYDVR0OBBYEFBhEDdcBRqn5
+wFEbAad559yrQPE7MAsGByqGSM44BAMFAAMvADAsAhRuMRxWMKxy3USjfSFn47H4
+Z5VIHgIUB2i6+RQi7dHOEQYKKmxdQvAPA9M=
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-private-key.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-private-key.pem b/tests/python/proton_tests/ssl_db/server-private-key.pem
index e4b4f5e..e68a39d 100644
--- a/tests/python/proton_tests/ssl_db/server-private-key.pem
+++ b/tests/python/proton_tests/ssl_db/server-private-key.pem
@@ -1,19 +1,15 @@
 Bag Attributes
     friendlyName: server-certificate
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 32 33 34 35 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 36 36 35 36 
 Key Attributes: <No Attributes>
------BEGIN DSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,58EA06E340D4B8FB
-
-cYo9OeXX1j8HazOZUVLCLaA5hbVd92OY5JufYXXzJsyfoBSWsH2IPIWw6oolJfD/
-Nd53xpl3gW5AuVk6gZkfV/qUQeymTJPtQUPjfgEEK50s7PCj5GKNL63/SOVVYudc
-HOczB9wb5VrVstKBdPe5SkxtOoMGka76uXDAaApezpHcwxFKyzmixevc8f7/3Q7q
-02TCaufgzAKYzO9sjY/U8nR0qvn1Cnx/AO8Lwt0K3mEExqCR0R7yyW1GwRRiMdDe
-x7QnYosHScSao7f1ToMLYPGdtMSUWBt1m10hrcPaCzvH5Zqy7w+wqQp5mG8dHp7o
-v767dWezeY1k8RpKiTZHlKZCksfqWr3TSgICOcFZrrQbxsCjIlpSW+65uhrDtUN1
-CqJmTzeUeRFBKGGdBMe+I1gUxsVohHyQzxyxUMwmu3fQQipSsvEyjq2O3CxaoPyi
-bbvbmvhdHGhjOQXeSJpZ8QsKRCUbeQQbaEzD6cGZv/VVzgYZfbEFz3xAb+nqVeKA
-JftTQeful80+cpUNalFMY7ozhbXznLwKGB4X5EnC5COLhJJdXOTEx9F0ASwvdi1p
-hvNdZ1wiRQvyvLyhvI2wQw==
------END DSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI6jwDH/9bZYMCAggA
+MBQGCCqGSIb3DQMHBAgbIQ8UrRfmAgSCAVDejPh9sT2PMvDjjzXG6xpSmBPNZRiz
+f2k2a9EaI8L4xadveiZTzOpk2C/nltMCNY2Vwf/LMtbvcLiadBRWM/4Uf5fvL/94
+zlKE77wPSWK1R+btZm0KIaA+EPAvnIGcjHlcSU58eQexwVlMXJ9pdeHm9KWbV1D+
+PjrlJ+SDq7OSGprTCz9r+gQ7Fy2Oe9OKc92tE29QD2AZXtSodvY9CosXCx4cqXr3
+ey+HXmVXJohsL89NycL80TvkxppqZ1hT3DZMkrFg2jFPz505rzE48y62FMoKNCjQ
+6HXvsniWYXf7ipr+A4/diSSMBr/zmA+H+ZHKlNO8FJqZ8eI1eqRO+PjO1VV9bbG0
+lYoeoFu0Y1xw6V2jLYnFF1mTCC6kegl6kruvnwO7Oy+6kPEvDrejuI6uozW2etej
+cBq1lUK5QNKSoaB7Qw+2qlyFg/KFwXXDBqk=
+-----END ENCRYPTED PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-request.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-request.pem b/tests/python/proton_tests/ssl_db/server-request.pem
index 2077425..da57b89 100644
--- a/tests/python/proton_tests/ssl_db/server-request.pem
+++ b/tests/python/proton_tests/ssl_db/server-request.pem
@@ -1,13 +1,15 @@
 -----BEGIN NEW CERTIFICATE REQUEST-----
-MIICajCCAicCAQAwNTEiMCAGA1UEAxMZQTEuR29vZC5TZXJ2ZXIuZG9tYWluLmNvbTEPMA0GA1UE
-ChMGU2VydmVyMIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E
-AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up
-1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUj
-C8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZ
-T+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7
-zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYQAAoGAZ3nV9bAohUzrAixWTS+jzoer
-eraDGU/RJOX8TMQF7D1u5Ixc8KpC9AiHD9R3r9/9DQrFy0+fwyo776MIJJgxgfl3UwTzlf1AzaaH
-j/F6NhZB1SWokqQc+joxsuAR9BjtTFfEyr0SSKP9PozJLVF33HAIJ/bAmGNXomrfkqmWdYygMDAu
-BgkqhkiG9w0BCQ4xITAfMB0GA1UdDgQWBBSVmCi/vFuniRy7Awjt3sADPgMfxjALBgcqhkjOOAQD
-BQADMAAwLQIUH7G2vQMVP1JURjsKcruCMMN2Nv8CFQCL3mjZX5zQE68aBdaL6163zvWMSQ==
+MIICazCCAigCAQAwNTEiMCAGA1UEAxMZQTEuR29vZC5TZXJ2ZXIuZG9tYWluLmNv
+bTEPMA0GA1UEChMGU2VydmVyMIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4Ed
+dRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs
+14E7gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208Ue
+wwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BY
+HPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+Zx
+BxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx
++2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIRG
+nLpGuQ0emBdP+4v2A38iDBjuSncjDOvWWuqj4eqbJ0T4LP26o8dXLGNfucdWt3CX
+vGCyiSLdDKgpytl9MvWhLv2Sh1Ybu3oLI62PYvcoYxR0iWpZ6lnDMIpNatvTtWOm
+qEyHRCHz4ioSa98L/hRU55z1qVfQ079yQNsgGEhOoDAwLgYJKoZIhvcNAQkOMSEw
+HzAdBgNVHQ4EFgQUGEQN1wFGqfnAURsBp3nn3KtA8TswCwYHKoZIzjgEAwUAAzAA
+MC0CFFIXSYKFVq90wR3lH+KCwvL+j0A4AhUAlxeczUtqTQFeGXFsDwIGO+5/uA4=
 -----END NEW CERTIFICATE REQUEST-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-wc-certificate.p12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-wc-certificate.p12 b/tests/python/proton_tests/ssl_db/server-wc-certificate.p12
index d512f52..3f8a53d 100644
Binary files a/tests/python/proton_tests/ssl_db/server-wc-certificate.p12 and b/tests/python/proton_tests/ssl_db/server-wc-certificate.p12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-wc-certificate.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-wc-certificate.pem b/tests/python/proton_tests/ssl_db/server-wc-certificate.pem
index 46db5db..f48c6fe 100644
--- a/tests/python/proton_tests/ssl_db/server-wc-certificate.pem
+++ b/tests/python/proton_tests/ssl_db/server-wc-certificate.pem
@@ -1,16 +1,19 @@
 -----BEGIN CERTIFICATE-----
-MIIDFTCCAtOgAwIBAgIEeHbOXTALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1c3RlZC5DQS5j
-b20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTMwMzIwMTU0NzA1WhgPMjI4NzAxMDIxNTQ3
-MDVaMDAxHTAbBgNVBAMMFCoucHJlZml4Ki5kb21haW4uY29tMQ8wDQYDVQQKEwZTZXJ2ZXIwggG3
-MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAi
-UftZPY1Y+r/F9bow9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYV
-DwT7g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi64QL8Fgc
-9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPo
-TCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa
-5Z8GkotmXoB7VSVkAUw7/s9JKgOBhAACgYB4enGCtdRSyyqTJ+q7oZCHyjB/2QdvIKMZrca0bNbk
-iVL0VT03aQ5XlzRCYPMBFwX8V4ap5XKmCj3GDVDA6cat1I0a4PWJmU2Mgv1jCgktrRghq+9dv+8i
-949cZf6FvMcA+CECkcR1t+V2dobQRwfhBgeql2TtUkuNRmknXplQ0aN3MHUwHQYDVR0OBBYEFPXv
-b/vh+yyp38bf6eodkSFKXRKxMB8GA1UdIwQYMBaAFKsQvo74oH6YkejN32+l6aYBsRSWMDMGA1Ud
-EQQsMCqCFmFsdGVybmF0ZS5uYW1lLm9uZS5jb22CEGFub3RoZXIubmFtZS5jb20wCwYHKoZIzjgE
-AwUAAy8AMCwCFFKqHg73AIZ9lsNClefQQqUqMp4/AhQjpVnd799wousXAvTtYNlH/7kWFA==
+MIIDFTCCAtOgAwIBAgIEVTK/cTALBgcqhkjOOAQDBQAwMTEXMBUGA1UEAxMOVHJ1
+c3RlZC5DQS5jb20xFjAUBgNVBAoTDVRydXN0IE1lIEluYy4wIBcNMTcwODAyMjE1
+MzM4WhgPMjI5MTA1MTcyMTUzMzhaMDAxHTAbBgNVBAMMFCoucHJlZml4Ki5kb21h
+aW4uY29tMQ8wDQYDVQQKEwZTZXJ2ZXIwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA
+/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow
+9subVWzXgTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7
+g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSMLzLKSuYKi
+64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5V0wLPQeCZ1FZV466
+1FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6i1R8jSjgo64eK7OmdZFuo38L
++iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa5Z8GkotmXoB7VSVkAUw7/s9JKgOBhAAC
+gYATsU4dSb5vvYkuhnLJPYpiHOEOagLSwwggm8CD4JqA8CC/lzIJBI3LkR7Ve1Mw
+xYiDbQQPaxGsdCxaDuE+rOHmJcCNxum4gIYxeOOGHLa9eezTXLu2s0kBgsWx3I0U
+98lI4E+gRHiU27NXlNiEKvVq3GhzWvKdUqClbtLZ+67gzqN3MHUwHwYDVR0jBBgw
+FoAUsjZ7PCKVgcZLkxE8xaWJ8cf5jmowMwYDVR0RBCwwKoIWYWx0ZXJuYXRlLm5h
+bWUub25lLmNvbYIQYW5vdGhlci5uYW1lLmNvbTAdBgNVHQ4EFgQUas7dEjv/R3ig
+GcCdPRLL5P3HPU8wCwYHKoZIzjgEAwUAAy8AMCwCFFuvuEosI+5a+lSmpEahvhyE
+31WUAhR6+NkSdChlT0v6HmjyhBL1hLZYNA==
 -----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-wc-private-key.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-wc-private-key.pem b/tests/python/proton_tests/ssl_db/server-wc-private-key.pem
index 8d2528e..c4556fb 100644
--- a/tests/python/proton_tests/ssl_db/server-wc-private-key.pem
+++ b/tests/python/proton_tests/ssl_db/server-wc-private-key.pem
@@ -1,38 +1,15 @@
 Bag Attributes
     friendlyName: server-wc-certificate
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 35 30 32 32 
+    localKeyID: 54 69 6D 65 20 31 35 30 31 37 31 30 38 31 38 34 39 33 
 Key Attributes: <No Attributes>
------BEGIN DSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,4AA7362A0A1CE3D0
-
-sLqxs1MtHOj0O0sO2YUSQMrsvl19KBlabPwiLhrLKPMzyK8Xad4S8V6J9U4QZl3I
-n6vY7XvLPx+OqPE9X6vuRfErzDzzjkrL3/4+VTj+bFdetR85ysg1iOVnM2B3MhxW
-qF9TeOpxOWokN8ck5X6TYuo1V6NcYO0rZ+oTcqe7nNdmJruwHf6dgWPeLRhyT7Cj
-IoidnCiTYKCIVH+3Hu30ZhnF81hE+vXt2EtN78kUNojlsSSsxmzOXIaPGwVRYMzw
-QqhKcX08Uo+1gHfcNfvjDpWyybBo0oznEneGvxxGoACC3KIJMAf6CB0ToP4JnSO9
-GuNj51k2M47MdCOlkvWD6OvwMNU+qtfFo02cHj2ZyjSYTry0/XnBSKfdMs8Yz0Xw
-GxsWY7f2041XBqP1gXUbjLygpNzNoD4jyxoPbgPequsCnSl6x+dORc7HICJ4VXFk
-9DCk0Xu+22PMuMl3i743SjOoxGntJCzQfJABbo6txbXbLnHrByRHgZyPeIBNrQZY
-fZm1BXRexrnXMiKyVhl0rgZaIlVwxW8yq76mRv3E+srYncWaPzPvI2UoNGJI6kqv
-TfQP2IYr3QQ4FsN70rZAe1kdur8qmo10
------END DSA PRIVATE KEY-----
-Bag Attributes
-    friendlyName: server-certificate
-    localKeyID: 54 69 6D 65 20 31 33 36 33 37 39 34 34 32 32 33 34 35 
-Key Attributes: <No Attributes>
------BEGIN DSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,2EC922782CE1727C
-
-fsM0zmhcMgj70OG+cX5FFIbS1dVFZDVpqUFXASlVzYgx5t8nTISPSBA9mQup34MG
-28sv2zxLdb+bXFuzkuq3mzuj3NLZizo7o6wRuUpbpbmp6hR6K5fkfu7GsPXCl380
-EjbrUCdt2iDiDJLyNT9Pu3ngdx3tOqz8JE3oD93FAfVZDKlzigfmX1sS+qOyqrCO
-JbRqaCJOQ5F+g73QvM9cOQLw1F/n9FqtPFNSy+Q0LFBcxfznsTk4pnPFJEko/2F0
-r9fudQS0vouNgZ4i1OzrQnWTzVeqVoSaa6AywCrynpiSWBfxMIbT78zjyoUBD47H
-nlGjMdtpoo6Xmd3CjY/pHc7Gi4RiTvBR225V/djdZpIDp7Hoyp2jMSWmsamCEFMj
-aEx7VJQtAEIyrVsCbYfvY6pE0id9dQOZSZnBtn8sHqy9DMfd6bR8FFQx48yXzO8H
-sxBNOFjkNjnjm3YWTm5q6iQ0LTke+EplixN2J1wjKz16Iy/36zCd+2rks2KXIXXX
-4dHTDPvV+9WKrfmk2ZQx/j2XQfPt34a0TIERJ5zAJuHH7a9zSCX0j4k7XRCI2GOQ
-Mu7wsBLassVgVCPF3J0Flw==
------END DSA PRIVATE KEY-----
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBljBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIFt9KwMYb/OQCAggA
+MBQGCCqGSIb3DQMHBAjQ+Hr462sAigSCAVAmqByfn+Ujb9TfpEI0d6mlW7Nyko00
+chzSFz61RVA/twfbLImhYvEo7P+UglcqGc1H3DaysDuMjbiNqgP25lDHO6ndhN7r
+XaeNshI8U3RQfUrhTwcA2pGpHQ6t+TGNKifRuJMbcHxWDNr+Tdod8uUADZt8Ywb+
+WQOqIrByNJryx5i2yZT7FphYrz6N0L5cNKVIirNv9/FOlKiyuzzg5c4NmABkpajE
+ZyT2H1p/qFipz8XeQ7BvFVDWSGn6Jb8vRvcc/swoCNSs8Wukr7tbryie2IbgktES
+gw7mVOw/Wdw6u26Q8Dz1c+eyy1WPuCiubFKUK12Ul0X9KKYCufVvQPoQBsMGikRM
+JcvrMd1cZ60pANJhnrogE6VEYE3NQrPC6SNao0NB+g4CW3tOH6m80H5+yHrMdvjo
+MQNXdlwdNWrCEH6hXJxzuE1qM5Ajc82bfwo=
+-----END ENCRYPTED PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-wc-request.pem
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-wc-request.pem b/tests/python/proton_tests/ssl_db/server-wc-request.pem
index 4160af8..af867f2 100644
--- a/tests/python/proton_tests/ssl_db/server-wc-request.pem
+++ b/tests/python/proton_tests/ssl_db/server-wc-request.pem
@@ -1,14 +1,16 @@
 -----BEGIN NEW CERTIFICATE REQUEST-----
-MIICmTCCAlcCAQAwMDEdMBsGA1UEAwwUKi5wcmVmaXgqLmRvbWFpbi5jb20xDzANBgNVBAoTBlNl
-cnZlcjCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+A
-tlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb
-+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5
-gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQ
-gYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6o
-UZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GEAAKBgHh6cYK11FLLKpMn6ruhkIfKMH/ZB28g
-oxmtxrRs1uSJUvRVPTdpDleXNEJg8wEXBfxXhqnlcqYKPcYNUMDpxq3UjRrg9YmZTYyC/WMKCS2t
-GCGr712/7yL3j1xl/oW8xwD4IQKRxHW35XZ2htBHB+EGB6qXZO1SS41GaSdemVDRoGUwYwYJKoZI
-hvcNAQkOMVYwVDAdBgNVHQ4EFgQU9e9v++H7LKnfxt/p6h2RIUpdErEwMwYDVR0RBCwwKoIWYWx0
-ZXJuYXRlLm5hbWUub25lLmNvbYIQYW5vdGhlci5uYW1lLmNvbTALBgcqhkjOOAQDBQADLwAwLAIU
-HwrrI5XVNNTolSMnuOEQ2uhE3lwCFEASAlVD+LyszXTiFF/8zOgbRy/Z
+MIICmTCCAlcCAQAwMDEdMBsGA1UEAwwUKi5wcmVmaXgqLmRvbWFpbi5jb20xDzAN
+BgNVBAoTBlNlcnZlcjCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLf
+Spwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4Ad
+NG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQT
+WhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGB
+APfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0
+SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEk
+O8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GEAAKBgBOxTh1Jvm+9
+iS6Gcsk9imIc4Q5qAtLDCCCbwIPgmoDwIL+XMgkEjcuRHtV7UzDFiINtBA9rEax0
+LFoO4T6s4eYlwI3G6biAhjF444Yctr157NNcu7azSQGCxbHcjRT3yUjgT6BEeJTb
+s1eU2IQq9WrcaHNa8p1SoKVu0tn7ruDOoGUwYwYJKoZIhvcNAQkOMVYwVDAzBgNV
+HREELDAqghZhbHRlcm5hdGUubmFtZS5vbmUuY29tghBhbm90aGVyLm5hbWUuY29t
+MB0GA1UdDgQWBBRqzt0SO/9HeKAZwJ09Esvk/cc9TzALBgcqhkjOOAQDBQADLwAw
+LAIUNn3ravBNvEsgZRjQd4EPPvQ1k9wCFEuakAyAzmt2ZfIKX3ZmTIgNKsvy
 -----END NEW CERTIFICATE REQUEST-----

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server-wc.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server-wc.pkcs12 b/tests/python/proton_tests/ssl_db/server-wc.pkcs12
new file mode 100644
index 0000000..0ceccbc
Binary files /dev/null and b/tests/python/proton_tests/ssl_db/server-wc.pkcs12 differ

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/62fee105/tests/python/proton_tests/ssl_db/server.pkcs12
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl_db/server.pkcs12 b/tests/python/proton_tests/ssl_db/server.pkcs12
index dd23587..f3c19e2 100644
Binary files a/tests/python/proton_tests/ssl_db/server.pkcs12 and b/tests/python/proton_tests/ssl_db/server.pkcs12 differ


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[34/50] qpid-proton git commit: PROTON-1557: c++ fix returned<> template windows link problems

Posted by ac...@apache.org.
PROTON-1557: c++ fix returned<> template windows link problems


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/69a99dd0
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/69a99dd0
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/69a99dd0

Branch: refs/heads/go1
Commit: 69a99dd0b82801d2c0bba6e30871f2c50f4bf74b
Parents: 398f786
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Aug 29 09:43:20 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Aug 29 09:59:01 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/include/proton/returned.hpp | 9 ++++++---
 proton-c/bindings/cpp/src/returned.cpp            | 8 ++++++--
 2 files changed, 12 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/69a99dd0/proton-c/bindings/cpp/include/proton/returned.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/returned.hpp b/proton-c/bindings/cpp/include/proton/returned.hpp
index 25b5c91..28c45a0 100644
--- a/proton-c/bindings/cpp/include/proton/returned.hpp
+++ b/proton-c/bindings/cpp/include/proton/returned.hpp
@@ -22,11 +22,14 @@
  *
  */
 
+#include "./internal/export.hpp"
 #include "./internal/object.hpp"
+
 #include "./connection.hpp"
 #include "./receiver.hpp"
 #include "./sender.hpp"
 
+
 /// @file
 /// Return type for container functions
 
@@ -45,14 +48,14 @@ template <class T> class factory;
 /// can access the value in @ref messaging_handler functions.
 ///
 template <class T>
-class returned
+class PN_CPP_CLASS_EXTERN returned
 {
   public:
-    operator T() const;
+    PN_CPP_EXTERN returned(const T&);
+    PN_CPP_EXTERN operator T() const;
 
   private:
     typename T::pn_type* ptr_;
-    returned(const T&);
     returned& operator=(const returned&);
     template <class U> friend class internal::factory;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/69a99dd0/proton-c/bindings/cpp/src/returned.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/returned.cpp b/proton-c/bindings/cpp/src/returned.cpp
index 2e1a4b2..a6c6101 100644
--- a/proton-c/bindings/cpp/src/returned.cpp
+++ b/proton-c/bindings/cpp/src/returned.cpp
@@ -19,6 +19,8 @@
 
 #include "proton_bits.hpp"
 
+#include <proton/internal/export.hpp>
+
 #include <proton/returned.hpp>
 #include <proton/connection.hpp>
 #include <proton/sender.hpp>
@@ -26,9 +28,11 @@
 
 namespace proton {
 
-template <class T> returned<T>::returned(const T& t) : ptr_(unwrap(t)) {}
+template <class T> PN_CPP_EXTERN returned<T>::returned(const T& t) : ptr_(unwrap(t)) {}
+
+//template <class T> PN_CPP_EXTERN returned<T>::returned(const returned<T>& x) : ptr_(x.ptr_) {}
 
-template <class T> returned<T>::operator T() const {
+template <class T> PN_CPP_EXTERN returned<T>::operator T() const {
     return internal::factory<T>::wrap(ptr_);
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[33/50] qpid-proton git commit: PROTON-1557: c++ improve multi-threaded clients

Posted by ac...@apache.org.
PROTON-1557: c++ improve multi-threaded clients

2 clients:
- multithreaded_client.cpp: simple send thread, receive thread, run thread
- multithreaded_client_flow_control: multi-connection, block for flow control

Changes:
- reduced needless diff between examples
- use separate work_queue* to clarify separate thread safety rules from sender
- took work_queue->add() out of lock to emphasize it is thread safe
- use fixed argument list, same arg order


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/398f786b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/398f786b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/398f786b

Branch: refs/heads/go1
Commit: 398f786ba94857b00d052c03232f8f9ef97f3f44
Parents: f1ee268
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Aug 28 11:53:35 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Aug 28 18:00:24 2017 -0400

----------------------------------------------------------------------
 examples/cpp/CMakeLists.txt                     |   3 +-
 examples/cpp/multithreaded_client.cpp           | 185 ++++++++++++
 .../cpp/multithreaded_client_flow_control.cpp   | 287 +++++++++++++++++++
 examples/cpp/send_recv_mt.cpp                   | 269 -----------------
 4 files changed, 474 insertions(+), 270 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/398f786b/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index df9f6a7..d116913 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -63,7 +63,8 @@ if(HAS_CPP11)
   # Examples that require C++11
   foreach(example
       scheduled_send
-      send_recv_mt
+      multithreaded_client
+      multithreaded_client_flow_control
       )
     add_executable(${example} ${example}.cpp)
   endforeach()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/398f786b/examples/cpp/multithreaded_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client.cpp b/examples/cpp/multithreaded_client.cpp
new file mode 100644
index 0000000..955655c
--- /dev/null
+++ b/examples/cpp/multithreaded_client.cpp
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+//
+// C++11 only
+//
+// A multi-threaded client that calls proton::container::run() in one thread, sends
+// messages in another and receives messages in a third.
+//
+// Note this client does not deal with flow-control. If the sender is faster
+// than the receiver, messages will build up in memory on the sending side.
+// See @ref multithreaded_client_flow_control.cpp for a more complex example with
+// flow control.
+//
+// NOTE: no proper error handling
+
+#include <proton/connection.hpp>
+#include <proton/connection_options.hpp>
+#include <proton/container.hpp>
+#include <proton/message.hpp>
+#include <proton/messaging_handler.hpp>
+#include <proton/receiver.hpp>
+#include <proton/sender.hpp>
+#include <proton/work_queue.hpp>
+
+#include <condition_variable>
+#include <iostream>
+#include <mutex>
+#include <queue>
+#include <sstream>
+#include <string>
+#include <thread>
+
+// Handler for a single thread-safe sending and receiving connection.
+class client : public proton::messaging_handler {
+    // Invariant
+    const std::string url_;
+    const std::string address_;
+
+    // Only used in proton handler thread
+    proton::sender sender_;
+
+    // Shared by proton and user threads, protected by lock_
+    std::mutex lock_;
+    proton::work_queue *work_queue_;
+    std::condition_variable sender_ready_;
+    std::queue<proton::message> messages_;
+    std::condition_variable messages_ready_;
+
+  public:
+    client(const std::string& url, const std::string& address) : url_(url), address_(address) {}
+
+    // Thread safe
+    void send(const proton::message& msg) {
+        // Use [=] to copy the message, we cannot pass it by reference since it
+        // will be used in another thread.
+        work_queue()->add([=]() { sender_.send(msg); });
+    }
+
+    // Thread safe
+    proton::message receive() {
+        std::unique_lock<std::mutex> l(lock_);
+        while (messages_.empty()) messages_ready_.wait(l);
+        auto msg = std::move(messages_.front());
+        messages_.pop();
+        return msg;
+    }
+
+    // Thread safe
+    void close() {
+        work_queue()->add([=]() { sender_.connection().close(); });
+    }
+
+  private:
+
+    proton::work_queue* work_queue() {
+        // Wait till work_queue_ and sender_ are initialized.
+        std::unique_lock<std::mutex> l(lock_);
+        while (!work_queue_) sender_ready_.wait(l);
+        return work_queue_;
+    }
+
+    // == messaging_handler overrides, only called in proton hander thread
+
+    // Note: this example creates a connection when the container starts.
+    // To create connections after the container has started, use
+    // container::connect().
+    // See @ref multithreaded_client_flow_control.cpp for an example.
+    void on_container_start(proton::container& cont) override {
+        cont.connect(url_);
+    }
+
+    void on_connection_open(proton::connection& conn) override {
+        conn.open_sender(address_);
+        conn.open_receiver(address_);
+    }
+
+    void on_sender_open(proton::sender& s) override {
+        {
+            // sender_ and work_queue_ must be set atomically
+            std::lock_guard<std::mutex> l(lock_);
+            sender_ = s;
+            work_queue_ = &s.work_queue();
+        }
+        sender_ready_.notify_all();
+    }
+
+    void on_message(proton::delivery& dlv, proton::message& msg) override {
+        {
+            std::lock_guard<std::mutex> l(lock_);
+            messages_.push(msg);
+        }
+        messages_ready_.notify_all();
+    }
+
+    void on_error(const proton::error_condition& e) override {
+        std::cerr << "unexpected error: " << e << std::endl;
+        exit(1);
+    }
+};
+
+int main(int argc, const char** argv) {
+    try {
+        if (argc != 4) {
+            std ::cerr <<
+                "Usage: " << argv[0] << " CONNECTION-URL AMQP-ADDRESS MESSAGE-COUNT\n"
+                "CONNECTION-URL: connection address, e.g.'amqp://127.0.0.1'\n"
+                "AMQP-ADDRESS: AMQP node address, e.g. 'examples'\n"
+                "MESSAGE-COUNT: number of messages to send\n";
+            return 1;
+        }
+        const char *url = argv[1];
+        const char *address = argv[2];
+        int n_messages = atoi(argv[3]);
+
+        client cl(url, address);
+        proton::container container(cl);
+        std::thread container_thread([&]() { container.run(); });
+
+        std::thread sender([&]() {
+                for (int i = 0; i < n_messages; ++i) {
+                    proton::message msg(std::to_string(i + 1));
+                    cl.send(msg);
+                    std::cout << "sent: " << msg.body() << std::endl;
+                }
+            });
+
+        int received = 0;
+        std::thread receiver([&]() {
+                for (int i = 0; i < n_messages; ++i) {
+                    auto msg = cl.receive();
+                    std::cout << "received: " << msg.body() << std::endl;
+                    ++received;
+                }
+            });
+
+        sender.join();
+        receiver.join();
+        cl.close();
+        container_thread.join();
+        std::cout << "received " << received << " messages" << std::endl;
+
+        return 0;
+    } catch (const std::exception& e) {
+        std::cerr << e.what() << std::endl;
+    }
+
+    return 1;
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/398f786b/examples/cpp/multithreaded_client_flow_control.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client_flow_control.cpp b/examples/cpp/multithreaded_client_flow_control.cpp
new file mode 100644
index 0000000..9eec782
--- /dev/null
+++ b/examples/cpp/multithreaded_client_flow_control.cpp
@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// C++11 only
+//
+// A multi-threaded client that sends and receives messages from multiple AMQP
+// addresses.
+//
+// Demonstrates how to:
+//
+// - implement proton handlers that interact with user threads safely
+// - block sender threads to respect AMQP flow control
+// - use AMQP flow control to limit message buffering for receivers threads
+//
+// We define sender and receiver classes with simple, thread-safe blocking
+// send() and receive() functions.
+//
+// These classes are also privately proton::message_handler instances. They use
+// the thread-safe proton::work_queue and standard C++ synchronization (std::mutex
+// etc.) to pass messages between user and proton::container threads.
+//
+// NOTE: no proper error handling
+
+#include <proton/connection.hpp>
+#include <proton/connection_options.hpp>
+#include <proton/container.hpp>
+#include <proton/message.hpp>
+#include <proton/messaging_handler.hpp>
+#include <proton/receiver.hpp>
+#include <proton/receiver_options.hpp>
+#include <proton/sender.hpp>
+#include <proton/work_queue.hpp>
+
+#include <atomic>
+#include <condition_variable>
+#include <iostream>
+#include <mutex>
+#include <queue>
+#include <sstream>
+#include <string>
+#include <thread>
+
+// A thread-safe sending connection that blocks sending threads when there
+// is no AMQP credit to send messages.
+class sender : private proton::messaging_handler {
+    // Only used in proton handler thread
+    proton::sender sender_;
+
+    // Shared by proton and user threads, protected by lock_
+    std::mutex lock_;
+    proton::work_queue *work_queue_;
+    std::condition_variable sender_ready_;
+    int queued_;                       // Queued messages waiting to be sent
+    int credit_;                       // AMQP credit - number of messages we can send
+
+  public:
+    sender(proton::container& cont, const std::string& url, const std::string& address)
+        : work_queue_(0), queued_(0), credit_(0)
+    {
+        cont.open_sender(url+"/"+address, proton::connection_options().handler(*this));
+    }
+
+    // Thread safe
+    void send(const proton::message& m) {
+        {
+            std::unique_lock<std::mutex> l(lock_);
+            // Don't queue up more messages than we have credit for
+            while (!work_queue_ || queued_ >= credit_) sender_ready_.wait(l);
+            ++queued_;
+        }
+        work_queue_->add([=]() { this->do_send(m); }); // work_queue_ is thread safe
+    }
+
+    // Thread safe
+    void close() {
+        work_queue()->add([=]() { sender_.connection().close(); });
+    }
+
+  private:
+
+    proton::work_queue* work_queue() {
+        // Wait till work_queue_ and sender_ are initialized.
+        std::unique_lock<std::mutex> l(lock_);
+        while (!work_queue_) sender_ready_.wait(l);
+        return work_queue_;
+    }
+
+    // == messaging_handler overrides, only called in proton hander thread
+
+    void on_sender_open(proton::sender& s) override {
+        // Make sure sender_ and work_queue_ are set atomically
+        std::lock_guard<std::mutex> l(lock_);
+        sender_ = s;
+        work_queue_ = &s.work_queue();
+    }
+
+    void on_sendable(proton::sender& s) override {
+        std::lock_guard<std::mutex> l(lock_);
+        credit_ = s.credit();
+        sender_ready_.notify_all(); // Notify senders we have credit
+    }
+
+    // work_queue work items is are automatically dequeued and called by proton
+    // This function is called because it was queued by send()
+    void do_send(const proton::message& m) {
+        sender_.send(m);
+        std::lock_guard<std::mutex> l(lock_);
+        --queued_;                    // work item was consumed from the work_queue
+        credit_ = sender_.credit();   // update credit
+        sender_ready_.notify_all();       // Notify senders we have space on queue
+    }
+
+    void on_error(const proton::error_condition& e) override {
+        std::cerr << "unexpected error: " << e << std::endl;
+        exit(1);
+    }
+};
+
+// A thread safe receiving connection that blocks receiving threads when there
+// are no messages available, and maintains a bounded buffer of incoming
+// messages by issuing AMQP credit only when there is space in the buffer.
+class receiver : private proton::messaging_handler {
+    static const size_t MAX_BUFFER = 100; // Max number of buffered messages
+
+    // Used in proton threads only
+    proton::receiver receiver_;
+
+    // Used in proton and user threads, protected by lock_
+    std::mutex lock_;
+    proton::work_queue* work_queue_;
+    std::queue<proton::message> buffer_; // Messages not yet returned by receive()
+    std::condition_variable can_receive_; // Notify receivers of messages
+
+  public:
+
+    // Connect to url
+    receiver(proton::container& cont, const std::string& url, const std::string& address)
+        : work_queue_()
+    {
+        // NOTE:credit_window(0) disables automatic flow control.
+        // We will use flow control to match AMQP credit to buffer capacity.
+        cont.open_receiver(url+"/"+address, proton::receiver_options().credit_window(0),
+                           proton::connection_options().handler(*this));
+    }
+
+    // Thread safe receive
+    proton::message receive() {
+        std::unique_lock<std::mutex> l(lock_);
+        // Wait for buffered messages
+        while (!work_queue_ || buffer_.empty())
+            can_receive_.wait(l);
+        proton::message m = std::move(buffer_.front());
+        buffer_.pop();
+        // Add a lambda to the work queue to call receive_done().
+        // This will tell the handler to add more credit.
+        work_queue_->add([=]() { this->receive_done(); });
+        return m;
+    }
+
+    void close() {
+        std::lock_guard<std::mutex> l(lock_);
+        if (work_queue_) work_queue_->add([this]() { this->receiver_.connection().close(); });
+    }
+
+  private:
+    // ==== The following are called by proton threads only.
+
+    void on_receiver_open(proton::receiver& r) override {
+        receiver_ = r;
+        std::lock_guard<std::mutex> l(lock_);
+        work_queue_ = &receiver_.work_queue();
+        receiver_.add_credit(MAX_BUFFER); // Buffer is empty, initial credit is the limit
+    }
+
+    void on_message(proton::delivery &d, proton::message &m) override {
+        // Proton automatically reduces credit by 1 before calling on_message
+        std::lock_guard<std::mutex> l(lock_);
+        buffer_.push(m);
+        can_receive_.notify_all();
+    }
+
+    // called via work_queue
+    void receive_done() {
+        // Add 1 credit, a receiver has taken a message out of the buffer.
+        receiver_.add_credit(1);
+    }
+
+    void on_error(const proton::error_condition& e) override {
+        std::cerr << "unexpected error: " << e << std::endl;
+        exit(1);
+    }
+};
+
+// ==== Example code using the sender and receiver
+
+// Send n messages
+void send_thread(sender& s, int n, bool print) {
+    auto id = std::this_thread::get_id();
+    for (int i = 0; i < n; ++i) {
+        std::ostringstream ss;
+        ss << std::this_thread::get_id() << ":" << i;
+        s.send(proton::message(ss.str()));
+        if (print) std::cout << "received: " << ss.str() << std::endl;
+    }
+    std::cout << id << " sent " << n << std::endl;
+}
+
+// Receive messages till atomic remaining count is 0.
+// remaining is shared among all receiving threads
+void receive_thread(receiver& r, std::atomic_int& remaining, bool print) {
+    auto id = std::this_thread::get_id();
+    int n = 0;
+    while (remaining-- > 0) {
+        auto m = r.receive();
+        ++n;
+        if (print) std::cout << id << "received: " << m.body() << std::endl;
+    }
+    std::cout << id << " received " << n << " messages" << std::endl;
+}
+
+int main(int argc, const char **argv) {
+    try {
+        if (argc != 5) {
+            std::cerr <<
+                "Usage: " << argv[0] << " MESSAGE-COUNT THREAD-COUNT URL\n"
+                "CONNECTION-URL: connection address, e.g.'amqp://127.0.0.1'\n"
+                "AMQP-ADDRESS: AMQP node address, e.g. 'examples'\n"
+                "MESSAGE-COUNT: number of messages to send\n"
+                "THREAD-COUNT: number of sender/receiver thread pairs\n";
+            return 1;
+        }
+
+        const char *url = argv[1];
+        const char *address = argv[2];
+        int n_messages = atoi(argv[3]);
+        int n_threads = atoi(argv[4]);
+
+        // Total messages to be received, multiple receiver threads will decrement this.
+        std::atomic_int remaining(n_messages * n_threads);
+        bool print = remaining < 1000; // Don't print for long runs, dominates run time
+
+        // Run the proton container
+        proton::container container;
+        auto container_thread = std::thread([&]() { container.run(); });
+
+        // A single sender and receiver to be shared by all the threads
+        sender send(container, url, address);
+        receiver recv(container, url, address);
+
+        // Start receiver threads, then sender threads.
+        // Starting receivers first gives all receivers a chance to compete for messages.
+        std::vector<std::thread> threads;
+        for (int i = 0; i < n_threads; ++i)
+            threads.push_back(std::thread([&]() { receive_thread(recv, remaining, print); }));
+        for (int i = 0; i < n_threads; ++i)
+            threads.push_back(std::thread([&]() { send_thread(send, n_messages, print); }));
+
+        // Wait for threads to finish
+        for (auto& t : threads)
+            t.join();
+        send.close();
+        recv.close();
+
+        container_thread.join();
+
+        return 0;
+    } catch (const std::exception& e) {
+        std::cerr << e.what() << std::endl;
+    }
+    return 1;
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/398f786b/examples/cpp/send_recv_mt.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/send_recv_mt.cpp b/examples/cpp/send_recv_mt.cpp
deleted file mode 100644
index addcbaf..0000000
--- a/examples/cpp/send_recv_mt.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// C++11 only
-//
-// A multi-threaded client that sends and receives messages from multiple AMQP
-// addresses.
-//
-// Demonstrates how to:
-//
-// - implement proton handlers that interact with user threads safely
-// - block user threads calling send() to respect AMQP flow control
-// - use AMQP flow control to limit message buffering for receivers
-//
-// We define mt_sender and mt_receiver classes with simple, thread-safe blocking
-// send() and receive() functions.
-//
-// These classes are also privately proton::message_handler instances. They use
-// the thread-safe proton::work_queue and standard C++ synchronization (std::mutex
-// etc.) to pass messages between user and proton::container threads.
-//
-// NOTE: no proper error handling
-
-#include <proton/connection.hpp>
-#include <proton/connection_options.hpp>
-#include <proton/container.hpp>
-#include <proton/message.hpp>
-#include <proton/messaging_handler.hpp>
-#include <proton/receiver_options.hpp>
-#include <proton/sender.hpp>
-#include <proton/work_queue.hpp>
-
-#include <atomic>
-#include <condition_variable>
-#include <iostream>
-#include <mutex>
-#include <queue>
-#include <sstream>
-#include <thread>
-
-// Lock to serialize std::cout, std::cerr used from multiple threads.
-std::mutex out_lock;
-#define LOCK(EXPR) do { std::lock_guard<std::mutex> l(out_lock); EXPR; } while(0)
-#define COUT(EXPR) do { LOCK(std::cout << EXPR); } while(0)
-#define CERR(EXPR) do { LOCK(std::cerr << EXPR); } while(0)
-
-// A thread-safe sending connection.
-class mt_sender : private proton::messaging_handler {
-    // Only used in proton thread
-    proton::sender sender_;
-
-    // Shared by proton and user threads, use lock_ to protect.
-    std::mutex lock_;
-    proton::work_queue* work_queue_;   // Messages waiting to be sent
-    std::condition_variable can_send_; // Signal sending threads
-    int queued_;                       // Queued messages waiting to be sent
-    int credit_;                       // AMQP credit - number of messages we can send
-
-  public:
-    // Connect to url
-    mt_sender(proton::container& cont, const std::string& url) :
-        work_queue_(0), queued_(0), credit_(0)
-    {
-        // Pass *this as handler.
-        cont.open_sender(url, proton::connection_options().handler(*this));
-    }
-
-    // Thread safe send()
-    void send(const proton::message& m) {
-        std::unique_lock<std::mutex> l(lock_);
-        // Don't queue up more messages than we have credit for
-        while (!(work_queue_ && queued_ < credit_))
-            can_send_.wait(l);
-        ++queued_;
-        // Add a lambda function to the work queue.
-        // This will call do_send() with a copy of m in the correct proton thread.
-        work_queue_->add([=]() { this->do_send(m); });
-    }
-
-    void close() {
-        std::lock_guard<std::mutex> l(lock_);
-        if (work_queue_)
-            work_queue_->add([this]() { this->sender_.connection().close(); });
-    }
-
-  private:
-    // ==== called by proton threads only
-
-    void on_sender_open(proton::sender& s) override {
-        sender_ = s;
-        std::lock_guard<std::mutex> l(lock_);
-        work_queue_ = &s.work_queue();
-    }
-
-    void on_sendable(proton::sender& s) override {
-        std::lock_guard<std::mutex> l(lock_);
-        credit_ = s.credit();
-        can_send_.notify_all(); // Notify senders we have credit
-    }
-
-    // work_queue work items is are automatically dequeued and called by proton
-    // This function is called because it was queued by send()
-    void do_send(const proton::message& m) {
-        sender_.send(m);
-        std::lock_guard<std::mutex> l(lock_);
-        --queued_;                    // work item was consumed from the work_queue
-        credit_ = sender_.credit();   // update credit
-        can_send_.notify_all();       // Notify senders we have space on queue
-    }
-
-    void on_error(const proton::error_condition& e) override {
-        CERR("unexpected error: " << e << std::endl);
-        exit(1);
-    }
-};
-
-// A thread safe receiving connection.
-class mt_receiver : private proton::messaging_handler {
-    static const size_t MAX_BUFFER = 100; // Max number of buffered messages
-
-    // Used in proton threads only
-    proton::receiver receiver_;
-
-    // Used in proton and user threads, protected by lock_
-    std::mutex lock_;
-    proton::work_queue* work_queue_;
-    std::queue<proton::message> buffer_; // Messages not yet returned by receive()
-    std::condition_variable can_receive_; // Notify receivers of messages
-
-  public:
-
-    // Connect to url
-    mt_receiver(proton::container& cont, const std::string& url) : work_queue_()
-    {
-        // NOTE:credit_window(0) disables automatic flow control.
-        // We will use flow control to match AMQP credit to buffer capacity.
-        cont.open_receiver(url, proton::receiver_options().credit_window(0),
-                           proton::connection_options().handler(*this));
-    }
-
-    // Thread safe receive
-    proton::message receive() {
-        std::unique_lock<std::mutex> l(lock_);
-        // Wait for buffered messages
-        while (!work_queue_ || buffer_.empty())
-            can_receive_.wait(l);
-        proton::message m = std::move(buffer_.front());
-        buffer_.pop();
-        // Add a lambda to the work queue to call receive_done().
-        // This will tell the handler to add more credit.
-        work_queue_->add([=]() { this->receive_done(); });
-        return m;
-    }
-
-    void close() {
-        std::lock_guard<std::mutex> l(lock_);
-        if (work_queue_)
-            work_queue_->add([this]() { this->receiver_.connection().close(); });
-    }
-
-  private:
-    // ==== The following are called by proton threads only.
-
-    void on_receiver_open(proton::receiver& r) override {
-        receiver_ = r;
-        std::lock_guard<std::mutex> l(lock_);
-        work_queue_ = &receiver_.work_queue();
-        receiver_.add_credit(MAX_BUFFER); // Buffer is empty, initial credit is the limit
-    }
-
-    void on_message(proton::delivery &d, proton::message &m) override {
-        // Proton automatically reduces credit by 1 before calling on_message
-        std::lock_guard<std::mutex> l(lock_);
-        buffer_.push(m);
-        can_receive_.notify_all();
-    }
-
-    // called via work_queue
-    void receive_done() {
-        // Add 1 credit, a receiver has taken a message out of the buffer.
-        receiver_.add_credit(1);
-    }
-
-    void on_error(const proton::error_condition& e) override {
-        CERR("unexpected error: " << e << std::endl);
-        exit(1);
-    }
-};
-
-// ==== Example code using the mt_sender and mt_receiver
-
-// Send n messages
-void send_thread(mt_sender& s, int n) {
-    for (int i = 0; i < n; ++i) {
-        std::ostringstream o;
-        o << std::this_thread::get_id() << ":" << i;
-        s.send(proton::message(o.str()));
-    }
-    COUT(std::this_thread::get_id() << " sent " << n << std::endl);
-}
-
-// Receive messages till atomic remaining count is 0.
-// remaining is shared among all receiving threads
-void receive_thread(mt_receiver& r, std::atomic_int& remaining, bool print) {
-    auto id = std::this_thread::get_id();
-    int n = 0;
-    while (remaining-- > 0) {
-        auto m = r.receive();
-        ++n;
-        if (print)
-            COUT(id << " received \"" << m.body() << '"' << std::endl);
-    }
-    COUT(id << " received " << n << " messages" << std::endl);
-}
-
-int main(int argc, const char **argv) {
-    try {
-        int n_threads = argc > 1 ? atoi(argv[1]) : 2;
-        int n_messages = argc > 2 ? atoi(argv[2]) : 10;
-        const char *url =  argc > 3 ? argv[3] : "amqp://127.0.0.1/examples";
-        std::atomic_int remaining(n_messages * n_threads); // Total messages to be received
-        bool print = (remaining <= 30); // Print messages for short runs only
-
-        // Run the proton container
-        proton::container container;
-        auto container_thread = std::thread([&]() { container.run(); });
-
-        // A single sender and receiver to be shared by all the threads
-        mt_sender sender(container, url);
-        mt_receiver receiver(container, url);
-
-        // Start receiver threads, then sender threads.
-        // Starting receivers first gives all receivers a chance to compete for messages.
-        std::vector<std::thread> threads;
-        for (int i = 0; i < n_threads; ++i)
-            threads.push_back(std::thread([&]() { receive_thread(receiver, remaining, print); }));
-        for (int i = 0; i < n_threads; ++i)
-            threads.push_back(std::thread([&]() { send_thread(sender, n_messages); }));
-
-        // Wait for threads to finish
-        for (auto& n_messages_threads : threads)
-            n_messages_threads.join();
-        sender.close();
-        receiver.close();
-
-        container_thread.join();
-
-        return 0;
-    } catch (const std::exception& e) {
-        std::cerr << e.what() << std::endl;
-    }
-    return 1;
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[09/50] qpid-proton git commit: NO-JIRA: Change travis to compile with both gcc and clang

Posted by ac...@apache.org.
NO-JIRA: Change travis to compile with both gcc and clang


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ca88f341
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ca88f341
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ca88f341

Branch: refs/heads/go1
Commit: ca88f3416cfe2a9fa4ab06a1d8282f231843386c
Parents: 8c54c62
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Aug 3 14:05:36 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 19:35:26 2017 -0400

----------------------------------------------------------------------
 .travis.yml | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ca88f341/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index c4e6d93..073ed95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,8 +19,10 @@
 
 os: linux
 sudo: false
-language: python
-python: 2.7
+language: cpp
+compiler:
+- gcc
+- clang
 
 addons:
   apt:
@@ -39,8 +41,8 @@ addons:
     - golang
 
 install:
-- pip install --upgrade pip
-- pip install tox
+- pip install --user --upgrade pip
+- pip install --user tox
 - gem install rspec
 - gem install simplecov || true
 - gem install minitest


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[11/50] qpid-proton git commit: PROTON-1526: Ensure the module .so file has no prefix; remove version-based rename

Posted by ac...@apache.org.
PROTON-1526: Ensure the module .so file has no prefix; remove version-based rename


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/1b8dae76
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/1b8dae76
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/1b8dae76

Branch: refs/heads/go1
Commit: 1b8dae76d36167b9f3e0748968d9b6ee1da3bc20
Parents: fb43963
Author: Justin Ross <jr...@apache.org>
Authored: Tue Aug 8 13:58:38 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Tue Aug 8 13:58:38 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/perl/CMakeLists.txt | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1b8dae76/proton-c/bindings/perl/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/perl/CMakeLists.txt b/proton-c/bindings/perl/CMakeLists.txt
index 1356cce..744e812 100644
--- a/proton-c/bindings/perl/CMakeLists.txt
+++ b/proton-c/bindings/perl/CMakeLists.txt
@@ -54,20 +54,12 @@ list(APPEND SWIG_MODULE_cproton_perl_EXTRA_DEPS
     ${PROTON_HEADERS}
 )
 swig_add_module(cproton_perl perl perl.i)
+set_target_properties(cproton_perl PROPERTIES PREFIX "")
 swig_link_libraries(cproton_perl ${BINDING_DEPS} ${PERL_LIBRARY})
 
-if ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8))
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton_perl.so
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton_perl.so
         DESTINATION ${PERL_VENDORARCH_DIR}/auto/cproton_perl
-        COMPONENT Perl
-        )
-else()
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcproton_perl.so
-        RENAME cproton_perl.so
-        DESTINATION ${PERL_VENDORARCH_DIR}/auto/cproton_perl
-        COMPONENT Perl
-        )
-endif ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8))
+        COMPONENT Perl)
 
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton_perl.pm
         DESTINATION ${PERL_VENDORARCH_DIR}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[44/50] qpid-proton git commit: PROTON-1543: Various improvements to the C++ API docs

Posted by ac...@apache.org.
PROTON-1543: Various improvements to the C++ API docs

 - Use 'Unsettled API' instead of 'Experimental'
 - Improve the map API docs
 - Document default values for endpoint options


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b60f093a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b60f093a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b60f093a

Branch: refs/heads/go1
Commit: b60f093a1ca77f7d2de94fdac3a57b16a3765426
Parents: ba696d2
Author: Justin Ross <jr...@apache.org>
Authored: Thu Aug 31 05:25:08 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 31 05:25:08 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/cpp/docs/io.md                |  2 +-
 .../cpp/include/proton/codec/common.hpp         |  4 +-
 .../cpp/include/proton/codec/decoder.hpp        |  2 +-
 .../cpp/include/proton/codec/encoder.hpp        |  2 +-
 .../cpp/include/proton/connection_options.hpp   | 31 ++++---
 .../bindings/cpp/include/proton/container.hpp   |  4 +-
 .../cpp/include/proton/error_condition.hpp      |  2 +-
 .../cpp/include/proton/internal/data.hpp        |  2 +-
 .../cpp/include/proton/io/connection_driver.hpp |  6 +-
 .../cpp/include/proton/io/link_namer.hpp        |  4 +-
 proton-c/bindings/cpp/include/proton/link.hpp   |  2 +-
 .../cpp/include/proton/listen_handler.hpp       |  2 +-
 proton-c/bindings/cpp/include/proton/map.hpp    | 85 ++++++++++++--------
 .../bindings/cpp/include/proton/message.hpp     | 12 +--
 .../cpp/include/proton/messaging_handler.hpp    |  4 +-
 .../bindings/cpp/include/proton/namespaces.hpp  |  4 +-
 .../bindings/cpp/include/proton/receiver.hpp    |  2 +-
 .../cpp/include/proton/receiver_options.hpp     | 34 ++++----
 proton-c/bindings/cpp/include/proton/sender.hpp |  2 +-
 .../cpp/include/proton/sender_options.hpp       | 11 ++-
 .../cpp/include/proton/session_options.hpp      |  4 +-
 proton-c/bindings/cpp/include/proton/source.hpp |  4 +-
 .../cpp/include/proton/source_options.hpp       | 23 +++---
 proton-c/bindings/cpp/include/proton/ssl.hpp    |  6 +-
 proton-c/bindings/cpp/include/proton/symbol.hpp |  8 +-
 .../cpp/include/proton/target_options.hpp       | 17 ++--
 proton-c/bindings/cpp/include/proton/url.hpp    |  2 +-
 .../bindings/cpp/include/proton/work_queue.hpp  | 24 +++---
 28 files changed, 169 insertions(+), 136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/docs/io.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/io.md b/proton-c/bindings/cpp/docs/io.md
index c0f7b02..2f380ce 100644
--- a/proton-c/bindings/cpp/docs/io.md
+++ b/proton-c/bindings/cpp/docs/io.md
@@ -1,6 +1,6 @@
 # IO integration {#io_page}
 
-**Experimental** - The `proton::io` interfaces are new and remain
+**Unsettled API** - The `proton::io` interfaces are new and remain
 subject to change.
 
 The `proton::io` namespace contains a service provider interface (SPI)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/codec/common.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/codec/common.hpp b/proton-c/bindings/cpp/include/proton/codec/common.hpp
index e8d8ce5..61de8a5 100644
--- a/proton-c/bindings/cpp/include/proton/codec/common.hpp
+++ b/proton-c/bindings/cpp/include/proton/codec/common.hpp
@@ -27,7 +27,7 @@
 namespace proton {
 namespace codec {
 
-/// **Experimental** - Start encoding a complex type.
+/// **Unsettled API** - Start encoding a complex type.
 struct start {
     /// @cond INTERNAL
     /// XXX Document
@@ -50,7 +50,7 @@ struct start {
     /// @endcond
 };
 
-/// **Experimental** - Finish inserting or extracting a complex type.
+/// **Unsettled API** - Finish inserting or extracting a complex type.
 struct finish {};
 
 } // codec

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/codec/decoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/codec/decoder.hpp b/proton-c/bindings/cpp/include/proton/codec/decoder.hpp
index 3dc6d57..cf42f90 100644
--- a/proton-c/bindings/cpp/include/proton/codec/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/codec/decoder.hpp
@@ -44,7 +44,7 @@ class value_base;
 
 namespace codec {
 
-/// **Experimental** - Stream-like decoder from AMQP bytes to C++
+/// **Unsettled API** - Stream-like decoder from AMQP bytes to C++
 /// values.
 ///
 /// For internal use only.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/codec/encoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/codec/encoder.hpp b/proton-c/bindings/cpp/include/proton/codec/encoder.hpp
index 2610021..043e999 100644
--- a/proton-c/bindings/cpp/include/proton/codec/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/codec/encoder.hpp
@@ -38,7 +38,7 @@ class value_base;
 
 namespace codec {
 
-/// **Experimental** - Stream-like encoder from C++ values to AMQP
+/// **Unsettled API** - Stream-like encoder from C++ values to AMQP
 /// bytes.
 ///
 /// For internal use only.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index c0ff457..62af5f3 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -86,26 +86,26 @@ class connection_options {
     /// Set the maximum frame size.  It is unlimited by default.
     PN_CPP_EXTERN connection_options& max_frame_size(uint32_t max);
 
-    /// Set the maximum number of open sessions.  The default value is 32767.
+    /// Set the maximum number of open sessions.  The default is 32767.
     PN_CPP_EXTERN connection_options& max_sessions(uint16_t max);
 
-    /// Set the idle timeout.  By default, none is set.
+    /// Set the idle timeout.  The default is no timeout.
     ///
-    /// If set, the local peer will disconnect if it does not receive
-    /// AMQP frames before the timeout expires.  This serves as
-    /// "heartbeating", a way to detect dead peers even in the
+    /// If set, the local peer will disconnect if it receives no AMQP
+    /// frames for an interval longer than `duration`.  Also known as
+    /// "heartbeating", this is a way to detect dead peers even in the
     /// presence of a live TCP connection.
     PN_CPP_EXTERN connection_options& idle_timeout(duration);
 
     /// Set the container ID.
     PN_CPP_EXTERN connection_options& container_id(const std::string& id);
 
-    /// Set the virtual host name for the connection. If making a
-    /// client connection by SSL/TLS, this name is also used for
-    /// certificate verification and Server Name Indication.  For
-    /// client connections, it defaults to the host name used to set
-    /// up the connection.  For server connections, it is not set by
-    /// default.
+    /// Set the virtual host name for the connection. For client
+    /// connections, it defaults to the host name used to set up the
+    /// connection.  For server connections, it is unset by default.
+    ///
+    /// If making a client connection by SSL/TLS, this name is also
+    /// used for certificate verification and Server Name Indication.
     PN_CPP_EXTERN connection_options& virtual_host(const std::string& name);
 
     /// Set the user name used to authenticate the connection.  It is
@@ -117,8 +117,7 @@ class connection_options {
     /// connection's identity is provided by the remote client.
     PN_CPP_EXTERN connection_options& user(const std::string&);
 
-    /// Set the password used to authenticate the connection.  It has
-    /// no default value.
+    /// Set the password used to authenticate the connection.
     ///
     /// This value is ignored if the connection is created by
     /// container::listen.
@@ -140,7 +139,7 @@ class connection_options {
     /// Enable or disable SASL.
     PN_CPP_EXTERN connection_options& sasl_enabled(bool);
 
-    /// Force the enabling of SASL mechanisms that disclose clear text
+    /// Force the enabling of SASL mechanisms that disclose cleartext
     /// passwords over the connection.  By default, such mechanisms
     /// are disabled.
     PN_CPP_EXTERN connection_options& sasl_allow_insecure_mechs(bool);
@@ -148,10 +147,10 @@ class connection_options {
     /// Specify the allowed mechanisms for use on the connection.
     PN_CPP_EXTERN connection_options& sasl_allowed_mechs(const std::string&);
 
-    /// **Experimental** - Set the SASL configuration name.
+    /// **Unsettled API** - Set the SASL configuration name.
     PN_CPP_EXTERN connection_options& sasl_config_name(const std::string&);
 
-    /// **Experimental** - Set the SASL configuration path.
+    /// **Unsettled API** - Set the SASL configuration path.
     PN_CPP_EXTERN connection_options& sasl_config_path(const std::string&);
 
     /// Update option values from values set in other.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index 64e52ad..d447abe 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -124,7 +124,7 @@ class PN_CPP_CLASS_EXTERN container {
     /// auto_stop is set by default when a new container is created.
     PN_CPP_EXTERN void auto_stop(bool);
 
-    /// **Experimental** - Stop the container with an error_condition
+    /// **Unsettled API** - Stop the container with an error_condition
     /// err.
     ///
     ///  - Abort all open connections and listeners.
@@ -133,7 +133,7 @@ class PN_CPP_CLASS_EXTERN container {
     ///  - run() will return in all threads.
     PN_CPP_EXTERN void stop(const error_condition& err);
 
-    /// **Experimental** - Stop the container with an empty error
+    /// **Unsettled API** - Stop the container with an empty error
     /// condition.
     ///
     /// @see stop(const error_condition&)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/error_condition.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/error_condition.hpp b/proton-c/bindings/cpp/include/proton/error_condition.hpp
index fb0d461..159356e 100644
--- a/proton-c/bindings/cpp/include/proton/error_condition.hpp
+++ b/proton-c/bindings/cpp/include/proton/error_condition.hpp
@@ -50,7 +50,7 @@ class error_condition {
     /// Create an error condition with a name and description.
     PN_CPP_EXTERN error_condition(std::string name, std::string description);
 
-    /// **Experimental** - Create an error condition with name,
+    /// **Unsettled API** - Create an error condition with name,
     /// description, and informational properties.
     PN_CPP_EXTERN error_condition(std::string name, std::string description, proton::value properties);
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/internal/data.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/internal/data.hpp b/proton-c/bindings/cpp/include/proton/internal/data.hpp
index 0e35486..97f900a 100644
--- a/proton-c/bindings/cpp/include/proton/internal/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/internal/data.hpp
@@ -78,7 +78,7 @@ class data : public object<pn_data_t> {
 };
 /// @endcond
 
-/// **Experimental** - Save and restore codec state
+/// **Unsettled API** - Save and restore codec state
 ///
 /// A state_guard saves the state and restores it in the destructor
 /// unless cancel() is called.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
index f9774ac..a7e96fe 100644
--- a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
+++ b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
@@ -39,7 +39,7 @@ class proton_handler;
 
 namespace io {
 
-/// **Experimental** - Pointer to a mutable memory region with a size.
+/// **Unsettled API** - Pointer to a mutable memory region with a size.
 struct mutable_buffer {
     char* data;                 ///< Beginning of the buffered data.
     size_t size;                ///< Number of bytes in the buffer.
@@ -48,7 +48,7 @@ struct mutable_buffer {
     mutable_buffer(char* data_=0, size_t size_=0) : data(data_), size(size_) {}
 };
 
-/// **Experimental** - Pointer to a const memory region with a size.
+/// **Unsettled API** - Pointer to a const memory region with a size.
 struct const_buffer {
     const char* data;           ///< Beginning of the buffered data.
     size_t size;                ///< Number of bytes in the buffer.
@@ -57,7 +57,7 @@ struct const_buffer {
     const_buffer(const char* data_=0, size_t size_=0) : data(data_), size(size_) {}
 };
 
-/// **Experimental** - An AMQP driver for a single connection.
+/// **Unsettled API** - An AMQP driver for a single connection.
 ///
 /// io::connection_driver manages a single proton::connection and dispatches
 /// events to a proton::messaging_handler. It does no IO of its own, but allows you to

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/io/link_namer.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/io/link_namer.hpp b/proton-c/bindings/cpp/include/proton/io/link_namer.hpp
index a0eea67..e6d84ee 100644
--- a/proton-c/bindings/cpp/include/proton/io/link_namer.hpp
+++ b/proton-c/bindings/cpp/include/proton/io/link_namer.hpp
@@ -31,7 +31,7 @@ class connection;
 
 namespace io {
 
-/// **Experimental** - Generate default link names that are unique
+/// **Unsettled API** - Generate default link names that are unique
 /// within a container.  base_container provides a default
 /// implementation.
 class link_namer {
@@ -42,7 +42,7 @@ class link_namer {
     virtual std::string link_name() = 0;
 };
 
-/// *Experimental* - Set the link_namer to use on a connection.
+/// **Unsettled API** - Set the link_namer to use on a connection.
 PN_CPP_EXTERN void set_link_namer(connection&, link_namer&);
 
 } // io

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp
index 8627ec9..eb28613 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -64,7 +64,7 @@ PN_CPP_CLASS_EXTERN link : public internal::object<pn_link_t> , public endpoint
     /// Credit available on the link.
     PN_CPP_EXTERN int credit() const;
 
-    /// **Experimental** - True for a receiver if a drain cycle has
+    /// **Unsettled API** - True for a receiver if a drain cycle has
     /// been started and the corresponding `on_receiver_drain_finish`
     /// event is still pending.  True for a sender if the receiver has
     /// requested a drain of credit and the sender has unused credit.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/listen_handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/listen_handler.hpp b/proton-c/bindings/cpp/include/proton/listen_handler.hpp
index 08d5e76..5373c54 100644
--- a/proton-c/bindings/cpp/include/proton/listen_handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/listen_handler.hpp
@@ -27,7 +27,7 @@
 namespace proton {
 
 // XXX Discuss more
-/// **Experimental** - A handler for incoming connections.
+/// **Unsettled API** - A handler for incoming connections.
 ///
 /// Implement this interface and pass to proton::container::listen()
 /// to be notified of new connections.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/map.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/map.hpp b/proton-c/bindings/cpp/include/proton/map.hpp
index 86948e5..dade948 100644
--- a/proton-c/bindings/cpp/include/proton/map.hpp
+++ b/proton-c/bindings/cpp/include/proton/map.hpp
@@ -1,5 +1,5 @@
-#ifndef PROTON_CPP_MAP_H
-#define PROTON_CPP_MAP_H
+#ifndef PROTON_MAP_HPP
+#define PROTON_MAP_HPP
 
 /*
  *
@@ -23,8 +23,7 @@
  */
 
 #include "./value.hpp"
-
-#include "internal/pn_unique_ptr.hpp"
+#include "./internal/pn_unique_ptr.hpp"
 
 #include <cstddef>
 
@@ -51,14 +50,16 @@ PN_CPP_EXTERN proton::codec::encoder& operator<<(proton::codec::encoder& e, cons
 template <class K, class T>
 PN_CPP_EXTERN void swap(map<K,T>&, map<K,T>&);
 
-/// Used to access standard AMQP property, annotation and filter maps attached
-/// to proton::message and proton::source.
+/// A collection of key-value pairs.
 ///
-/// Provides only basic get()/set() operations for convenience.  For more
-/// complicated use (iteration, preserving order etc.) you should convert to a
-/// standard C++ map type such as std::map. See @ref message_properties.cpp
-/// and @ref types_page.
+/// Used to access standard AMQP property, annotation, and filter maps
+/// attached to proton::message and proton::source.
 ///
+/// This class provides only basic get() and put() operations for
+/// convenience.  For more complicated uses (iteration, preserving
+/// order, and so on), convert the value to a standard C++ map type
+/// such as `std::map`. See @ref message_properties.cpp and @ref
+/// types_page.
 template <class K, class T>
 class PN_CPP_CLASS_EXTERN map {
     template <class M, class U=void>
@@ -66,50 +67,69 @@ class PN_CPP_CLASS_EXTERN map {
             public internal::enable_if<codec::is_encodable_map<M,K,T>::value, U> {};
 
  public:
-    /// @name Construct and assign
-    /// @{
+    /// Construct an empty map.
     PN_CPP_EXTERN map();
-    PN_CPP_EXTERN map(const map& cm);
-    PN_CPP_EXTERN map& operator=(const map& cm);
+
+    /// Copy a map.
+    PN_CPP_EXTERN map(const map&);
+
+    /// Copy a map.
+    PN_CPP_EXTERN map& operator=(const map&);
+
 #if PN_CPP_HAS_RVALUE_REFERENCES
+    /// Move a map.
     PN_CPP_EXTERN map(map&&);
+
+    /// Move a map.
     PN_CPP_EXTERN map& operator=(map&&);
 #endif
-    ///@}
     PN_CPP_EXTERN ~map();
 
-    /// Type-safe assign from a compatible map, e.g. std::map<K,T> - see @ref types_page
+    /// Type-safe assign from a compatible map, for instance
+    /// `std::map<K,T>`. See @ref types_page.
     template <class M>
-    typename assignable_map<M, map&>::type operator=(const M& x) { value(x); return *this;}
+    typename assignable_map<M, map&>::type operator=(const M& x) { value(x); return *this; }
 
     /// Copy from a proton::value.
-    /// @throw proton::conversion_error if x does not contain a compatible map.
+    ///
+    /// @throw proton::conversion_error if `x` does not contain a
+    /// compatible map.
     PN_CPP_EXTERN void value(const value& x);
-    /// Access as a proton::value containing an AMQP map
+
+    /// Access as a proton::value containing an AMQP map.
     PN_CPP_EXTERN proton::value& value();
-    /// Access as a proton::value containing an AMQP map
+
+    /// Access as a proton::value containing an AMQP map.
     PN_CPP_EXTERN const proton::value& value() const;
 
-    /// Get the map entry for key k, return T() if no such entry
+    /// Get the map entry for key `k`.  Return `T()` if there is no
+    /// such entry.
     PN_CPP_EXTERN T get(const K& k) const;
-    /// Put a map entry for key k.
+
+    /// Put a map entry for key `k`.
     PN_CPP_EXTERN void put(const K& k, const T& v);
-    /// Erase the map entry at k
+
+    /// Erase the map entry at `k`.
     PN_CPP_EXTERN size_t erase(const K& k);
-    /// True if there is a map entry for k
+
+    /// True if the map has an entry for `k`.
     PN_CPP_EXTERN bool exists(const K& k) const;
-    /// Number of map entries
+
+    /// Get the number of map entries.
     PN_CPP_EXTERN size_t size() const;
-    /// Clear the map
+
+    /// Remove all map entries.
     PN_CPP_EXTERN void clear();
-    /// True if the map is empty
+
+    /// True if the map has no entries.
     PN_CPP_EXTERN bool empty() const;
 
-    ///@cond INTERNAL
+    /// @cond INTERNAL
     explicit map(pn_data_t*);
     void reset(pn_data_t*);
+    /// @endcond
 
- private:
+  private:
     typedef map_type_impl<K,T> map_type;
     mutable internal::pn_unique_ptr<map_type> map_;
     mutable proton::value value_;
@@ -117,12 +137,13 @@ class PN_CPP_CLASS_EXTERN map {
     map_type& cache() const;
     proton::value& flush() const;
 
+    /// @cond INTERNAL
   friend PN_CPP_EXTERN proton::codec::decoder& operator>> <>(proton::codec::decoder&, map&);
   friend PN_CPP_EXTERN proton::codec::encoder& operator<< <>(proton::codec::encoder&, const map&);
   friend PN_CPP_EXTERN void swap<>(map&, map&);
-  /// @endcond
+    /// @endcond
 };
 
-} // namespace proton
+} // proton
 
-#endif // PROTON_CPP_MAP_H
+#endif // PROTON_MAP_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/message.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp
index a428c46..40aa98c 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -46,11 +46,11 @@ namespace proton {
 /// message.
 class message {
   public:
-    /// **Experimental** - A map of string keys and AMQP scalar
+    /// **Unsettled API** - A map of string keys and AMQP scalar
     /// values.
     typedef map<std::string, scalar> property_map;
 
-    /// **Experimental** - A map of AMQP annotation keys and AMQP
+    /// **Unsettled API** - A map of AMQP annotation keys and AMQP
     /// values.
     typedef map<annotation_key, value> annotation_map;
 
@@ -287,17 +287,17 @@ class message {
 
     /// @}
 
-    /// @name **Experimental** - Application properties
+    /// @name **Unsettled API** - Application properties
     /// @{
 
-    /// **Experimental** - Get the application properties map.  It can
+    /// **Unsettled API** - Get the application properties map.  It can
     /// be modified in place.
     PN_CPP_EXTERN property_map& properties();
 
-    /// **Experimental** - examine the application properties map.
+    /// **Unsettled API** - examine the application properties map.
     PN_CPP_EXTERN const property_map& properties() const;
 
-    /// @name **Experimental** - Annotations
+    /// @name **Unsettled API** - Annotations
     ///
     /// Normally used by messaging infrastructure, not applications.
     /// @{

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
index a5e2bdd..9c4d8f8 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
@@ -143,11 +143,11 @@ PN_CPP_CLASS_EXTERN messaging_handler {
     /// The sending peer settled a transfer.
     PN_CPP_EXTERN virtual void on_delivery_settle(delivery &d);
 
-    /// **Experimental** - The receiving peer has requested a drain of
+    /// **Unsettled API** - The receiving peer has requested a drain of
     /// remaining credit.
     PN_CPP_EXTERN virtual void on_sender_drain_start(sender &s);
     
-    /// **Experimental** - The credit outstanding at the time of the
+    /// **Unsettled API** - The credit outstanding at the time of the
     /// call to receiver::drain has been consumed or returned.
     PN_CPP_EXTERN virtual void on_receiver_drain_finish(receiver &r);
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/namespaces.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/namespaces.hpp b/proton-c/bindings/cpp/include/proton/namespaces.hpp
index 62b4913..d7b5cf9 100644
--- a/proton-c/bindings/cpp/include/proton/namespaces.hpp
+++ b/proton-c/bindings/cpp/include/proton/namespaces.hpp
@@ -23,7 +23,7 @@
 /// The main Proton namespace.
 namespace proton {
 
-/// **Experimental** - AMQP data encoding and decoding.
+/// **Unsettled API** - AMQP data encoding and decoding.
 ///
 /// You can use these classes on an experimental basis to create your
 /// own AMQP encodings for C++ types, but they may change in the
@@ -32,7 +32,7 @@ namespace proton {
 namespace codec {
 }
 
-/// **Experimental** - An SPI for multithreaded network IO.
+/// **Unsettled API** - An SPI for multithreaded network IO.
 namespace io {
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp
index b995e6f..46e5c4d 100644
--- a/proton-c/bindings/cpp/include/proton/receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver.hpp
@@ -63,7 +63,7 @@ PN_CPP_CLASS_EXTERN receiver : public link {
     /// the drain completes.
     PN_CPP_EXTERN void add_credit(uint32_t);
 
-    /// **Experimental** - Commence a drain cycle.  If there is
+    /// **Unsettled API** - Commence a drain cycle.  If there is
     /// positive credit, a request is sent to the sender to
     /// immediately use up all of the existing credit balance by
     /// sending messages that are immediately available and releasing

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/receiver_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver_options.hpp b/proton-c/bindings/cpp/include/proton/receiver_options.hpp
index 413e4d4..1e43adb 100644
--- a/proton-c/bindings/cpp/include/proton/receiver_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver_options.hpp
@@ -62,42 +62,46 @@ class receiver_options {
     /// Copy options.
     PN_CPP_EXTERN receiver_options& operator=(const receiver_options&);
 
-    /// Merge with another option set
+    /// Merge with another option set.
     PN_CPP_EXTERN void update(const receiver_options& other);
 
-    /// Set a messaging_handler for receiver events only.
-    /// The handler is no longer in use when messaging_handler::on_receiver_close() is called.
+    /// Set a messaging_handler for receiver events only.  The handler
+    /// is no longer in use when
+    /// messaging_handler::on_receiver_close() is called.
     PN_CPP_EXTERN receiver_options& handler(class messaging_handler&);
 
-    /// Set the delivery mode on the receiver.
+    /// Set the delivery mode on the receiver.  The default is
+    /// delivery_mode::AT_LEAST_ONCE.
     PN_CPP_EXTERN receiver_options& delivery_mode(delivery_mode);
 
-    /// Automatically accept inbound messages that aren't otherwise
-    /// released, rejected, or modified (default is true).
+    /// Enable or disable automatic acceptance of messages that aren't
+    /// otherwise released, rejected, or modified.  It is enabled by
+    /// default.
     PN_CPP_EXTERN receiver_options& auto_accept(bool);
 
-    /// Automatically settle messages (default is true).
+    /// Enable or disable automatic settlement of messages.  It is
+    /// enabled by default.
     PN_CPP_EXTERN receiver_options& auto_settle(bool);
 
     /// Options for the source node of the receiver.
-    PN_CPP_EXTERN receiver_options& source(source_options &);
+    PN_CPP_EXTERN receiver_options& source(source_options&);
 
     /// Options for the target node of the receiver.
-    PN_CPP_EXTERN receiver_options& target(target_options &);
+    PN_CPP_EXTERN receiver_options& target(target_options&);
 
-    /// Set automated flow control to pre-fetch this many messages
-    /// (default is 10).  Set to zero to disable automatic credit
-    /// replenishing.
-    PN_CPP_EXTERN receiver_options& credit_window(int);
+    /// Automatically replenish credit for flow control up to `count`
+    /// messages.  The default is 10.  Set to zero to disable
+    /// automatic replenishment.
+    PN_CPP_EXTERN receiver_options& credit_window(int count);
 
-    /// @cond INTERNAL
   private:
     void apply(receiver &) const;
 
     class impl;
     internal::pn_unique_ptr<impl> impl_;
 
-    friend class receiver;
+    /// @cond INTERNAL
+  friend class receiver;
     /// @endcond
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp
index b01f21c..7a1ae15 100644
--- a/proton-c/bindings/cpp/include/proton/sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender.hpp
@@ -60,7 +60,7 @@ PN_CPP_CLASS_EXTERN sender : public link {
     /// Get the target node.
     PN_CPP_EXTERN class target target() const;
 
-    /// **Experimental** - Return all unused credit to the receiver in
+    /// **Unsettled API** - Return all unused credit to the receiver in
     /// response to a drain request.  Has no effect unless there has
     /// been a drain request and there is remaining credit to use or
     /// return.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/sender_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender_options.hpp b/proton-c/bindings/cpp/include/proton/sender_options.hpp
index 9d7bb42..ea7f7d3 100644
--- a/proton-c/bindings/cpp/include/proton/sender_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender_options.hpp
@@ -43,14 +43,13 @@ namespace proton {
 ///
 /// @code
 /// sender_options opts;
-/// opts.browsing(true);
+/// opts.delivery_mode(delivery_mode::AT_MOST_ONCE);
 /// l1 = container.open_sender(url1, opts.handler(h1));
 /// c2 = container.open_receiver(url2, opts.handler(h2));
 /// @endcode
 ///
 /// Normal value semantics: copy or assign creates a separate copy of
 /// the options.
-// XXX opts.browsing is not a good example here
 class sender_options {
   public:
     /// Create an empty set of options.
@@ -80,19 +79,19 @@ class sender_options {
     PN_CPP_EXTERN sender_options& auto_settle(bool);
 
     /// Options for the source node of the sender.
-    PN_CPP_EXTERN sender_options& source(const source_options &);
+    PN_CPP_EXTERN sender_options& source(const source_options&);
 
     /// Options for the receiver node of the receiver.
-    PN_CPP_EXTERN sender_options& target(const target_options &);
+    PN_CPP_EXTERN sender_options& target(const target_options&);
 
-    /// @cond INTERNAL
   private:
     void apply(sender&) const;
 
     class impl;
     internal::pn_unique_ptr<impl> impl_;
 
-    friend class sender;
+    /// @cond INTERNAL
+  friend class sender;
     /// @endcond
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/session_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/session_options.hpp b/proton-c/bindings/cpp/include/proton/session_options.hpp
index eb47a89..9672c82 100644
--- a/proton-c/bindings/cpp/include/proton/session_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/session_options.hpp
@@ -34,7 +34,6 @@ namespace proton {
 ///
 /// Normal value semantics: copy or assign creates a separate copy of
 /// the options.
-// XXX Does this need the CLASS_EXTERN stuff? - Add just for consistency
 class session_options {
   public:
     /// Create an empty set of options.
@@ -51,8 +50,9 @@ class session_options {
     /// Set a messaging_handler for the session.
     PN_CPP_EXTERN session_options& handler(class messaging_handler &);
 
-    /// @cond INTERNAL
     // Other useful session configuration TBD.
+
+    /// @cond INTERNAL
   private:
     void apply(session&) const;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/source.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/source.hpp b/proton-c/bindings/cpp/include/proton/source.hpp
index 59963dd..52afd8f 100644
--- a/proton-c/bindings/cpp/include/proton/source.hpp
+++ b/proton-c/bindings/cpp/include/proton/source.hpp
@@ -40,7 +40,7 @@ namespace proton {
 /// @see proton::sender, proton::receiver, proton::target
 class source : public terminus {
   public:
-    /// **Experimental** - A map of AMQP symbol keys and filter
+    /// **Unsettled API** - A map of AMQP symbol keys and filter
     /// specifiers.
     typedef map<symbol, value> filter_map;
 
@@ -68,7 +68,7 @@ class source : public terminus {
     /// Get the distribution mode.
     PN_CPP_EXTERN enum distribution_mode distribution_mode() const;
 
-    /// **Experimental** - Obtain the set of message filters.
+    /// **Unsettled API** - Obtain the set of message filters.
     PN_CPP_EXTERN const filter_map& filters() const;
 
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/source_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/source_options.hpp b/proton-c/bindings/cpp/include/proton/source_options.hpp
index 19e3cdf..1b2876c 100644
--- a/proton-c/bindings/cpp/include/proton/source_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/source_options.hpp
@@ -40,7 +40,6 @@ namespace proton {
 /// the options.
 class source_options {
   public:
-
     /// Create an empty set of options.
     PN_CPP_EXTERN source_options();
 
@@ -52,26 +51,32 @@ class source_options {
     /// Copy options.
     PN_CPP_EXTERN source_options& operator=(const source_options&);
 
-    /// Set the address for the source.  Ignored if dynamic is true.
+    /// Set the address for the source.  It is unset by default.  The
+    /// address is ignored if dynamic() is true.
     PN_CPP_EXTERN source_options& address(const std::string&);
 
-    /// Request a dynamically created node to be created by the remote peer.
-    /// Any specified source address is ignored.
+    /// Request that a node be dynamically created by the remote peer.
+    /// The default is false.  Any specified source address() is
+    /// ignored.
     PN_CPP_EXTERN source_options& dynamic(bool);
 
-    /// Control whether messsages are browsed or consumed.
+    /// Control whether messsages are browsed or consumed.  The
+    /// default is source::MOVE, meaning consumed.
     PN_CPP_EXTERN source_options& distribution_mode(enum source::distribution_mode);
 
-    /// Control the persistence of source state.
+    /// Control the persistence of the source node.  The default is
+    /// source::NONDURABLE, meaning non-persistent.
     PN_CPP_EXTERN source_options& durability_mode(enum source::durability_mode);
 
-    /// The expiry period after which the source is discarded.
+    /// The expiry period after which the source is discarded.  The
+    /// default is no timeout.
     PN_CPP_EXTERN source_options& timeout(duration);
 
-    /// Control when the clock for expiration begins.
+    /// Control when the clock for expiration begins.  The default is
+    /// source::LINK_CLOSE.
     PN_CPP_EXTERN source_options& expiry_policy(enum source::expiry_policy);
 
-    /// **Experimental** - Specify a filter mechanism on the source
+    /// **Unsettled API** - Specify a filter mechanism on the source
     /// that restricts message flow to a subset of the available
     /// messages.
     PN_CPP_EXTERN source_options& filters(const source::filter_map&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/ssl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/ssl.hpp b/proton-c/bindings/cpp/include/proton/ssl.hpp
index c6c4c93..896c23d 100644
--- a/proton-c/bindings/cpp/include/proton/ssl.hpp
+++ b/proton-c/bindings/cpp/include/proton/ssl.hpp
@@ -92,7 +92,7 @@ class ssl {
     /// @endcond
 };
 
-/// **Experimental** - An SSL certificate.
+/// **Unsettled API** - An SSL certificate.
 class ssl_certificate {
   public:
     /// Create an SSL certificate.
@@ -141,7 +141,7 @@ class ssl_domain {
 
 }
 
-/// **Experimental** - SSL configuration for inbound connections.
+/// **Unsettled API** - SSL configuration for inbound connections.
 class ssl_server_options : private internal::ssl_domain {
   public:
     /// Server SSL options based on the supplied X.509 certificate
@@ -168,7 +168,7 @@ class ssl_server_options : private internal::ssl_domain {
     /// @endcond
 };
 
-/// **Experimental** - SSL configuration for outbound connections.
+/// **Unsettled API** - SSL configuration for outbound connections.
 class ssl_client_options : private internal::ssl_domain {
   public:
     /// Create SSL client options (no client certificate).

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/symbol.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/symbol.hpp b/proton-c/bindings/cpp/include/proton/symbol.hpp
index 303f350..3f60540 100644
--- a/proton-c/bindings/cpp/include/proton/symbol.hpp
+++ b/proton-c/bindings/cpp/include/proton/symbol.hpp
@@ -26,18 +26,18 @@
 
 namespace proton {
 
-/// A std::string that represents the AMQP symbol type.
+/// A `std::string` that represents the AMQP symbol type.
 ///
-/// A symbol can only contain 7-bit ASCII characters.
+/// A symbol can contain only 7-bit ASCII characters.
 class symbol : public std::string {
   public:
-    /// Construct from a std::string.
+    /// Construct from a `std::string`.
     symbol(const std::string& s=std::string()) : std::string(s) {}
 
     /// Construct from a C string.
     symbol(const char* s) : std::string(s) {}
 
-    /// Construct from any sequence of char.
+    /// Construct from any sequence of `char`.
     template<class Iter> symbol(Iter start, Iter finish) : std::string(start, finish) {}
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/target_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/target_options.hpp b/proton-c/bindings/cpp/include/proton/target_options.hpp
index 0f2245b..05249d0 100644
--- a/proton-c/bindings/cpp/include/proton/target_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/target_options.hpp
@@ -51,20 +51,25 @@ class target_options {
     /// Copy options.
     PN_CPP_EXTERN target_options& operator=(const target_options&);
 
-    /// Set the address for the target.  Ignored if dynamic is true.
+    /// Set the address for the target.  It is unset by default.  The
+    /// address is ignored if dynamic() is true.
     PN_CPP_EXTERN target_options& address(const std::string& addr);
 
-    /// Request a dynamically created node to be created by the peer.
-    /// Any specified target address is ignored.
+    /// Request that a node be dynamically created by the remote peer.
+    /// The default is false.  Any specified target address() is
+    /// ignored.
     PN_CPP_EXTERN target_options& dynamic(bool);
 
-    /// Control the persistence of target state.
+    /// Control the persistence of the target node.  The default is
+    /// target::NONDURABLE, meaning non-persistent.
     PN_CPP_EXTERN target_options& durability_mode(enum target::durability_mode);
 
-    /// The expiry period after which the target is discarded.
+    /// The expiry period after which the target is discarded.  The
+    /// default is no timeout.
     PN_CPP_EXTERN target_options& timeout(duration);
 
-    /// Control when the clock for expiration begins.
+    /// Control when the clock for expiration begins.  The default is
+    /// target::LINK_CLOSE.
     PN_CPP_EXTERN target_options& expiry_policy(enum target::expiry_policy);
 
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/url.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/url.hpp b/proton-c/bindings/cpp/include/proton/url.hpp
index b94b24d..28f31e9 100644
--- a/proton-c/bindings/cpp/include/proton/url.hpp
+++ b/proton-c/bindings/cpp/include/proton/url.hpp
@@ -70,7 +70,7 @@ class url {
     /// @cond INTERNAL
     /// XXX I want to understand why this is important to keep.
     ///
-    /// **Experimental** - Parse `url_str` as an AMQP URL. If
+    /// **Unsettled API** - Parse `url_str` as an AMQP URL. If
     /// `defaults` is true, fill in defaults for missing values.
     /// Otherwise, return an empty string for missing values.
     ///

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b60f093a/proton-c/bindings/cpp/include/proton/work_queue.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/work_queue.hpp b/proton-c/bindings/cpp/include/proton/work_queue.hpp
index 2d728fd..f5e60cd 100644
--- a/proton-c/bindings/cpp/include/proton/work_queue.hpp
+++ b/proton-c/bindings/cpp/include/proton/work_queue.hpp
@@ -37,21 +37,21 @@ struct pn_link_t;
 
 namespace proton {
 
-/// **Experimental** - Work to be queued on a @ref work_queue.  It can
+/// **Unsettled API** - Work to be queued on a @ref work_queue.  It can
 /// be created from a function that takes no parameters and returns no
 /// value.
 class work {
   public:
 #if PN_CPP_HAS_STD_FUNCTION
-    /// **Experimental**
+    /// **Unsettled API**
     work(void_function0& f): item_( [&f]() { f(); }) {}
 
-    /// **Experimental** - Construct a unit of work from a
+    /// **Unsettled API** - Construct a unit of work from a
     /// std::function.
     template <class T>
     work(T f): item_(f) {}
 
-    /// **Experimental**
+    /// **Unsettled API**
     void operator()() { item_(); }
 #else
     /// **Experimetnal**
@@ -71,7 +71,7 @@ class work {
 #endif
 };
 
-/// **Experimental** - A work queue for serial execution.
+/// **Unsettled API** - A work queue for serial execution.
 ///
 /// Event handler functions associated with a single
 /// proton::connection are called in sequence.  The connection's
@@ -94,15 +94,15 @@ class PN_CPP_CLASS_EXTERN work_queue {
     /// @endcond
 
   public:
-    /// **Experimental** - Create a work_queue.
+    /// **Unsettled API** - Create a work_queue.
     PN_CPP_EXTERN work_queue();
 
-    /// **Experimental** - Create a work_queue backed by `container`.
+    /// **Unsettled API** - Create a work_queue backed by `container`.
     PN_CPP_EXTERN work_queue(container&);
 
     PN_CPP_EXTERN ~work_queue();
 
-    /// **Experimental** - Add work to the work queue: f() will be
+    /// **Unsettled API** - Add work to the work queue: f() will be
     /// called serialised with other work in the queue: deferred and
     /// possibly in another thread.
     ///
@@ -110,7 +110,7 @@ class PN_CPP_CLASS_EXTERN work_queue {
     /// or f() cannot be injected for any other reason.
     PN_CPP_EXTERN bool add(work f);
 
-    /// **Experimental** - Add work to the work queue after duration:
+    /// **Unsettled API** - Add work to the work queue after duration:
     /// f() will be called after the duration serialised with other
     /// work in the queue: possibly in another thread.
     ///
@@ -363,19 +363,19 @@ void schedule_work(WQ wq, duration dn, F f, A a, B b, C c, D d) {
 // The C++11 version is *much* simpler and even so more general!
 // These definitions encompass everything in the C++03 section
 
-/// **Experimental**
+/// **Unsettled API**
 template <class WQ, class... Rest>
 bool schedule_work(WQ wq, Rest&&... r) {
     return wq->add(std::bind(std::forward<Rest>(r)...));
 }
 
-/// **Experimental**
+/// **Unsettled API**
 template <class WQ, class... Rest>
 void schedule_work(WQ wq, duration d, Rest&&... r) {
     wq->schedule(d, std::bind(std::forward<Rest>(r)...));
 }
 
-/// **Experimental**
+/// **Unsettled API**
 template <class... Rest>
 work make_work(Rest&&... r) {
     return std::bind(std::forward<Rest>(r)...);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[16/50] qpid-proton git commit: NO-JIRA: cpp: minor doc update for connection options

Posted by ac...@apache.org.
NO-JIRA: cpp: minor doc update for connection options


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/31c16db1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/31c16db1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/31c16db1

Branch: refs/heads/go1
Commit: 31c16db1286fca5c37f0e0853fe4d65bc7e534bd
Parents: b4e1dd0
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Aug 11 12:00:46 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Aug 11 12:00:46 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/include/proton/connection_options.hpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/31c16db1/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index 9c7923e..2769a7e 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -108,10 +108,11 @@ class connection_options {
     /// This will override any user name that is specified in the url
     /// used for container::connect.
     /// It will be ignored if the connection is created by container::listen as
-    /// a listening connection has no user name.
+    /// a listening connection's identity is provided by the remote client.
     PN_CPP_EXTERN connection_options& user(const std::string& user);
 
     /// Set the password used to authenticate the connection
+    /// It will be ignored if the connection is created by container::listen.
     PN_CPP_EXTERN connection_options& password(const std::string& pass);
 
     /// @cond INTERNAL


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[42/50] qpid-proton git commit: NO-JIRA: c++ backwards compatible thread_safe.hpp stub

Posted by ac...@apache.org.
NO-JIRA: c++ backwards compatible thread_safe.hpp stub

Empty file to prevent compile failures for code with #include thread_safe.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/28061408
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/28061408
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/28061408

Branch: refs/heads/go1
Commit: 2806140889079fd082a748e56e383bbc7d091f06
Parents: d0d61a5
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Aug 30 16:13:36 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Aug 30 16:15:04 2017 -0400

----------------------------------------------------------------------
 .../bindings/cpp/include/proton/thread_safe.hpp | 26 ++++++++++++++++++++
 1 file changed, 26 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/28061408/proton-c/bindings/cpp/include/proton/thread_safe.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/thread_safe.hpp b/proton-c/bindings/cpp/include/proton/thread_safe.hpp
new file mode 100644
index 0000000..7fc1bcd
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/thread_safe.hpp
@@ -0,0 +1,26 @@
+#ifndef PROTON_THREAD_SAFE_HPP
+#define PROTON_THREAD_SAFE_HPP
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// DEPRECATED: This file is no longer used and will be removed,
+// you should not include it in your code.
+
+#endif // PROTON_THREAD_SAFE_HPP


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[40/50] qpid-proton git commit: PROTON-1557: c++ correct output typo in multi-threaded examples

Posted by ac...@apache.org.
PROTON-1557: c++ correct output typo in multi-threaded examples


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/759686f1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/759686f1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/759686f1

Branch: refs/heads/go1
Commit: 759686f1e4ba0cff5aad902ae031a208341ebc4d
Parents: d7e3aa5
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Aug 30 13:28:02 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Aug 30 13:55:03 2017 -0400

----------------------------------------------------------------------
 examples/cpp/multithreaded_client.cpp              | 4 ++--
 examples/cpp/multithreaded_client_flow_control.cpp | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/759686f1/examples/cpp/multithreaded_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client.cpp b/examples/cpp/multithreaded_client.cpp
index 4119bbf..6fb7868 100644
--- a/examples/cpp/multithreaded_client.cpp
+++ b/examples/cpp/multithreaded_client.cpp
@@ -157,7 +157,7 @@ int main(int argc, const char** argv) {
                 for (int i = 0; i < n_messages; ++i) {
                     proton::message msg(std::to_string(i + 1));
                     cl.send(msg);
-                    OUT(std::cout << "sent: " << msg.body() << std::endl);
+                    OUT(std::cout << "sent \"" << msg.body() << '"' << std::endl);
                 }
             });
 
@@ -165,7 +165,7 @@ int main(int argc, const char** argv) {
         std::thread receiver([&]() {
                 for (int i = 0; i < n_messages; ++i) {
                     auto msg = cl.receive();
-                    OUT(std::cout << " received: " << msg.body() << std::endl);
+                    OUT(std::cout << "received \"" << msg.body() << '"' << std::endl);
                     ++received;
                 }
             });

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/759686f1/examples/cpp/multithreaded_client_flow_control.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client_flow_control.cpp b/examples/cpp/multithreaded_client_flow_control.cpp
index 8764793..c2b403b 100644
--- a/examples/cpp/multithreaded_client_flow_control.cpp
+++ b/examples/cpp/multithreaded_client_flow_control.cpp
@@ -218,9 +218,9 @@ void send_thread(sender& s, int n) {
     auto id = std::this_thread::get_id();
     for (int i = 0; i < n; ++i) {
         std::ostringstream ss;
-        ss << std::this_thread::get_id() << ":" << i;
+        ss << std::this_thread::get_id() << "-" << i;
         s.send(proton::message(ss.str()));
-        OUT(std::cout << id << " received: " << ss.str() << std::endl);
+        OUT(std::cout << id << " sent \"" << ss.str() << '"' << std::endl);
     }
     OUT(std::cout << id << " sent " << n << std::endl);
 }
@@ -236,7 +236,7 @@ void receive_thread(receiver& r, std::atomic_int& remaining) {
     while (remaining-- > 0) {
         auto m = r.receive();
         ++n;
-        OUT(std::cout << id << " received: " << m.body() << std::endl);
+        OUT(std::cout << id << " received \"" << m.body() << '"' << std::endl);
     }
     OUT(std::cout << id << " received " << n << " messages" << std::endl);
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[23/50] qpid-proton git commit: PROTON-1347: For Python 2.6, define NullHandler if the logging module doesn't have it

Posted by ac...@apache.org.
PROTON-1347: For Python 2.6, define NullHandler if the logging module doesn't have it


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/4657d9fb
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/4657d9fb
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/4657d9fb

Branch: refs/heads/go1
Commit: 4657d9fbd4ac999ce3aa6c790d2a80eb9334709d
Parents: 7a381d2
Author: Justin Ross <jr...@apache.org>
Authored: Thu Aug 17 16:09:40 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 17 16:09:40 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/python/proton/__init__.py | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4657d9fb/proton-c/bindings/python/proton/__init__.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py
index 43f4067..f73e99d 100644
--- a/proton-c/bindings/python/proton/__init__.py
+++ b/proton-c/bindings/python/proton/__init__.py
@@ -37,8 +37,23 @@ from proton import _compat
 
 import logging, weakref, socket, sys, threading
 
+try:
+  handler = logging.NullHandler()
+except AttributeError:
+  class NullHandler(logging.Handler):
+    def handle(self, record):
+        pass
+
+    def emit(self, record):
+        pass
+
+    def createLock(self):
+        self.lock = None
+
+  handler = NullHandler()
+
 log = logging.getLogger("proton")
-log.addHandler(logging.NullHandler())
+log.addHandler(handler)
 
 try:
   import uuid


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[27/50] qpid-proton git commit: PROTON-209: Add the minimum Ruby version and make the version notation consistent across deps

Posted by ac...@apache.org.
PROTON-209: Add the minimum Ruby version and make the version notation consistent across deps


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/06061266
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/06061266
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/06061266

Branch: refs/heads/go1
Commit: 0606126665f91edbc568ee386f0e85675823e10b
Parents: 8c3ba56
Author: Justin Ross <jr...@apache.org>
Authored: Tue Aug 22 12:13:13 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Tue Aug 22 12:13:13 2017 -0700

----------------------------------------------------------------------
 INSTALL.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/06061266/INSTALL.md
----------------------------------------------------------------------
diff --git a/INSTALL.md b/INSTALL.md
index 6a212c0..4ce2dde 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -11,8 +11,8 @@ Cross-platform dependencies
 
   - CMake 2.8.7+
   - Swig 1.3+ (for the bindings)
-  - Python 2.6+ or 3 (for the Python binding)
-  - Ruby (for the Ruby binding)
+  - Python 2.6+ (for the Python binding)
+  - Ruby 1.9+ (for the Ruby binding)
 
 Linux dependencies
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[21/50] qpid-proton git commit: PROTON-1347: Use a dedicated proton logger, not the root one; disable log output by default

Posted by ac...@apache.org.
PROTON-1347: Use a dedicated proton logger, not the root one; disable log output by default


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/73aa2d7b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/73aa2d7b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/73aa2d7b

Branch: refs/heads/go1
Commit: 73aa2d7bdf9f6332d08b7e190aadcdacbebf09ee
Parents: 1b1f3f9
Author: Justin Ross <jr...@apache.org>
Authored: Tue Aug 15 16:10:11 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Tue Aug 15 16:10:11 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/python/proton/__init__.py | 15 +++++++++------
 proton-c/bindings/python/proton/handlers.py |  9 +++++----
 proton-c/bindings/python/proton/reactor.py  | 14 ++++++++------
 3 files changed, 22 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/73aa2d7b/proton-c/bindings/python/proton/__init__.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py
index dca600b..43f4067 100644
--- a/proton-c/bindings/python/proton/__init__.py
+++ b/proton-c/bindings/python/proton/__init__.py
@@ -35,7 +35,10 @@ from cproton import *
 from .wrapper import Wrapper
 from proton import _compat
 
-import weakref, socket, sys, threading
+import logging, weakref, socket, sys, threading
+
+log = logging.getLogger("proton")
+log.addHandler(logging.NullHandler())
 
 try:
   import uuid
@@ -4064,17 +4067,17 @@ class WrappedHandlersChildSurrogate:
         delegate = self.delegate()
         if delegate:
             dispatch(delegate, method, event)
-    
+
 
 class WrappedHandlersProperty(object):
     def __get__(self, obj, clazz):
         if obj is None:
             return None
         return self.surrogate(obj).handlers
-    
+
     def __set__(self, obj, value):
         self.surrogate(obj).handlers = value
-        
+
     def surrogate(self, obj):
         key = "_surrogate"
         objdict = obj.__dict__
@@ -4085,7 +4088,7 @@ class WrappedHandlersProperty(object):
         return surrogate
 
 class WrappedHandler(Wrapper):
-    
+
   handlers = WrappedHandlersProperty()
 
   @classmethod
@@ -4096,7 +4099,7 @@ class WrappedHandler(Wrapper):
       handler = cls(impl)
       handler.__dict__["on_error"] = on_error
       return handler
-  
+
   def __init__(self, impl_or_constructor):
     Wrapper.__init__(self, impl_or_constructor)
     if list(self.__class__.__mro__).index(WrappedHandler) > 1:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/73aa2d7b/proton-c/bindings/python/proton/handlers.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/handlers.py b/proton-c/bindings/python/proton/handlers.py
index 6d3cce5..cd646aa 100644
--- a/proton-c/bindings/python/proton/handlers.py
+++ b/proton-c/bindings/python/proton/handlers.py
@@ -23,6 +23,7 @@ from proton import Collector, Connection, Delivery, Described, Endpoint, Event,
 from proton import Message, Handler, ProtonException, Transport, TransportException, ConnectionException
 from select import select
 
+log = logging.getLogger("proton")
 
 class OutgoingMessageHandler(Handler):
     """
@@ -231,9 +232,9 @@ class EndpointStateHandler(Handler):
     @classmethod
     def print_error(cls, endpoint, endpoint_type):
         if endpoint.remote_condition:
-            logging.error(endpoint.remote_condition.description or endpoint.remote_condition.name)
+            log.error(endpoint.remote_condition.description or endpoint.remote_condition.name)
         elif cls.is_local_open(endpoint) and cls.is_remote_closed(endpoint):
-            logging.error("%s closed by peer" % endpoint_type)
+            log.error("%s closed by peer" % endpoint_type)
 
     def on_link_remote_close(self, event):
         if event.link.remote_condition:
@@ -403,9 +404,9 @@ class MessagingHandler(Handler, Acking):
         """
         if event.transport.condition:
             if event.transport.condition.info:
-                logging.error("%s: %s" % (event.transport.condition.name, event.transport.condition.description, event.transport.condition.info))
+                log.error("%s: %s: %s" % (event.transport.condition.name, event.transport.condition.description, event.transport.condition.info))
             else:
-                logging.error("%s: %s" % (event.transport.condition.name, event.transport.condition.description))
+                log.error("%s: %s" % (event.transport.condition.name, event.transport.condition.description))
             if event.transport.condition.name in self.fatal_conditions:
                 event.connection.close()
         else:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/73aa2d7b/proton-c/bindings/python/proton/reactor.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py
index 7b7c701..537b280 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -38,6 +38,8 @@ try:
 except ImportError:
     import queue as Queue
 
+log = logging.getLogger("proton")
+
 class Task(Wrapper):
 
     @staticmethod
@@ -389,7 +391,7 @@ class Transaction(object):
             elif event.delivery.remote_state == Delivery.REJECTED:
                 self.handler.on_transaction_declare_failed(event)
             else:
-                logging.warning("Unexpected outcome for declare: %s" % event.delivery.remote_state)
+                log.warning("Unexpected outcome for declare: %s" % event.delivery.remote_state)
                 self.handler.on_transaction_declare_failed(event)
         elif event.delivery == self._discharge:
             if event.delivery.remote_state == Delivery.REJECTED:
@@ -552,7 +554,7 @@ class Connector(Handler):
         # if virtual-host not set, use host from address as default
         if self.virtual_host is None:
             connection.hostname = url.host
-        logging.debug("connecting to %s..." % url)
+        log.debug("connecting to %s..." % url)
 
         transport = Transport()
         if self.sasl_enabled:
@@ -583,7 +585,7 @@ class Connector(Handler):
         self._connect(event.connection, event.reactor)
 
     def on_connection_remote_open(self, event):
-        logging.debug("connected to %s" % event.connection.hostname)
+        log.debug("connected to %s" % event.connection.hostname)
         if self.reconnect:
             self.reconnect.reset()
             self.transport = None
@@ -598,15 +600,15 @@ class Connector(Handler):
                 event.transport.unbind()
                 delay = self.reconnect.next()
                 if delay == 0:
-                    logging.info("Disconnected, reconnecting...")
+                    log.info("Disconnected, reconnecting...")
                     self._connect(self.connection, event.reactor)
                     return
                 else:
-                    logging.info("Disconnected will try to reconnect after %s seconds" % delay)
+                    log.info("Disconnected will try to reconnect after %s seconds" % delay)
                     event.reactor.schedule(delay, self)
                     return
             else:
-                logging.debug("Disconnected")
+                log.debug("Disconnected")
         # See connector.cpp: conn.free()/pn_connection_release() here?
         self.connection = None
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[43/50] qpid-proton git commit: PROTON-1564: epoll proactor determine inactive state after timeout callback instead of before

Posted by ac...@apache.org.
PROTON-1564: epoll proactor determine inactive state after timeout callback instead of before


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ba696d24
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ba696d24
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ba696d24

Branch: refs/heads/go1
Commit: ba696d242787429d164fde2932b558a62b526fbc
Parents: 2806140
Author: Clifford Jansen <cl...@apache.org>
Authored: Wed Aug 30 15:44:25 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Wed Aug 30 15:44:25 2017 -0700

----------------------------------------------------------------------
 proton-c/src/proactor/epoll.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ba696d24/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 9a29869..89cad31 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -381,6 +381,7 @@ struct pn_proactor_t {
   bool need_inactive;
   bool need_timeout;
   bool timeout_set; /* timeout has been set by user and not yet cancelled or generated event */
+  bool timeout_processed;  /* timout event dispatched in the most recent event batch */
   bool timer_armed; /* timer is armed in epoll */
   bool shutting_down;
   // wake subsystem
@@ -1700,7 +1701,6 @@ static bool proactor_update_batch(pn_proactor_t *p) {
     p->need_timeout = false;
     p->timeout_set = false;
     proactor_add_event(p, PN_PROACTOR_TIMEOUT);
-    p->need_inactive = is_inactive(p);
     return true;
   }
   if (p->need_interrupt) {
@@ -1721,6 +1721,8 @@ static pn_event_t *proactor_batch_next(pn_event_batch_t *batch) {
   lock(&p->context.mutex);
   proactor_update_batch(p);
   pn_event_t *e = pn_collector_next(p->collector);
+  if (e && pn_event_type(e) == PN_PROACTOR_TIMEOUT)
+    p->timeout_processed = true;
   unlock(&p->context.mutex);
   return log_event(p, e);
 }
@@ -1896,9 +1898,15 @@ void pn_proactor_done(pn_proactor_t *p, pn_event_batch_t *batch) {
     bool rearm_timer = !p->timer_armed && !p->shutting_down;
     p->timer_armed = true;
     p->context.working = false;
+    if (p->timeout_processed) {
+      p->timeout_processed = false;
+      if (wake_if_inactive(p))
+        notify = true;
+    }
     proactor_update_batch(p);
     if (proactor_has_event(p))
-      notify = wake(&p->context);
+      if (wake(&p->context))
+        notify = true;
     unlock(&p->context.mutex);
     if (notify)
       wake_notify(&p->context);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[05/50] qpid-proton git commit: PROTON-1326: restore anonymous cyphers by lowering OpenSSL v1.1 security level just for the PN_SSL_ANONYMOUS_PEER verification mode

Posted by ac...@apache.org.
PROTON-1326: restore anonymous cyphers by lowering OpenSSL v1.1 security level just for the PN_SSL_ANONYMOUS_PEER verification mode


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/8c54c625
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/8c54c625
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/8c54c625

Branch: refs/heads/go1
Commit: 8c54c62516671375de4068158ccaa0bc1dba0a4a
Parents: 62fee10
Author: Cliff Jansen <cj...@redhat.com>
Authored: Wed Aug 2 16:34:39 2017 -0700
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 12:47:44 2017 -0400

----------------------------------------------------------------------
 proton-c/src/ssl/openssl.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8c54c625/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 8cb4e7b..f37cf49 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -72,6 +72,9 @@ struct pn_ssl_domain_t {
   char *trusted_CAs;
 
   int   ref_count;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+  int default_seclevel;
+#endif
   pn_ssl_mode_t mode;
   pn_ssl_verify_mode_t verify_mode;
 
@@ -524,6 +527,9 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
   // Mitigate the CRIME vulnerability
   SSL_CTX_set_options(domain->ctx, SSL_OP_NO_COMPRESSION);
 #endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+    domain->default_seclevel = SSL_CTX_get_security_level(domain->ctx);
+#endif
 
   // by default, allow anonymous ciphers so certificates are not required 'out of the box'
   if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_ANONYMOUS )) {
@@ -647,6 +653,10 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
   case PN_SSL_VERIFY_PEER:
   case PN_SSL_VERIFY_PEER_NAME:
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+    SSL_CTX_set_security_level(domain->ctx, domain->default_seclevel);
+#endif
+
     if (!domain->has_ca_db) {
       pn_transport_logf(NULL, "Error: cannot verify peer without a trusted CA configured.\n"
                  "       Use pn_ssl_domain_set_trusted_ca_db()");
@@ -685,6 +695,10 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
     break;
 
   case PN_SSL_ANONYMOUS_PEER:   // hippie free love mode... :)
+#if OPENSSL_VERSION_NUMBER >= 0x10100000
+    // Must use lowest OpenSSL security level to enable anonymous ciphers.
+    SSL_CTX_set_security_level(domain->ctx, 0);
+#endif
     SSL_CTX_set_verify( domain->ctx, SSL_VERIFY_NONE, NULL );
     break;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[19/50] qpid-proton git commit: PROTON-1535: allow plugins to set the hostname sent out in sasl-int frames

Posted by ac...@apache.org.
PROTON-1535: allow plugins to set the hostname sent out in sasl-int frames


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/46f3007c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/46f3007c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/46f3007c

Branch: refs/heads/go1
Commit: 46f3007c4cad01891a2993e368f92222b12e02aa
Parents: 79309b0
Author: Gordon Sim <gs...@redhat.com>
Authored: Fri Aug 11 20:33:31 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Fri Aug 11 20:33:38 2017 +0100

----------------------------------------------------------------------
 proton-c/include/proton/sasl-plugin.h |  1 +
 proton-c/src/sasl/sasl-internal.h     |  1 +
 proton-c/src/sasl/sasl.c              | 12 ++++++++++--
 3 files changed, 12 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/46f3007c/proton-c/include/proton/sasl-plugin.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/sasl-plugin.h b/proton-c/include/proton/sasl-plugin.h
index cbc6684..a6bdc85 100644
--- a/proton-c/include/proton/sasl-plugin.h
+++ b/proton-c/include/proton/sasl-plugin.h
@@ -125,6 +125,7 @@ PN_EXTERN const char *pnx_sasl_get_selected_mechanism(pn_transport_t *transport)
 PN_EXTERN void  pnx_sasl_set_bytes_out(pn_transport_t *transport, pn_bytes_t bytes);
 PN_EXTERN void  pnx_sasl_set_desired_state(pn_transport_t *transport, enum pnx_sasl_state desired_state);
 PN_EXTERN void  pnx_sasl_set_selected_mechanism(pn_transport_t *transport, const char *mechanism);
+PN_EXTERN void  pnx_sasl_set_local_hostname(pn_transport_t * transport, const char * fqdn);
 PN_EXTERN void  pnx_sasl_succeed_authentication(pn_transport_t *transport, const char *username);
 PN_EXTERN void  pnx_sasl_fail_authentication(pn_transport_t *transport);
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/46f3007c/proton-c/src/sasl/sasl-internal.h
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl-internal.h b/proton-c/src/sasl/sasl-internal.h
index fc141b4..aade2e0 100644
--- a/proton-c/src/sasl/sasl-internal.h
+++ b/proton-c/src/sasl/sasl-internal.h
@@ -46,6 +46,7 @@ struct pni_sasl_t {
   const char *username;
   char *password;
   const char *remote_fqdn;
+  char *local_fqdn;
   char *external_auth;
   int external_ssf;
   size_t max_encrypt_size;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/46f3007c/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index a39e602..1469c51 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -439,8 +439,8 @@ static void pni_post_sasl_frame(pn_transport_t *transport)
   while (sasl->desired_state > sasl->last_state) {
     switch (desired_state) {
     case SASL_POSTED_INIT:
-      pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[sz]", SASL_INIT, sasl->selected_mechanism,
-                    out.size, out.start);
+      pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[szS]", SASL_INIT, sasl->selected_mechanism,
+                    out.size, out.start, sasl->local_fqdn);
       pni_emit(transport);
       break;
     case SASL_POSTED_MECHANISMS: {
@@ -699,6 +699,7 @@ pn_sasl_t *pn_sasl(pn_transport_t *transport)
     sasl->username = NULL;
     sasl->password = NULL;
     sasl->remote_fqdn = NULL;
+    sasl->local_fqdn = NULL;
     sasl->external_auth = NULL;
     sasl->external_ssf = 0;
     sasl->outcome = PN_SASL_NONE;
@@ -726,6 +727,7 @@ void pn_sasl_free(pn_transport_t *transport)
       free(sasl->included_mechanisms);
       free(sasl->password);
       free(sasl->external_auth);
+      free(sasl->local_fqdn);
 
       if (sasl->impl_context) {
         pni_sasl_impl_free(transport);
@@ -743,6 +745,12 @@ void pni_sasl_set_remote_hostname(pn_transport_t * transport, const char * fqdn)
   sasl->remote_fqdn = fqdn;
 }
 
+void pnx_sasl_set_local_hostname(pn_transport_t * transport, const char * fqdn)
+{
+  pni_sasl_t *sasl = transport->sasl;
+  sasl->local_fqdn = pn_strdup(fqdn);
+}
+
 void pni_sasl_set_user_password(pn_transport_t *transport, const char *user, const char *password)
 {
   pni_sasl_t *sasl = transport->sasl;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[04/50] qpid-proton git commit: PROTON-1529: Check some return values from openssl

Posted by ac...@apache.org.
PROTON-1529: Check some return values from openssl


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/31d9942e
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/31d9942e
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/31d9942e

Branch: refs/heads/go1
Commit: 31d9942eeef8564124394d16cacf6dc3046aa183
Parents: b79759d
Author: Andrew Stitcher <as...@apache.org>
Authored: Wed Jul 26 18:00:24 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 12:47:29 2017 -0400

----------------------------------------------------------------------
 proton-c/src/ssl/openssl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/31d9942e/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 0d7c40b..0b7d157 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -1330,8 +1330,8 @@ int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0, char *fingerprint, size_t finger
     const EVP_MD  *digest = EVP_get_digestbyname(digest_name);
 
     pni_ssl_t *ssl = get_ssl_internal(ssl0);
-
     X509 *cert = get_peer_certificate(ssl);
+    if (!cert) return PN_ERR;
 
     if(cert) {
         unsigned int len;
@@ -1392,6 +1392,7 @@ const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subje
 
     pni_ssl_t *ssl = get_ssl_internal(ssl0);
     X509 *cert = get_peer_certificate(ssl);
+    if (!cert) return NULL;
 
     X509_NAME *subject_name = X509_get_subject_name(cert);
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[14/50] qpid-proton git commit: PROTON-1506: Expose max frame size in the python binding; thanks to Gordon Sim for the patch

Posted by ac...@apache.org.
PROTON-1506: Expose max frame size in the python binding; thanks to Gordon Sim for the patch


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/9eaca615
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/9eaca615
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/9eaca615

Branch: refs/heads/go1
Commit: 9eaca615c5f5aa97d89d1b87471d81bff7237df0
Parents: 4d25d88
Author: Justin Ross <jr...@apache.org>
Authored: Thu Aug 10 05:27:43 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 10 05:27:43 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/python/proton/reactor.py | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9eaca615/proton-c/bindings/python/proton/reactor.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py
index 4beede0..7b7c701 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -543,6 +543,7 @@ class Connector(Handler):
         self.password = None
         self.virtual_host = None
         self.ssl_sni = None
+        self.max_frame_size = None
 
     def _connect(self, connection, reactor):
         assert(reactor is not None)
@@ -575,6 +576,8 @@ class Connector(Handler):
                 raise SSLUnavailable("amqps: SSL libraries not found")
             self.ssl = SSL(transport, self.ssl_domain)
             self.ssl.peer_hostname = self.ssl_sni or self.virtual_host or url.host
+        if self.max_frame_size:
+            transport.max_frame_size = self.max_frame_size
 
     def on_connection_local_open(self, event):
         self._connect(event.connection, event.reactor)
@@ -735,6 +738,7 @@ class Container(Reactor):
             # only set hostname if virtual-host is a non-empty string
             conn.hostname = connector.virtual_host
         connector.ssl_sni = kwargs.get('sni')
+        connector.max_frame_size = kwargs.get('max_frame_size')
 
         conn._overrides = connector
         if url: connector.address = Urls([url])


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[03/50] qpid-proton git commit: PROTON-1394: Python client resource cleanup, circular references and underlying C objects

Posted by ac...@apache.org.
PROTON-1394: Python client resource cleanup, circular references and underlying C objects


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b79759d6
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b79759d6
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b79759d6

Branch: refs/heads/go1
Commit: b79759d6dbd2f542086bb6bcb3c94806ed818b5a
Parents: b17671e
Author: Clifford Jansen <cl...@apache.org>
Authored: Fri Jul 28 16:44:18 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Fri Jul 28 16:44:18 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/python/proton/__init__.py |  9 ++++---
 proton-c/bindings/python/proton/handlers.py |  8 +++---
 proton-c/bindings/python/proton/reactor.py  | 31 +++++++++++++++++-------
 proton-c/bindings/python/proton/utils.py    | 21 ++++++++++------
 4 files changed, 45 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b79759d6/proton-c/bindings/python/proton/__init__.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py
index 2b354df..dca600b 100644
--- a/proton-c/bindings/python/proton/__init__.py
+++ b/proton-c/bindings/python/proton/__init__.py
@@ -2324,7 +2324,7 @@ class Endpoint(object):
     from . import reactor
     ractor = reactor.Reactor.wrap(pn_object_reactor(self._impl))
     if ractor:
-      on_error = ractor.on_error
+      on_error = ractor.on_error_delegate()
     else:
       on_error = None
     record = self._get_attachments()
@@ -2334,7 +2334,7 @@ class Endpoint(object):
     from . import reactor
     ractor = reactor.Reactor.wrap(pn_object_reactor(self._impl))
     if ractor:
-      on_error = ractor.on_error
+      on_error = ractor.on_error_delegate()
     else:
       on_error = None
     impl = _chandler(handler, on_error)
@@ -4110,9 +4110,10 @@ class WrappedHandler(Wrapper):
     else:
       on_error(info)
 
-  def add(self, handler):
+  def add(self, handler, on_error=None):
     if handler is None: return
-    impl = _chandler(handler, self._on_error)
+    if on_error is None: on_error = self._on_error
+    impl = _chandler(handler, on_error)
     pn_handler_add(self._impl, impl)
     pn_decref(impl)
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b79759d6/proton-c/bindings/python/proton/handlers.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/handlers.py b/proton-c/bindings/python/proton/handlers.py
index 6d580b7..6d3cce5 100644
--- a/proton-c/bindings/python/proton/handlers.py
+++ b/proton-c/bindings/python/proton/handlers.py
@@ -16,7 +16,7 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-import heapq, logging, os, re, socket, time, types
+import heapq, logging, os, re, socket, time, types, weakref
 
 from proton import dispatch, generate_uuid, PN_ACCEPTED, SASL, symbol, ulong, Url
 from proton import Collector, Connection, Delivery, Described, Endpoint, Event, Link, Terminus, Timeout
@@ -390,9 +390,9 @@ class MessagingHandler(Handler, Acking):
         self.handlers = []
         if prefetch:
             self.handlers.append(CFlowController(prefetch))
-        self.handlers.append(EndpointStateHandler(peer_close_is_error, self))
-        self.handlers.append(IncomingMessageHandler(auto_accept, self))
-        self.handlers.append(OutgoingMessageHandler(auto_settle, self))
+        self.handlers.append(EndpointStateHandler(peer_close_is_error, weakref.proxy(self)))
+        self.handlers.append(IncomingMessageHandler(auto_accept, weakref.proxy(self)))
+        self.handlers.append(OutgoingMessageHandler(auto_settle, weakref.proxy(self)))
         self.fatal_conditions = ["amqp:unauthorized-access"]
 
     def on_transport_error(self, event):

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b79759d6/proton-c/bindings/python/proton/reactor.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py
index bffeea1..5f6d8cb 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -84,20 +84,33 @@ class Reactor(Wrapper):
     def __init__(self, *handlers, **kwargs):
         Wrapper.__init__(self, kwargs.get("impl", pn_reactor), pn_reactor_attachments)
         for h in handlers:
-            self.handler.add(h)
+            self.handler.add(h, on_error=self.on_error_delegate())
 
     def _init(self):
         self.errors = []
 
+    # on_error relay handler tied to underlying C reactor.  Use when the
+    # error will always be generated from a callback from this reactor.
+    # Needed to prevent reference cycles and be compatible with wrappers.
+    class ErrorDelegate(object):
+      def __init__(self, reactor):
+        self.reactor_impl = reactor._impl
+      def on_error(self, info):
+        ractor = Reactor.wrap(self.reactor_impl)
+        ractor.on_error(info)
+
+    def on_error_delegate(self):
+        return Reactor.ErrorDelegate(self).on_error
+
     def on_error(self, info):
         self.errors.append(info)
         self.yield_()
 
     def _get_global(self):
-        return WrappedHandler.wrap(pn_reactor_get_global_handler(self._impl), self.on_error)
+        return WrappedHandler.wrap(pn_reactor_get_global_handler(self._impl), self.on_error_delegate())
 
     def _set_global(self, handler):
-        impl = _chandler(handler, self.on_error)
+        impl = _chandler(handler, self.on_error_delegate())
         pn_reactor_set_global_handler(self._impl, impl)
         pn_decref(impl)
 
@@ -118,10 +131,10 @@ class Reactor(Wrapper):
         return pn_reactor_mark(self._impl)
 
     def _get_handler(self):
-        return WrappedHandler.wrap(pn_reactor_get_handler(self._impl), self.on_error)
+        return WrappedHandler.wrap(pn_reactor_get_handler(self._impl), self.on_error_delegate())
 
     def _set_handler(self, handler):
-        impl = _chandler(handler, self.on_error)
+        impl = _chandler(handler, self.on_error_delegate())
         pn_reactor_set_handler(self._impl, impl)
         pn_decref(impl)
 
@@ -164,13 +177,13 @@ class Reactor(Wrapper):
         self._check_errors()
 
     def schedule(self, delay, task):
-        impl = _chandler(task, self.on_error)
+        impl = _chandler(task, self.on_error_delegate())
         task = Task.wrap(pn_reactor_schedule(self._impl, secs2millis(delay), impl))
         pn_decref(impl)
         return task
 
     def acceptor(self, host, port, handler=None):
-        impl = _chandler(handler, self.on_error)
+        impl = _chandler(handler, self.on_error_delegate())
         aimpl = pn_reactor_acceptor(self._impl, unicode2utf8(host), str(port), impl)
         pn_decref(impl)
         if aimpl:
@@ -181,7 +194,7 @@ class Reactor(Wrapper):
     def connection(self, handler=None):
         """Deprecated: use connection_to_host() instead
         """
-        impl = _chandler(handler, self.on_error)
+        impl = _chandler(handler, self.on_error_delegate())
         result = Connection.wrap(pn_reactor_connection(self._impl, impl))
         if impl: pn_decref(impl)
         return result
@@ -215,7 +228,7 @@ class Reactor(Wrapper):
         return utf82unicode(_url)
 
     def selectable(self, handler=None):
-        impl = _chandler(handler, self.on_error)
+        impl = _chandler(handler, self.on_error_delegate())
         result = Selectable.wrap(pn_reactor_selectable(self._impl))
         if impl:
             record = pn_selectable_attachments(result._impl)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b79759d6/proton-c/bindings/python/proton/utils.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/utils.py b/proton-c/bindings/python/proton/utils.py
index 05ef80d..d0679ae 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -137,10 +137,10 @@ class BlockingReceiver(BlockingLink):
     def __del__(self):
         self.fetcher = None
         # The next line causes a core dump if the Proton-C reactor finalizes
-        # first.  The self.container reference prevents reactor finalization
-        # until after it is set to None.
-        self.link.handler = None
-        self.container = None
+        # first.  The self.container reference prevents out of order reactor
+        # finalization. It may not be set if exception in BlockingLink.__init__
+        if hasattr(self, "container"):
+            self.link.handler = None  # implicit call to reactor
 
     def receive(self, timeout=False):
         if not self.fetcher:
@@ -208,9 +208,16 @@ class BlockingConnection(Handler):
         self.container.timeout = self.timeout
         self.container.start()
         self.url = Url(url).defaults()
-        self.conn = self.container.connect(url=self.url, handler=self, ssl_domain=ssl_domain, reconnect=False, heartbeat=heartbeat, **kwargs)
-        self.wait(lambda: not (self.conn.state & Endpoint.REMOTE_UNINIT),
-                  msg="Opening connection")
+        self.conn = None
+        failed = True
+        try:
+            self.conn = self.container.connect(url=self.url, handler=self, ssl_domain=ssl_domain, reconnect=False, heartbeat=heartbeat, **kwargs)
+            self.wait(lambda: not (self.conn.state & Endpoint.REMOTE_UNINIT),
+                      msg="Opening connection")
+            failed = False
+        finally:
+            if failed and self.conn:
+                self.close()
 
     def create_sender(self, address, handler=None, name=None, options=None):
         return BlockingSender(self, self.container.create_sender(self.conn, address, name=name, handler=handler, options=options))


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[08/50] qpid-proton git commit: PROTON-1381, PROTON-1326: Modify openssl DH code to work with openssl 1.1 Modified patch from Volker Diels-Grabsch

Posted by ac...@apache.org.
PROTON-1381, PROTON-1326: Modify openssl DH code to work with openssl 1.1
Modified patch from Volker Diels-Grabsch


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/bc872440
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/bc872440
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/bc872440

Branch: refs/heads/go1
Commit: bc872440428073e86ce2631276dc8b7f62da4c33
Parents: 31d9942
Author: Andrew Stitcher <as...@apache.org>
Authored: Tue Jan 17 02:10:48 2017 -0500
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 12:47:44 2017 -0400

----------------------------------------------------------------------
 proton-c/src/ssl/openssl.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc872440/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 0b7d157..0c51c03 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -356,12 +356,22 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
   return preverify_ok;
 }
 
+// This was introduced in v1.1
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+  dh->p = p;
+  dh->q = q;
+  dh->g = g;
+  return 1;
+}
+#endif
 
 // this code was generated using the command:
 // "openssl dhparam -C -2 2048"
 static DH *get_dh2048(void)
 {
-  static const unsigned char dh2048_p[]={
+  static const unsigned char dhp_2048[]={
     0xAE,0xF7,0xE9,0x66,0x26,0x7A,0xAC,0x0A,0x6F,0x1E,0xCD,0x81,
     0xBD,0x0A,0x10,0x7E,0xFA,0x2C,0xF5,0x2D,0x98,0xD4,0xE7,0xD9,
     0xE4,0x04,0x8B,0x06,0x85,0xF2,0x0B,0xA3,0x90,0x15,0x56,0x0C,
@@ -385,17 +395,24 @@ static DH *get_dh2048(void)
     0xA4,0xED,0xFD,0x49,0x0B,0xE3,0x4A,0xF6,0x28,0xB3,0x98,0xB0,
     0x23,0x1C,0x09,0x33,
   };
-  static const unsigned char dh2048_g[]={
+  static const unsigned char dhg_2048[]={
     0x02,
   };
-  DH *dh;
-
-  if ((dh=DH_new()) == NULL) return(NULL);
-  dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
-  dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
-  if ((dh->p == NULL) || (dh->g == NULL))
-    { DH_free(dh); return(NULL); }
-  return(dh);
+  DH *dh = DH_new();
+  BIGNUM *dhp_bn, *dhg_bn;
+
+  if (dh == NULL)
+    return NULL;
+  dhp_bn = BN_bin2bn(dhp_2048, sizeof (dhp_2048), NULL);
+  dhg_bn = BN_bin2bn(dhg_2048, sizeof (dhg_2048), NULL);
+  if (dhp_bn == NULL || dhg_bn == NULL
+      || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
+    DH_free(dh);
+    BN_free(dhp_bn);
+    BN_free(dhg_bn);
+    return NULL;
+  }
+  return dh;
 }
 
 typedef struct {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[46/50] qpid-proton git commit: NO-JIRA: go fix CMakeLists.txt for older cmake versions

Posted by ac...@apache.org.
NO-JIRA: go fix CMakeLists.txt for older cmake versions

DEPENDS not allowed in add_test


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ab8ae87a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ab8ae87a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ab8ae87a

Branch: refs/heads/go1
Commit: ab8ae87ad37833e3a88a9dc00ba5d1027e20d011
Parents: 740b950
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Aug 31 16:05:13 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Aug 31 16:05:13 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/go/CMakeLists.txt | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ab8ae87a/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index d29ac06..9c44a5a 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -57,13 +57,12 @@ set(GO_TEST ${GO} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACH
 # CMake so just run them every time, they do nothing if nothing needs to be
 # done.
 add_custom_target(go-build ALL
-  COMMAND ${GO_INSTALL} qpid.apache.org/...
+  COMMAND ${GO_INSTALL} qpid.aspache.org/...
   DEPENDS qpid-proton-core
   WORKING_DIRECTORY $ENV{PWD})
 
 add_test(
   NAME go-test COMMAND ${GO_TEST} qpid.apache.org/...
-  DEPENDS qpid-proton-core
   WORKING_DIRECTORY $ENV{PWD})
 
 # Make available to examples/go/CMakeLists


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[26/50] qpid-proton git commit: PROTON-209: Add a list of dependencies with tested minimum versions where they are known

Posted by ac...@apache.org.
PROTON-209: Add a list of dependencies with tested minimum versions where they are known


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/8c3ba56b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/8c3ba56b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/8c3ba56b

Branch: refs/heads/go1
Commit: 8c3ba56b8e7dfe92fb23c409cb64e960dacae26a
Parents: 20da10d
Author: Justin Ross <jr...@apache.org>
Authored: Thu Aug 17 16:38:39 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 17 16:38:39 2017 -0700

----------------------------------------------------------------------
 INSTALL.md | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8c3ba56b/INSTALL.md
----------------------------------------------------------------------
diff --git a/INSTALL.md b/INSTALL.md
index 83d1270..6a212c0 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -4,6 +4,27 @@ Installing Qpid Proton
 The CMake build system can build the entire codebase, including proton-c,
 and all its language bindings.
 
+Dependencies
+------------
+
+Cross-platform dependencies
+
+  - CMake 2.8.7+
+  - Swig 1.3+ (for the bindings)
+  - Python 2.6+ or 3 (for the Python binding)
+  - Ruby (for the Ruby binding)
+
+Linux dependencies
+
+  - GNU Make 3.81+
+  - GCC 4.4+
+  - Cyrus SASL 2.1+ (for SASL support)
+  - OpenSSL 1.0+ (for SSL support)
+
+Windows dependencies
+
+  - Visual Studio 2005 or newer (regular or C++ Express)
+
 CMake (Linux)
 -------------
 
@@ -26,7 +47,7 @@ language.
     $ yum install python-devel                               # Python
     $ yum install ruby-devel rubygem-rspec rubygem-simplecov # Ruby
     $ yum install rubygem-test-unit                          # Ruby on Fedora >= 25
-    $ yum install pphp-devel                                 # PHP
+    $ yum install php-devel                                  # PHP
     $ yum install perl-devel                                 # Perl
 
     # Dependencies needed for Python docs
@@ -89,7 +110,7 @@ The following packages must be installed:
 
 Additional packages are required for the language bindings:
 
-  - swig (www.swig.org)
+  - Swig (www.swig.org)
   - Development headers and libraries for the language of choice
 
 Notes:


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[47/50] qpid-proton git commit: PROTON-1568: c++ enable race detection for self-tests

Posted by ac...@apache.org.
PROTON-1568: c++ enable race detection for self-tests

- update proctest.py to enable `valgrind --tool=helgrind` tests
- enable helgrind for C++ multithreaded_client* tests
- set valgrind options for max speed, run separately for more debugging info
- fix race in proactor/epoll.c shown by helgrind
- clarify lock scopes in proactor_container_impl.cpp


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/17d2a6f4
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/17d2a6f4
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/17d2a6f4

Branch: refs/heads/go1
Commit: 17d2a6f48898a20020d2509e63e9736a946d6b96
Parents: ab8ae87
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Aug 29 18:07:03 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Aug 31 16:13:34 2017 -0400

----------------------------------------------------------------------
 examples/cpp/example_test.py                    | 67 +++++++++---------
 .../cpp/src/proactor_container_impl.cpp         | 27 ++++++--
 proton-c/src/proactor/epoll.c                   | 51 +++++++++++---
 proton-c/src/tests/fdlimit.py                   |  2 +-
 tests/perf/quick_perf.py                        |  5 +-
 tools/py/proctest.py                            | 72 ++++++++++++++------
 6 files changed, 147 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index 98f1d90..248e596 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -22,7 +22,7 @@
 import unittest
 import os, sys, socket, time, re, inspect
 from proctest import *
-from  random import randrange
+from random import randrange
 from subprocess import Popen, PIPE, STDOUT, call
 from copy import copy
 import platform
@@ -32,25 +32,11 @@ from string import Template
 
 createdSASLDb = False
 
-def findfileinpath(filename, searchpath):
-    """Find filename in the searchpath
-        return absolute path to the file or None
-    """
-    paths = searchpath.split(os.pathsep)
-    for path in paths:
-        if os.path.exists(os.path.join(path, filename)):
-            return os.path.abspath(os.path.join(path, filename))
-    return None
-
 def _cyrusSetup(conf_dir):
-  """Write out simple SASL config.
+  """Write out simple SASL config.tests
   """
-  saslpasswd = ""
-  if 'SASLPASSWD' in os.environ:
-    saslpasswd = os.environ['SASLPASSWD']
-  else:
-    saslpasswd = findfileinpath('saslpasswd2', os.getenv('PATH')) or ""
-  if os.path.exists(saslpasswd):
+  saslpasswd = os.getenv('SASLPASSWD') or find_file('saslpasswd2', os.getenv('PATH'))
+  if saslpasswd:
     t = Template("""sasldb_path: ${db}
 mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS
 """)
@@ -87,7 +73,6 @@ class BrokerTestCase(ProcTestCase):
     ExampleTest that starts a broker in setUpClass and kills it in tearDownClass.
     Subclasses must set `broker_exe` class variable with the name of the broker executable.
     """
-
     @classmethod
     def setUpClass(cls):
         cls.broker = None       # In case Proc throws, create the attribute.
@@ -147,7 +132,8 @@ class ContainerExampleTest(BrokerTestCase):
     def test_simple_send_direct_recv(self):
         with TestPort() as tp:
             addr = "%s/examples" % tp.addr
-            recv = self.proc(["direct_recv", "-a", addr], "listening")
+            recv = self.proc(["direct_recv", "-a", addr])
+            recv.wait_re("listening")
             self.assertMultiLineEqual("all messages confirmed\n",
                              self.proc(["simple_send", "-a", addr]).wait_exit())
             self.assertMultiLineEqual(recv_expect("direct_recv", addr), recv.wait_exit())
@@ -155,7 +141,8 @@ class ContainerExampleTest(BrokerTestCase):
     def test_simple_recv_direct_send(self):
         with TestPort() as tp:
             addr = "%s/examples" % tp.addr
-            send = self.proc(["direct_send", "-a", addr], "listening")
+            send = self.proc(["direct_send", "-a", addr])
+            send.wait_re("listening")
             self.assertMultiLineEqual(recv_expect("simple_recv", addr),
                              self.proc(["simple_recv", "-a", addr]).wait_exit())
             self.assertMultiLineEqual(
@@ -163,14 +150,16 @@ class ContainerExampleTest(BrokerTestCase):
                 send.wait_exit())
 
     def test_request_response(self):
-        server = self.proc(["server", "-a", self.addr], "connected")
+        server = self.proc(["server", "-a", self.addr])
+        server.wait_re("connected")
         self.assertMultiLineEqual(CLIENT_EXPECT,
                          self.proc(["client", "-a", self.addr]).wait_exit())
 
     def test_request_response_direct(self):
         with TestPort() as tp:
             addr = "%s/examples" % tp.addr
-            server = self.proc(["server_direct", "-a", addr], "listening")
+            server = self.proc(["server_direct", "-a", addr])
+            server.wait_re("listening")
             self.assertMultiLineEqual(CLIENT_EXPECT,
                              self.proc(["client", "-a", addr]).wait_exit())
 
@@ -216,13 +205,11 @@ map{string(k1):int(42), symbol(k2):boolean(0)}
         self.assertTrue(len(out) > 0);
         self.assertEqual(["send"]*len(out), out)
 
+    @unittest.skipUnless(find_exes('scheduled_send'), "not a  C++11 build")
     def test_scheduled_send(self):
-        try:
-            out = self.proc(["scheduled_send", "-a", self.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).wait_exit().split()
-            self.assertTrue(len(out) > 0);
-            self.assertEqual(["send"]*len(out), out)
-        except ProcError:       # File not found, not a C++11 build.
-            pass
+        out = self.proc(["scheduled_send", "-a", self.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).wait_exit().split()
+        self.assertTrue(len(out) > 0);
+        self.assertEqual(["send"]*len(out), out)
 
     def test_message_properties(self):
         expect="""using put/get: short=123 string=foo symbol=sym
@@ -236,20 +223,28 @@ expected conversion_error: "unexpected type, want: uint got: string"
 """
         self.assertMultiLineEqual(expect, self.proc(["message_properties"]).wait_exit())
 
+    @unittest.skipUnless(find_exes('multithreaded_client'), "not a  C++11 build")
+    def test_multithreaded_client(self):
+        got = self.proc(["multithreaded_client", self.addr, "examples", "10"], helgrind=True).wait_exit()
+        self.maxDiff = None
+        self.assertRegexpMatches(got, "10 messages sent and received");
 
+    @unittest.skipUnless(find_exes('multithreaded_client_flow_control'), "not a  C++11 build")
+    def test_multithreaded_client_flow_control(self):
+        got = self.proc(["multithreaded_client_flow_control", self.addr, "examples", "10", "2"], helgrind=True).wait_exit()
+        self.maxDiff = None
+        self.assertRegexpMatches(got, "20 messages sent and received");
 
 class ContainerExampleSSLTest(BrokerTestCase):
     """Run the SSL container examples, verify they behave as expected."""
 
     broker_exe = "broker"
+    valgrind = False            # Disable for all tests, including inherited
 
     def setUp(self):
         super(ContainerExampleSSLTest, self).setUp()
-        self.vg_args = Proc.vg_args
-        Proc.vg_args = []       # Disable
 
     def tearDown(self):
-        Proc.vg_args = self.vg_args
         super(ContainerExampleSSLTest, self).tearDown()
 
     def ssl_certs_dir(self):
@@ -262,7 +257,7 @@ class ContainerExampleSSLTest(BrokerTestCase):
         with TestPort() as tp:
             addr = "amqps://%s/examples" % tp.addr
             # Disable valgrind when using OpenSSL
-            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir()], skip_valgrind=True).wait_exit()
+            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir()]).wait_exit()
             expect = "Outgoing client connection connected via SSL.  Server certificate identity CN=test_server\nHello World!"
             expect_found = (out.find(expect) >= 0)
             self.assertEqual(expect_found, True)
@@ -272,7 +267,7 @@ class ContainerExampleSSLTest(BrokerTestCase):
         with TestPort() as tp:
             addr = "amqps://%s/examples" % tp.addr
             # Disable valgrind when using OpenSSL
-            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "noname"], skip_valgrind=True).wait_exit()
+            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "noname"], valgrind=False).wait_exit()
             expect = "Outgoing client connection connected via SSL.  Server certificate identity CN=test_server\nHello World!"
             expect_found = (out.find(expect) >= 0)
             self.assertEqual(expect_found, True)
@@ -282,7 +277,7 @@ class ContainerExampleSSLTest(BrokerTestCase):
         with TestPort() as tp:
             addr = "amqps://%s/examples" % tp.addr
             # Disable valgrind when using OpenSSL
-            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "fail"], skip_valgrind=True).wait_exit()
+            out = self.proc(["ssl", "-a", addr, "-c", self.ssl_certs_dir(), "-v", "fail"]).wait_exit()
             expect = "Expected failure of connection with wrong peer name"
             expect_found = (out.find(expect) >= 0)
             self.assertEqual(expect_found, True)
@@ -296,7 +291,7 @@ Hello World!
         with TestPort() as tp:
             addr = "amqps://%s/examples" % tp.addr
             # Disable valgrind when using OpenSSL
-            out = self.proc(["ssl_client_cert", addr, self.ssl_certs_dir()], skip_valgrind=True).wait_exit()
+            out = self.proc(["ssl_client_cert", addr, self.ssl_certs_dir()]).wait_exit()
             expect_found = (out.find(expect) >= 0)
             self.assertEqual(expect_found, True)
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index ff4d4bb..7f5edfe 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -187,6 +187,16 @@ pn_connection_t* container::impl::make_connection_lh(
     return pnc;                 // 1 refcount from pn_connection()
 }
 
+// Takes ownership of pnc
+//
+// NOTE: After the call to start_connecton() pnc is active in a proactor thread,
+// and may even have been freed already. It is undefined to use pnc (or any
+// object belonging to it) except in appropriate handlers.
+//
+// SUBTLE NOTE: There must not be any proton::object wrappers in scope when
+// start_connecton() is called. The wrapper destructor will call pn_decref()
+// after start_connecton() which is undefined!
+//
 void container::impl::start_connection(const url& url, pn_connection_t *pnc) {
     char caddr[PN_MAX_ADDR];
     pn_proactor_addr(caddr, sizeof(caddr), url.host().c_str(), url.port().c_str());
@@ -261,10 +271,13 @@ returned<connection> container::impl::connect(
     const std::string& addr,
     const proton::connection_options& user_opts)
 {
-    GUARD(lock_);
     proton::url url(addr);
-    pn_connection_t *pnc = make_connection_lh(url, user_opts);
-    start_connection(url, pnc);
+    pn_connection_t* pnc = 0;
+    {
+        GUARD(lock_);
+        pnc = make_connection_lh(url, user_opts);
+    }
+    start_connection(url, pnc); // See comment on start_connection
     return make_returned<proton::connection>(pnc);
 }
 
@@ -280,8 +293,8 @@ returned<sender> container::impl::open_sender(const std::string &urlstr, const p
         pnc = make_connection_lh(url, o2);
         connection conn(make_wrapper(pnc));
         pnl = unwrap(conn.default_session().open_sender(url.path(), lopts));
-    }                                   // There must be no refcounting after here
-    start_connection(url, pnc);         // Takes ownership of pnc
+    }
+    start_connection(url, pnc); // See comment on start_connection
     return make_returned<sender>(pnl);  // Unsafe returned pointer
 }
 
@@ -296,8 +309,8 @@ returned<receiver> container::impl::open_receiver(const std::string &urlstr, con
         pnc = make_connection_lh(url, o2);
         connection conn(make_wrapper(pnc));
         pnl = unwrap(conn.default_session().open_receiver(url.path(), lopts));
-    }                                   // There must be no refcounting after here
-    start_connection(url, pnc);
+    }
+    start_connection(url, pnc); // See comment on start_connection
     return make_returned<receiver>(pnl);
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 89cad31..46effcc 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -121,6 +121,11 @@ typedef enum {
 
 // Data to use with epoll.
 typedef struct epoll_extended_t {
+  /* epoll_ctl()/epoll_wake() do not form a memory barrier, so cached memory
+     writes to struct epoll_extended_t in the EPOLL_ADD thread might not be
+     visible to epoll_wait() thread. Lock use of epoll_extended_t to be safe.
+  */
+  pmutex mutex;
   struct psocket_t *psocket;  // pconnection, listener, or NULL -> proactor
   int fd;
   epoll_type_t type;   // io/timer/wakeup
@@ -277,24 +282,33 @@ PN_STRUCT_CLASSDEF(pn_listener, CID_pn_listener)
 static bool start_polling(epoll_extended_t *ee, int epollfd) {
   if (ee->polling)
     return false;
+  pmutex_init(&ee->mutex);
+  lock(&ee->mutex);
   ee->polling = true;
   struct epoll_event ev;
   ev.data.ptr = ee;
   ev.events = ee->wanted | EPOLLONESHOT;
-  return (epoll_ctl(epollfd, EPOLL_CTL_ADD, ee->fd, &ev) == 0);
+  int fd = ee->fd;
+  unlock(&ee->mutex);
+  return (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == 0);
 }
 
 static void stop_polling(epoll_extended_t *ee, int epollfd) {
   // TODO: check for error, return bool or just log?
+  lock(&ee->mutex);
   if (ee->fd == -1 || !ee->polling || epollfd == -1)
     return;
   struct epoll_event ev;
   ev.data.ptr = ee;
   ev.events = 0;
+  unlock(&ee->mutex);
   if (epoll_ctl(epollfd, EPOLL_CTL_DEL, ee->fd, &ev) == -1)
     EPOLL_FATAL("EPOLL_CTL_DEL", errno);
+  lock(&ee->mutex);
   ee->fd = -1;
   ee->polling = false;
+  unlock(&ee->mutex);
+  pmutex_finalize(&ee->mutex);
 }
 
 /*
@@ -628,8 +642,11 @@ static void psocket_gai_error(psocket_t *ps, int gai_err, const char* what) {
 static void rearm(pn_proactor_t *p, epoll_extended_t *ee) {
   struct epoll_event ev;
   ev.data.ptr = ee;
+  lock(&ee->mutex);
   ev.events = ee->wanted | EPOLLONESHOT;
-  if (epoll_ctl(p->epollfd, EPOLL_CTL_MOD, ee->fd, &ev) == -1)
+  int fd = ee->fd;
+  unlock(&ee->mutex);
+  if (epoll_ctl(p->epollfd, EPOLL_CTL_MOD, fd, &ev) == -1)
     EPOLL_FATAL("arming polled file descriptor", errno);
 }
 
@@ -1168,9 +1185,11 @@ static void pconnection_start(pconnection_t *pc) {
 
   start_polling(&pc->timer.epoll_io, efd);  // TODO: check for error
   epoll_extended_t *ee = &pc->psocket.epoll_io;
+  lock(&ee->mutex);
   ee->fd = pc->psocket.sockfd;
   ee->wanted = EPOLLIN | EPOLLOUT;
   ee->polling = false;
+  unlock(&ee->mutex);
   start_polling(ee, efd);  // TODO: check for error
 }
 
@@ -1237,8 +1256,6 @@ void pn_proactor_connect(pn_proactor_t *p, pn_connection_t *c, const char *addr)
 
   lock(&pc->context.mutex);
   proactor_add(&pc->context);
-  pn_connection_open(pc->driver.connection); /* Auto-open */
-
   bool notify = false;
   bool notify_proactor = false;
 
@@ -1604,11 +1621,14 @@ void pn_listener_accept(pn_listener_t *l, pn_connection_t *c) {
 
 /* Set up an epoll_extended_t to be used for wakeup or interrupts */
 static void epoll_wake_init(epoll_extended_t *ee, int eventfd, int epollfd) {
+  pmutex_init(&ee->mutex);
+  lock(&ee->mutex);
   ee->psocket = NULL;
   ee->fd = eventfd;
   ee->type = WAKE;
   ee->wanted = EPOLLIN;
   ee->polling = false;
+  unlock(&ee->mutex);
   start_polling(ee, epollfd);  // TODO: check for error
 }
 
@@ -1620,6 +1640,7 @@ pn_proactor_t *pn_proactor() {
   pmutex_init(&p->eventfd_mutex);
   pmutex_init(&p->bind_mutex);
   ptimer_init(&p->timer, 0);
+  pmutex_init(&p->overflow_mutex);
 
   if ((p->epollfd = epoll_create(1)) >= 0) {
     if ((p->eventfd = eventfd(0, EFD_NONBLOCK)) >= 0) {
@@ -1801,7 +1822,11 @@ static bool proactor_remove(pcontext_t *ctx) {
 }
 
 static pn_event_batch_t *process_inbound_wake(pn_proactor_t *p, epoll_extended_t *ee) {
-  if  (ee->fd == p->interruptfd) {        /* Interrupts have their own dedicated eventfd */
+  lock(&ee->mutex);
+  int fd = ee->fd;
+  unlock(&ee->mutex);
+
+  if  (fd == p->interruptfd) {        /* Interrupts have their own dedicated eventfd */
     (void)read_uint64(p->interruptfd);
     rearm(p, &p->epoll_interrupt);
     return proactor_process(p, PN_PROACTOR_INTERRUPT);
@@ -1847,23 +1872,27 @@ static pn_event_batch_t *proactor_do_epoll(struct pn_proactor_t* p, bool can_blo
     assert(n == 1);
     epoll_extended_t *ee = (epoll_extended_t *) ev.data.ptr;
 
-    if (ee->type == WAKE) {
+    lock(&ee->mutex);
+    epoll_type_t type = ee->type;
+    psocket_t* psocket = ee->psocket;
+    unlock(&ee->mutex);
+    if (type == WAKE) {
       batch = process_inbound_wake(p, ee);
-    } else if (ee->type == PROACTOR_TIMER) {
+    } else if (type == PROACTOR_TIMER) {
       batch = proactor_process(p, PN_PROACTOR_TIMEOUT);
     } else {
-      pconnection_t *pc = psocket_pconnection(ee->psocket);
+      pconnection_t *pc = psocket_pconnection(psocket);
       if (pc) {
-        if (ee->type == PCONNECTION_IO) {
+        if (type == PCONNECTION_IO) {
           batch = pconnection_process(pc, ev.events, false, false);
         } else {
-          assert(ee->type == PCONNECTION_TIMER);
+          assert(type == PCONNECTION_TIMER);
           batch = pconnection_process(pc, 0, true, false);
         }
       }
       else {
         // TODO: can any of the listener processing be parallelized like IOCP?
-        batch = listener_process(ee->psocket, ev.events);
+        batch = listener_process(psocket, ev.events);
       }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/proton-c/src/tests/fdlimit.py
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/fdlimit.py b/proton-c/src/tests/fdlimit.py
index a31fa09..4f4a342 100644
--- a/proton-c/src/tests/fdlimit.py
+++ b/proton-c/src/tests/fdlimit.py
@@ -55,7 +55,7 @@ class FdLimitTest(ProcTestCase):
 
     def proc(self, *args, **kwargs):
         """Skip valgrind for all processes started by this test"""
-        return super(FdLimitTest, self).proc(*args, skip_valgrind=True, **kwargs)
+        return super(FdLimitTest, self).proc(*args, valgrind=False, **kwargs)
 
     def test_fd_limit_broker(self):
         """Check behaviour when running out of file descriptors on accept"""

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/tests/perf/quick_perf.py
----------------------------------------------------------------------
diff --git a/tests/perf/quick_perf.py b/tests/perf/quick_perf.py
index 59b47a2..7af57d2 100644
--- a/tests/perf/quick_perf.py
+++ b/tests/perf/quick_perf.py
@@ -61,11 +61,10 @@ except:
 
 
 # Use Proton-C reactor-recv as a relatively fast loopback "broker" for these tests
-server = Proc(["reactor-recv", "-X", "listening", "-a", linkaddr, "-c", str(mcount), "-R"], ready="listening", 
-              skip_valgrind=True, timeout=300)
+server = Proc(["reactor-recv", "-X", "listening", "-a", linkaddr, "-c", str(mcount), "-R"], ready="listening", valgrind=False, timeout=300)
 try:
     start = time.time()
-    client = Proc(perf_target, skip_valgrind=True, timeout=300)
+    client = Proc(perf_target, valgrind=False, timeout=300)
     print client.wait_exit()
     server.wait_exit()
     end = time.time()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/17d2a6f4/tools/py/proctest.py
----------------------------------------------------------------------
diff --git a/tools/py/proctest.py b/tools/py/proctest.py
index ebd7db2..fc4450f 100644
--- a/tools/py/proctest.py
+++ b/tools/py/proctest.py
@@ -1,4 +1,4 @@
-#
+
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -58,12 +58,18 @@ class ProcError(Exception):
     """An exception that displays failed process output"""
     def __init__(self, proc, what="bad exit status"):
         self.out = proc.out.strip()
+        returncode = getattr(proc, 'returncode') # Can be missing in some cases
+        if returncode == proc.valgrind_exit:
+            self.out = \
+            "\n==NOTE== valgrind options set for speed, for more detail run command with" \
+            "\n==NOTE== e.g. --leak-check=full --history-level=full --num-callers=40" \
+            + self.out
+        msg = "%s (exit=%s) command:\n%s" % (what, returncode, " ".join(proc.args))
         if self.out:
-            msgtail = "\nvvvvvvvvvvvvvvvv\n%s\n^^^^^^^^^^^^^^^^\n" % self.out
+            msg += "\nvvvvvvvvvvvvvvvv\n%s\n^^^^^^^^^^^^^^^^" % self.out
         else:
-            msgtail = ", no output"
-        super(Exception, self, ).__init__(
-            "%s %s, code=%s%s" % (proc.args, what, getattr(proc, 'returncode', 'noreturn'), msgtail))
+            msg += "\n<<no output>>"
+        super(ProcError, self, ).__init__(msg)
 
 class NotFoundError(ProcError):
     pass
@@ -73,11 +79,7 @@ class Proc(Popen):
     'ready' pattern' Use self.out to access output (combined stdout and stderr).
     You can't set the Popen stdout and stderr arguments, they will be overwritten.
     """
-
-    if "VALGRIND" in os.environ and os.environ["VALGRIND"]:
-        vg_args = [os.environ["VALGRIND"], "--error-exitcode=42", "--quiet", "--leak-check=full"]
-    else:
-        vg_args = []
+    valgrind_exit = 42          # Special exit code for valgrind errors
 
     @property
     def out(self):
@@ -85,18 +87,23 @@ class Proc(Popen):
         # Normalize line endings, os.tmpfile() opens in binary mode.
         return self._out.read().replace('\r\n','\n').replace('\r','\n')
 
-    def __init__(self, args, skip_valgrind=False, **kwargs):
+    def __init__(self, args, valgrind=True, helgrind=False, **kwargs):
         """Start an example process"""
-        args = list(args)
-        if skip_valgrind:
-            self.args = args
-        else:
-            self.args = self.vg_args + args
+        self.args = list(args)
         self.kwargs = kwargs
         self._out = tempfile.TemporaryFile()
+        valgrind_exe = valgrind and os.getenv("VALGRIND")
+        if valgrind_exe:
+            # run valgrind for speed, not for detailed information
+            vg = [valgrind_exe, "--quiet", "--num-callers=2",
+                  "--error-exitcode=%s" % self.valgrind_exit]
+            if helgrind:
+                vg += ["--tool=helgrind", "--history-level=none"]
+            else:
+                vg += ["--tool=memcheck", "--leak-check=full",  "--leak-resolution=low"]
+            self.args = vg + self.args
+            self._out.flush()
         try:
-            if (os.getenv("PROCTEST_VERBOSE")):
-                sys.stderr.write("\nstart proc: %s\n" % self.args)
             Popen.__init__(self, self.args, stdout=self._out, stderr=STDOUT, **kwargs)
         except OSError, e:
             if e.errno == errno.ENOENT:
@@ -161,9 +168,16 @@ class ProcTestCase(unittest.TestCase):
             p.kill()
         super(ProcTestCase, self).tearDown()
 
+    # Default value for valgrind= in proc() function if not explicitly set.
+    # Override by setting a "valgrind" member in subclass or instance.
+    valgrind=True
+
     def proc(self, *args, **kwargs):
         """Return a Proc() that will be automatically killed on teardown"""
-        p = Proc(*args, **kwargs)
+        if 'valgrind' in kwargs:
+            p = Proc(*args, **kwargs)
+        else:
+            p = Proc(*args, valgrind=self.valgrind, **kwargs)
         self.procs.append(p)
         return p
 
@@ -201,6 +215,26 @@ class ProcTestCase(unittest.TestCase):
         def assertMultiLineEqual(self, a, b):
             self.assertEqual(a, b)
 
+def find_file(filename, path):
+    """
+    Find filename in path. Path is a list of directory names or OS path strings
+    separated with os.pathsep. return absolute path to the file or None
+
+    """
+    dirs = reduce((lambda x,y: x+y), (p.split(os.pathsep) for p in path))
+    for d in dirs:
+        if os.path.exists(os.path.join(d, filename)):
+            return os.path.abspath(os.path.join(d, filename))
+    return None
+
+def find_exes(*filenames):
+    """
+    True if all filenames in the list are found on the system PATH.
+    """
+    for f in filenames:
+        if not find_file(f, os.getenv('PATH')): return False
+    return True
+
 from unittest import main
 if __name__ == "__main__":
     main()


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[28/50] qpid-proton git commit: PROTON-1532: ruby Container support for SASL, client and server.

Posted by ac...@apache.org.
PROTON-1532: ruby Container support for SASL, client and server.

- add Container.connect options for client-side SASL settings
- use on_connection_bound for server-side SASL settings based on incoming connection/transport

For example code see proton-c/bindings/ruby/tests/test_container.rb
Proper examples will be added later.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/36b64f73
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/36b64f73
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/36b64f73

Branch: refs/heads/go1
Commit: 36b64f73ffe7e9add93c32da622474d2ee29dce6
Parents: 0606126
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Aug 11 15:55:25 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Aug 22 15:41:48 2017 -0400

----------------------------------------------------------------------
 proton-c/CMakeLists.txt                         |  11 +-
 proton-c/bindings/ruby/lib/core/connection.rb   |  15 +-
 proton-c/bindings/ruby/lib/core/message.rb      |   4 +-
 proton-c/bindings/ruby/lib/core/sasl.rb         | 104 ++++++----
 proton-c/bindings/ruby/lib/core/transport.rb    |   2 +
 proton-c/bindings/ruby/lib/core/url.rb          |  16 +-
 .../ruby/lib/handler/endpoint_state_handler.rb  |   2 +-
 proton-c/bindings/ruby/lib/reactor/connector.rb |  73 ++++---
 proton-c/bindings/ruby/lib/reactor/container.rb |  77 +++----
 proton-c/bindings/ruby/lib/reactor/reactor.rb   |   1 -
 proton-c/bindings/ruby/lib/reactor/urls.rb      |   7 +-
 proton-c/bindings/ruby/lib/util/condition.rb    |   2 +
 proton-c/bindings/ruby/lib/util/swig_helper.rb  |   2 +-
 proton-c/bindings/ruby/tests/test_container.rb  | 200 +++++++++++++++++++
 proton-c/bindings/ruby/tests/test_tools.rb      | 193 ++++++++++++++++++
 proton-c/src/sasl/cyrus_sasl.c                  |   6 +-
 16 files changed, 603 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 054a054..2bfbb27 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -792,11 +792,12 @@ find_program(RUBY_EXE "ruby")
 if (RUBY_EXE AND BUILD_RUBY)
   set (rb_root "${pn_test_root}/ruby")
   set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby")
-  set (rb_lib "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby/lib")
+  set (rb_lib "${rb_src}/lib")
+  set (rb_tests "${rb_src}/tests")
   set (rb_bin "${CMAKE_CURRENT_BINARY_DIR}/bindings/ruby")
   set (rb_bld "$<TARGET_FILE_DIR:qpid-proton>")
   set (rb_path $ENV{PATH} ${rb_bin} ${rb_bld})
-  set (rb_rubylib ${rb_root} ${rb_src} ${rb_bin} ${rb_bld} ${rb_lib})
+  set (rb_rubylib ${rb_root} ${rb_src} ${rb_bin} ${rb_bld} ${rb_lib} ${rb_tests})
   to_native_path("${rb_path}" rb_path)
   to_native_path("${rb_rubylib}" rb_rubylib)
 
@@ -806,6 +807,12 @@ if (RUBY_EXE AND BUILD_RUBY)
     COMMAND ${env_py} -- "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
     ${RUBY_EXE} example_test.rb -v)
 
+  # TODO aconway 2017-08-16: move test cmake code to ruby/tests directory
+  add_test(NAME ruby-container-test
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/proton-c/bindings/ruby
+    COMMAND ${env_py} -- "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
+    ${RUBY_EXE} ${rb_tests}/test_container.rb -v)
+
   # ruby unit tests:  tests/ruby/proton-test
   # only enable the tests if the Ruby gem dependencies were found
   if (DEFAULT_RUBY_TESTING)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index c1bcaf3..949ff2a 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -19,7 +19,7 @@
 
 module Qpid::Proton
 
-  # A Connection option has at most one Qpid::Proton::Transport instance.
+  # A Connection has at most one Qpid::Proton::Transport instance.
   #
   class Connection < Endpoint
 
@@ -35,6 +35,19 @@ module Qpid::Proton
     #
     proton_accessor :hostname
 
+    # @!attribute user
+    #   The user name for authentication.
+    #
+    #   A client sets authentication data with the :user and :password options
+    #   to {Container#connect}. On a server this returns the authenticated name
+    #   from the client. It makes no sense to set this on the server side.
+    #
+    #   @return [String] the user name
+    proton_accessor :user
+
+    # @private
+    proton_writer :password
+
     # @private
     proton_reader :attachments
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index 26a3ae2..81bbadb 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -129,13 +129,13 @@ module Qpid::Proton
     end
 
     # Creates a new +Message+ instance.
-    def initialize
+    def initialize(body = nil)
       @impl = Cproton.pn_message
       ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
       @properties = {}
       @instructions = {}
       @annotations = {}
-      @body = nil
+      self.body = body unless body.nil?
     end
 
     def to_s

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/core/sasl.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/sasl.rb b/proton-c/bindings/ruby/lib/core/sasl.rb
index be57044..965c889 100644
--- a/proton-c/bindings/ruby/lib/core/sasl.rb
+++ b/proton-c/bindings/ruby/lib/core/sasl.rb
@@ -28,19 +28,7 @@ module Qpid::Proton
   # The peer acting as the SASL server must provide authentication against the
   # received credentials.
   #
-  # @example
-  #   # SCENARIO: the remote endpoint has not initialized their connection
-  #   #           then the local endpoint, acting as a SASL server, decides
-  #   #           to allow an anonymous connection.
-  #   #
-  #   #           The SASL layer locally assumes the role of server and then
-  #   #           enables anonymous authentication for the remote endpoint.
-  #   #
-  #   sasl = @transport.sasl
-  #   sasl.server
-  #   sasl.mechanisms("ANONYMOUS")
-  #   sasl.done(Qpid::Proton::SASL::OK)
-  #
+  # @note Do not instantiate directly, use {Transport#sasl} to create a SASL object.
   class SASL
 
     # Negotation has not completed.
@@ -50,45 +38,89 @@ module Qpid::Proton
     # Authentication failed due to bad credentials.
     AUTH = Cproton::PN_SASL_AUTH
 
-    # Constructs a new instance for the given transport.
-    #
-    # @param transport [Transport] The transport.
-    #
-    # @private A SASL should be fetched only from its Transport
-    #
+    private
+
+    include Util::SwigHelper
+    PROTON_METHOD_PREFIX = "pn_sasl"
+
+    public
+
+    # @private
+    # @note Do not instantiate directly, use {Transport#sasl} to create a SASL object.
     def initialize(transport)
       @impl = Cproton.pn_sasl(transport.impl)
     end
 
-    # Sets the acceptable SASL mechanisms.
+    # @!attribute allow_insecure_mechs
+    #   @return [Bool] true if clear text authentication is allowed on insecure connections.
+    proton_accessor :allow_insecure_mechs
+
+    # @!attribute user [r]
+    #   @return [String] the authenticated user name
+    proton_reader :user
+
+    # Set the mechanisms allowed for SASL negotation
+    # @param mechanisms [String] space-delimited list of allowed mechanisms
+    def allowed_mechs=(mechanisms)
+      Cproton.pn_sasl_allowed_mechs(@impl, mechanisms)
+    end
+
+    # @deprecated use {#allowed_mechs=}
+    def mechanisms(m)
+      self.allowed_mechs = m
+    end
+
+    # True if extended SASL negotiation is supported
     #
-    # @param mechanisms [String] The space-delimited set of mechanisms.
+    # All implementations of Proton support ANONYMOUS and EXTERNAL on both
+    # client and server sides and PLAIN on the client side.
     #
-    # @example Use anonymous SASL authentication.
-    #  @sasl.mechanisms("GSSAPI CRAM-MD5 PLAIN")
+    # Extended SASL implememtations use an external library (Cyrus SASL)
+    # to support other mechanisms.
     #
-    def mechanisms(mechanisms)
-      Cproton.pn_sasl_mechanisms(@impl, mechanisms)
+    # @return [Bool] true if extended SASL negotiation is supported
+    def self.extended?()
+      Cproton.pn_sasl_extended()
     end
 
-    # Returns the outcome of the SASL negotiation.
+    # Set the sasl configuration path
+    #
+    # This is used to tell SASL where to look for the configuration file.
+    # In the current implementation it can be a colon separated list of directories.
+    #
+    # The environment variable PN_SASL_CONFIG_PATH can also be used to set this path,
+    # but if both methods are used then this pn_sasl_config_path() will take precedence.
+    #
+    # If not set the underlying implementation default will be used.
     #
-    # @return [Integer] The outcome.
+    # @param path the configuration path
     #
-    def outcome
-      outcome = Cprotn.pn_sasl_outcome(@impl)
-      return nil if outcome == NONE
-      outcome
+    def self.config_path=(path)
+      Cproton.pn_sasl_config_path(nil, path)
+      path
     end
 
-    # Set the condition of the SASL negotiation.
+    # @deprecated use {config_path=}
+    def self.config_path(path)
+      self.config_path = path
+    end
+
+    # Set the configuration file name, without extension
+    #
+    # The name with an a ".conf" extension will be searched for in the
+    # configuration path.  If not set, it defaults to "proton-server" or
+    # "proton-client" for a server (incoming) or client (outgoing) connection
+    # respectively.
     #
-    # @param outcome [Integer] The outcome.
+    # @param name the configuration file name without extension
     #
-    def done(outcome)
-      Cproton.pn_sasl_done(@impl, outcome)
+    def self.config_name=(name)
+      Cproton.pn_sasl_config_name(nil, name)
     end
 
+    # @deprecated use {config_name=}
+    def self.config_name(name)
+      self.config_name = name
+    end
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index c3cacc7..04697a3 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -386,6 +386,8 @@ module Qpid::Proton
       Cproton.pn_transport_tick(@impl, now)
     end
 
+    # Create, or return existing, SSL object for the transport.
+    # @return [SASL] the SASL object
     def sasl
       SASL.new(self)
     end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/core/url.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/url.rb b/proton-c/bindings/ruby/lib/core/url.rb
index 1fa1222..39b6465 100644
--- a/proton-c/bindings/ruby/lib/core/url.rb
+++ b/proton-c/bindings/ruby/lib/core/url.rb
@@ -28,11 +28,13 @@ module Qpid::Proton
     attr_reader :port
     attr_reader :path
 
+    # Parse a string, return a new URL
+    # @param url [#to_s] the URL string
     def initialize(url = nil, options = {})
       options[:defaults] = true
 
       if url
-        @url = Cproton.pn_url_parse(url)
+        @url = Cproton.pn_url_parse(url.to_s)
         if @url.nil?
           raise ::ArgumentError.new("invalid url: #{url}")
         end
@@ -64,6 +66,11 @@ module Qpid::Proton
       "#{@scheme}://#{@username.nil? ? '' : @username}#{@password.nil? ? '' : '@' + @password + ':'}#{@host}:#{@port}/#{@path}"
     end
 
+    # Return self
+    def to_url()
+      self
+    end
+
     private
 
     def defaults
@@ -71,7 +78,12 @@ module Qpid::Proton
       @host = @host || "0.0.0.0"
       @port = @port || 5672
     end
-
   end
+end
 
+class String
+  # Convert this string to a URL
+  def to_url()
+    return URL.new(self)
+  end
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
index 727a20b..11e970a 100644
--- a/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/endpoint_state_handler.rb
@@ -119,7 +119,7 @@ module Qpid::Proton::Handler
     end
 
     def on_connection_opened(event)
-      Qpid::Proton::Event.dispatch(@delegate, :on_session_opened, event) if !@delegate.nil?
+      Qpid::Proton::Event.dispatch(@delegate, :on_connection_opened, event) if !@delegate.nil?
     end
 
     def on_session_opened(event)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/reactor/connector.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/connector.rb b/proton-c/bindings/ruby/lib/reactor/connector.rb
index a6523db..0971141 100644
--- a/proton-c/bindings/ruby/lib/reactor/connector.rb
+++ b/proton-c/bindings/ruby/lib/reactor/connector.rb
@@ -21,16 +21,24 @@ module Qpid::Proton::Reactor
 
   class Connector < Qpid::Proton::BaseHandler
 
-    attr_accessor :address
-    attr_accessor :reconnect
-    attr_accessor :ssl_domain
+    def initialize(connection, url, opts)
+      @connection, @opts = connection, opts
+      @urls = URLs.new(url) if url
+      opts.each do |k,v|
+        case k
+        when :url, :urls, :address
+          @urls = URLs.new(v) unless @urls
+        when :reconnect
+          @reconnect = v
+        end
+      end
+      raise ::ArgumentError.new("no url for connect") unless @urls
 
-    def initialize(connection)
-      @connection = connection
-      @address = nil
-      @heartbeat = nil
-      @reconnect = nil
-      @ssl_domain = nil
+      # TODO aconway 2017-08-17: review reconnect configuration and defaults
+      @reconnect = Backoff.new() unless @reconnect
+      @ssl_domain = SessionPerConnection.new # TODO seems this should be configurable
+      @connection.overrides = self
+      @connection.open
     end
 
     def on_connection_local_open(event)
@@ -38,10 +46,7 @@ module Qpid::Proton::Reactor
     end
 
     def on_connection_remote_open(event)
-      if !@reconnect.nil?
-        @reconnect.reset
-        @transport = nil
-      end
+      @reconnect.reset if @reconnect
     end
 
     def on_transport_tail_closed(event)
@@ -73,26 +78,38 @@ module Qpid::Proton::Reactor
     end
 
     def connect(connection)
-      url = @address.next
+      url = @urls.next
+      transport = Qpid::Proton::Transport.new
+      @opts.each do |k,v|
+        case k
+        when :user
+          connection.user = v
+        when :password
+          connection.password = v
+        when :heartbeat
+          transport.idle_timeout = v.to_i
+        when :idle_timeout
+          transport.idle_timeout = v.(v*1000).to_i
+        when :sasl_enabled
+          transport.sasl if v
+        when :sasl_allow_insecure_mechs
+          transport.sasl.allow_insecure_mechs = v
+        when :sasl_allowed_mechs, :sasl_mechanisms
+          transport.sasl.allowed_mechs = v
+        end
+      end
+
+      # TODO aconway 2017-08-11: hostname setting is incorrect, reactor only
       connection.hostname = "#{url.host}:#{url.port}"
+      connection.user = url.username if url.username && !url.username.empty?
+      connection.password = url.password if url.password && !url.password.empty?
 
-      transport = Qpid::Proton::Transport.new
       transport.bind(connection)
-      if !@heartbeat.nil?
-        transport.idle_timeout = @heartbeat
-      elsif (url.scheme == "amqps") && !@ssl_domain.nil?
+
+      if (url.scheme == "amqps") && @ssl_domain
         @ssl = Qpid::Proton::SSL.new(transport, @ssl_domain)
-        @ss.peer_hostname = url.host
-      elsif !url.username.nil?
-        sasl = transport.sasl
-        if url.username == "anonymous"
-          sasl.mechanisms("ANONYMOUS")
-        else
-          sasl.plain(url.username, url.password)
-        end
+        @ssl.peer_hostname = url.host
       end
     end
-
   end
-
 end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/reactor/container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/container.rb b/proton-c/bindings/ruby/lib/reactor/container.rb
index 2a7a030..aa1b303 100644
--- a/proton-c/bindings/ruby/lib/reactor/container.rb
+++ b/proton-c/bindings/ruby/lib/reactor/container.rb
@@ -19,7 +19,7 @@
 
 module Qpid::Proton::Reactor
 
-  # @private
+  private
   class InternalTransactionHandler < Qpid::Proton::Handler::OutgoingMessageHandler
 
     def initialize
@@ -35,7 +35,7 @@ module Qpid::Proton::Reactor
 
   end
 
-
+  public
   # A representation of the AMQP concept of a container which, loosely
   # speaking, is something that establishes links to or from another
   # container on which messages are transferred.
@@ -74,42 +74,49 @@ module Qpid::Proton::Reactor
       end
     end
 
-    # Initiates the establishment of an AMQP connection.
+    # TODO aconway 2017-08-17: fill out options
+
+    # Connects to a remote AMQP endpoint and sends an AMQP "open" frame.
     #
-    # @param options [Hash] A hash of named arguments.
+    # @param url [#to_url] Connect to URL host:port.
+    #   If URL has user:password use them for authentication.
     #
-    def connect(options = {})
-      conn = self.connection(options[:handler])
-      conn.container = self.container_id || generate_uuid
-      connector = Connector.new(conn)
-      conn.overrides = connector
-      if !options[:url].nil?
-        connector.address = URLs.new([options[:url]])
-      elsif !options[:urls].nil?
-        connector.address = URLs.new(options[:urls])
-      elsif !options[:address].nil?
-        connector.address = URLs.new([Qpid::Proton::URL.new(options[:address])])
-      else
-        raise ::ArgumentError.new("either :url or :urls or :address required")
-      end
-
-      connector.heartbeat = options[:heartbeat] if !options[:heartbeat].nil?
-      if !options[:reconnect].nil?
-        connector.reconnect = options[:reconnect]
-      else
-        connector.reconnect = Backoff.new()
+    # @option opts [String] :user user name for authentication if not given by URL
+    # @option opts [String] :password password for authentication if not given by URL
+    #
+    # @option opts [Numeric] :idle_timeout seconds before closing an idle connection
+    #
+    # @option opts [Boolean] :sasl_enabled Enable or disable SASL.
+    #
+    # @option opts [Boolean] :sasl_allow_insecure_mechs Allow mechanisms that disclose clear text
+    #   passwords, even over an insecure connection. By default, such mechanisms are only allowed
+    #   when SSL is enabled.
+    #
+    # @option opts [String] :sasl_allowed_mechs the allowed SASL mechanisms for use on the connection.
+    #
+    # @param url [Hash] *deprecated* if url is a Hash and opts is unspecified, treat it as opts.
+    # @option opts [#to_url] :url *deprecated* use the url parameter
+    # @option opts [Enumerable<#to_url>] :urls *deprecated* use the url parameter
+    # @option opts [#to_url] :address *deprecated* use the url parameter
+    # @option opts [#to_url] :heartbeat *deprecated* alias for :idle_timeout, but in milliseconds
+    # @return [Connection] the new connection
+    #
+    def connect(url, opts = {})
+      # Backwards compatible with old connect(options)
+      if url.is_a? Hash and opts.empty?
+        opts = url
+        url = nil
       end
-
-      connector.ssl_domain = SessionPerConnection.new # TODO seems this should be configurable
-
-      conn.open
-
+      conn = self.connection(opts[:handler])
+      conn.container = self.container_id || generate_uuid
+      connector = Connector.new(conn, url, opts)
       return conn
     end
 
+    private
     def _session(context)
       if context.is_a?(Qpid::Proton::URL)
-        return self._session(self.connect(:url => context))
+        return _session(self.connect(:url => context))
       elsif context.is_a?(Qpid::Proton::Session)
         return context
       elsif context.is_a?(Qpid::Proton::Connection)
@@ -123,6 +130,7 @@ module Qpid::Proton::Reactor
       end
     end
 
+    public
     # Initiates the establishment of a link over which messages can be sent.
     #
     # @param context [String, URL] The context.
@@ -146,7 +154,7 @@ module Qpid::Proton::Reactor
         target = context.path
       end
 
-      session = self._session(context)
+      session = _session(context)
 
       sender = session.sender(opts[:name] ||
                               id(session.connection.container,
@@ -155,7 +163,7 @@ module Qpid::Proton::Reactor
         sender.target.address = target if target
         sender.handler = opts[:handler] if !opts[:handler].nil?
         sender.tag_generator = opts[:tag_generator] if !opts[:tag_gnenerator].nil?
-        self._apply_link_options(opts[:options], sender)
+        _apply_link_options(opts[:options], sender)
         sender.open
         return sender
     end
@@ -192,7 +200,7 @@ module Qpid::Proton::Reactor
         source = context.path
       end
 
-      session = self._session(context)
+      session = _session(context)
 
       receiver = session.receiver(opts[:name] ||
                                   id(session.connection.container,
@@ -201,7 +209,7 @@ module Qpid::Proton::Reactor
       receiver.source.dynamic = true if opts.has_key?(:dynamic) && opts[:dynamic]
       receiver.target.address = opts[:target] if !opts[:target].nil?
       receiver.handler = opts[:handler] if !opts[:handler].nil?
-      self._apply_link_options(opts[:options], receiver)
+      _apply_link_options(opts[:options], receiver)
       receiver.open
       return receiver
     end
@@ -236,6 +244,7 @@ module Qpid::Proton::Reactor
       return acceptor
     end
 
+    private
     def do_work(timeout = nil)
       self.timeout = timeout unless timeout.nil?
       self.process

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/reactor/reactor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/reactor.rb b/proton-c/bindings/ruby/lib/reactor/reactor.rb
index a84a716..f612876 100644
--- a/proton-c/bindings/ruby/lib/reactor/reactor.rb
+++ b/proton-c/bindings/ruby/lib/reactor/reactor.rb
@@ -115,7 +115,6 @@ module Qpid::Proton::Reactor
     end
 
     def run(&block)
-      self.timeout = 3.14159265359
       self.start
       while self.process do
         if block_given?

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/reactor/urls.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/urls.rb b/proton-c/bindings/ruby/lib/reactor/urls.rb
index 8cdb16c..44fd956 100644
--- a/proton-c/bindings/ruby/lib/reactor/urls.rb
+++ b/proton-c/bindings/ruby/lib/reactor/urls.rb
@@ -22,7 +22,12 @@ module Qpid::Proton::Reactor
   class URLs
 
     def initialize(values)
-      @values = [values].flatten
+      @values = values
+      if @values.is_a? Enumerable
+        @values = @values.map { |u| u.to_url }
+      else
+        @values = [values.to_url]
+      end
       @iter = @values.each
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/util/condition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/condition.rb b/proton-c/bindings/ruby/lib/util/condition.rb
index b8fd94b..ad49595 100644
--- a/proton-c/bindings/ruby/lib/util/condition.rb
+++ b/proton-c/bindings/ruby/lib/util/condition.rb
@@ -21,6 +21,8 @@ module Qpid::Proton::Util
 
   class Condition
 
+    attr_reader :name, :description, :info
+
     def initialize(name, description = nil, info = nil)
       @name = name
       @description = description

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/lib/util/swig_helper.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/util/swig_helper.rb b/proton-c/bindings/ruby/lib/util/swig_helper.rb
index d60e9e4..5567235 100644
--- a/proton-c/bindings/ruby/lib/util/swig_helper.rb
+++ b/proton-c/bindings/ruby/lib/util/swig_helper.rb
@@ -86,7 +86,7 @@ module Qpid::Proton::Util
         proton_method = "#{self::PROTON_METHOD_PREFIX}_#{name}"
         # drop the trailing '?' if this is a property method
         proton_method = proton_method[0..-2] if proton_method.end_with? "?"
-        create_wrapper_method(name, proton_method)
+        create_wrapper_method(name, proton_method, options[:arg])
       end
 
       def proton_writer(name, options = {})

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/tests/test_container.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_container.rb b/proton-c/bindings/ruby/tests/test_container.rb
new file mode 100644
index 0000000..7ed81b2
--- /dev/null
+++ b/proton-c/bindings/ruby/tests/test_container.rb
@@ -0,0 +1,200 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+require 'test_tools'
+
+Message = Qpid::Proton::Message
+SASL = Qpid::Proton::SASL
+URL = Qpid::Proton::URL
+
+class ContainerTest < Minitest::Test
+
+  # Send n messages
+  class SendMessageClient < TestHandler
+    attr_reader :accepted
+
+    def initialize(url, link_name, body)
+      super()
+      @url, @link_name, @message = url, link_name, Message.new(body)
+    end
+
+    def on_start(event)
+      event.container.create_sender(@url, {:name => @link_name})
+    end
+
+    def on_sendable(event)
+      if event.sender.credit > 0
+        event.sender.send(@message)
+      end
+    end
+
+    def on_accepted(event)
+      @accepted = event
+      event.connection.close
+    end
+  end
+
+  def test_simple()
+    TestServer.new.run do |s|
+      lname = "test-link"
+      body = "hello"
+      c = SendMessageClient.new(s.addr, lname, body).run
+      assert_instance_of(Qpid::Proton::Event::Event, c.accepted)
+      assert_equal(lname, s.links.pop(true).name)
+      assert_equal(body, s.messages.pop(true).body)
+    end
+  end
+
+end
+
+class ContainerSASLTest < Minitest::Test
+
+  # Connect to URL using mechanisms and insecure to configure the transport
+  class SASLClient < TestHandler
+
+    def initialize(url, opts={})
+      super()
+      @url, @opts = url, opts
+    end
+
+    def on_start(event)
+      event.container.connect(@url, @opts)
+    end
+
+    def on_connection_opened(event)
+      super
+      event.container.stop
+    end
+  end
+
+  # Server with SASL settings
+  class SASLServer < TestServer
+    def initialize(mechanisms=nil, insecure=nil, realm=nil)
+      super()
+      @mechanisms, @insecure, @realm = mechanisms, insecure, realm
+    end
+
+    def on_connection_bound(event)
+      sasl = event.transport.sasl
+      sasl.allow_insecure_mechs = @insecure unless @insecure.nil?
+      sasl.allowed_mechs = @mechanisms unless @mechanisms.nil?
+      # TODO aconway 2017-08-16: need `sasl.realm(@realm)` here for non-default realms.
+      # That reqiures pn_sasl_set_realm() at the C layer - the realm should
+      # be passed to cyrus_sasl_init_server()
+    end
+  end
+
+  # Generate SASL server configuration files and database, initialize proton SASL
+  class SASLConfig
+    attr_reader :conf_dir, :conf_file, :conf_name, :database
+
+    def initialize()
+      if SASL.extended? # Configure cyrus SASL
+        @conf_dir = File.expand_path('sasl_conf')
+        @conf_name = "proton-server"
+        @database = File.join(@conf_dir, "proton.sasldb")
+        @conf_file = File.join(conf_dir,"#{@conf_name}.conf")
+        Dir::mkdir(@conf_dir) unless File.directory?(@conf_dir)
+        # Same user name in different realms
+        make_user("user", "password", "proton") # proton realm
+        make_user("user", "default_password") # Default realm
+        File.open(@conf_file, 'w') do |f|
+          f.write("
+sasldb_path: #{database}
+mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS
+")
+        end
+        # Tell proton library to use the new configuration
+        SASL.config_path(conf_dir)
+        SASL.config_name(conf_name)
+      end
+    end
+
+    private
+
+    SASLPASSWD = (ENV['SASLPASSWD'] or 'saslpasswd2')
+
+    def make_user(user, password, realm=nil)
+      realm_opt = (realm ? "-u #{realm}" : "")
+      cmd = "echo '#{password}' | #{SASLPASSWD} -c -p -f #{database} #{realm_opt} #{user}"
+      system(cmd) or raise RuntimeError.new("saslpasswd2 failed: #{makepw_cmd}")
+    end
+    DEFAULT = SASLConfig.new
+  end
+
+  def test_sasl_anonymous()
+    SASLServer.new("ANONYMOUS").run do |s|
+      c = SASLClient.new(s.addr, {:sasl_allowed_mechs => "ANONYMOUS"}).run
+      refute_empty(c.connections)
+      refute_empty(s.connections)
+      assert_nil(s.connections.pop(true).user)
+    end
+  end
+
+  def test_sasl_plain_url()
+    # Use default realm with URL, should authenticate with "default_password"
+    SASLServer.new("PLAIN", true).run do |s|
+      c = SASLClient.new("amqp://user:default_password@#{s.addr}",
+                         {:sasl_allowed_mechs => "PLAIN", :sasl_allow_insecure_mechs => true}).run
+      refute_empty(c.connections)
+      refute_empty(s.connections)
+      sc = s.connections.pop(true)
+      assert_equal("user", sc.transport.sasl.user)
+    end
+  end
+
+  def test_sasl_plain_options()
+    # Use default realm with connection options, should authenticate with "default_password"
+    SASLServer.new("PLAIN", true).run do |s|
+      c = SASLClient.new(s.addr,
+                         {:user => "user", :password => "default_password",
+                          :sasl_allowed_mechs => "PLAIN", :sasl_allow_insecure_mechs => true}).run
+      refute_empty(c.connections)
+      refute_empty(s.connections)
+      sc = s.connections.pop(true)
+      assert_equal("user", sc.transport.sasl.user)
+    end
+  end
+
+  # Test disabled, see on_connection_bound - missing realm support in proton C.
+  def TODO_test_sasl_plain_realm()
+    # Use the non-default proton realm on the server, should authenticate with "password"
+    SASLServer.new("PLAIN", true, "proton").run do |s|
+      c = SASLClient.new("amqp://user:password@#{s.addr}",
+                         {:sasl_allowed_mechs => "PLAIN", :sasl_allow_insecure_mechs => true}).run
+      refute_empty(c.connections)
+      refute_empty(s.connections)
+      sc = s.connections.pop(true)
+      assert_equal("user", sc.transport.sasl.user)
+    end
+  end
+
+  # Ensure we don't allow PLAIN if allow_insecure_mechs = true is not explicitly set
+  def test_disallow_insecure()
+    # Don't set allow_insecure_mechs, but try to use PLAIN
+    SASLServer.new("PLAIN", nil).run(true) do |s|
+      begin
+        SASLClient.new("amqp://user:password@#{s.addr}",
+                       {:sasl_allowed_mechs => "PLAIN", :sasl_allow_insecure_mechs => true}).run
+      rescue TestError => e
+        assert_match(/PN_TRANSPORT_ERROR.*unauthorized-access/, e.to_s)
+      end
+    end
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/bindings/ruby/tests/test_tools.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_tools.rb b/proton-c/bindings/ruby/tests/test_tools.rb
new file mode 100644
index 0000000..a48a508
--- /dev/null
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -0,0 +1,193 @@
+#--
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#++
+
+# Tools for tests
+
+require 'minitest/autorun'
+require 'qpid_proton'
+require 'thread'
+require 'socket'
+
+Container = Qpid::Proton::Reactor::Container
+MessagingHandler = Qpid::Proton::Handler::MessagingHandler
+
+# Bind an unused local port using bind(0) and SO_REUSEADDR and hold it till close()
+# Provides #host, #port and #addr ("host:port") as strings
+class TestPort
+  attr_reader :host, :port, :addr
+
+  # With block, execute block passing self then close
+  # Note host must be the local host, but you can pass '::1' instead for ipv6
+  def initialize(host='127.0.0.1')
+    @sock = Socket.new(:INET, :STREAM)
+    @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
+    @sock.bind(Socket.sockaddr_in(0, host))
+    @host, @port = @sock.connect_address.ip_unpack
+    @addr = "#{@host}:#{@port}"
+    if block_given?
+      begin
+        yield self
+      ensure
+        close
+      end
+    end
+  end
+
+  def close
+    @sock.close()
+  end
+end
+
+class TestError < Exception; end
+
+# Handler that creates its own container to run itself, and records some common
+# events that are checked by tests
+class TestHandler < MessagingHandler
+
+  # Record errors and successfully opened endpoints
+  attr_reader :errors, :connections, :sessions, :links, :messages
+
+  # Pass optional extra handlers and options to the Container
+  def initialize(handlers=[], options={})
+    super()
+    # Use Queue so the values can be extracted in a thread-safe way during or after a test.
+    @errors, @connections, @sessions, @links, @messages = (1..5).collect { Queue.new }
+    @container = Container.new([self]+handlers, options)
+  end
+
+  # Run the handlers container, return self.
+  # Raise an exception for server errors unless no_raise is true.
+  def run(no_raise=false)
+    @container.run
+    raise_errors unless no_raise
+    self
+  end
+
+  # If the handler has errors, raise a TestError with all the error text
+  def raise_errors()
+    return if @errors.empty?
+    text = ""
+    while @errors.size > 0
+      text << @errors.pop + "\n"
+    end
+    raise TestError.new("TestServer has errors:\n #{text}")
+  end
+
+  # TODO aconway 2017-08-15: implement in MessagingHandler
+  def on_error(event, endpoint)
+    @errors.push "#{event.type}: #{endpoint.condition.name}: #{endpoint.condition.description}"
+    raise_errors
+  end
+
+  def on_transport_error(event)
+    on_error(event, event.transport)
+  end
+
+  def on_connection_error(event)
+    on_error(event, event.condition)
+  end
+
+  def on_session_error(event)
+    on_error(event, event.session)
+  end
+
+  def on_link_error(event)
+    on_error(event, event.link)
+  end
+
+  def on_opened(queue, endpoint)
+    queue.push(endpoint)
+    endpoint.open
+  end
+
+  def on_connection_opened(event)
+    on_opened(@connections, event.connection)
+  end
+
+  def on_session_opened(event)
+    on_opened(@sessions, event.session)
+  end
+
+  def on_link_opened(event)
+    on_opened(@links, event.link)
+  end
+
+  def on_message(event)
+    @messages.push(event.message)
+  end
+end
+
+# A TestHandler that runs itself in a thread and listens on a TestPort
+class TestServer < TestHandler
+  attr_reader :host, :port, :addr
+
+  # Pass optional handlers, options to the container
+  def initialize(handlers=[], options={})
+    super
+    @tp = TestPort.new
+    @host, @port, @addr = @tp.host, @tp.port, @tp.addr
+    @listening = false
+    @ready = Queue.new
+  end
+
+  # Start server thread
+  def start(no_raise=false)
+    @thread = Thread.new do
+      begin
+        @container.listen(addr)
+        @container.run
+      rescue TestError
+        ready.push :error
+       rescue => e
+        msg = "TestServer run raised: #{e.message}\n#{e.backtrace.join("\n")}"
+        @errors << msg
+        @ready.push(:error)
+        # TODO aconway 2017-08-22: container.stop - doesn't stop the thread.
+      end
+    end
+    raise_errors unless @ready.pop == :listening or no_raise
+  end
+
+  # Stop server thread
+  def stop(no_raise=false)
+    @container.stop
+    if not @errors.empty?
+      @thread.kill
+    else
+      @thread.join
+    end
+    @tp.close
+    raise_errors unless no_raise
+  end
+
+  # start(), execute block with self, stop()
+  def run(no_raise=false)
+    begin
+      start(no_raise)
+      yield self
+    ensure
+      stop(no_raise)
+    end
+  end
+
+  def on_start(event)
+    @ready.push :listening
+    @listening = true
+  end
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/36b64f73/proton-c/src/sasl/cyrus_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/cyrus_sasl.c b/proton-c/src/sasl/cyrus_sasl.c
index 88bdd7a..ab6eba6 100644
--- a/proton-c/src/sasl/cyrus_sasl.c
+++ b/proton-c/src/sasl/cyrus_sasl.c
@@ -180,9 +180,9 @@ void pn_sasl_config_name(pn_sasl_t *sasl0, const char *name)
 
 void pn_sasl_config_path(pn_sasl_t *sasl0, const char *dir)
 {
-    if (!pni_cyrus_config_dir) {
-      pni_cyrus_config_dir = strdup(dir);
-    }
+  if (!pni_cyrus_config_dir) {
+    pni_cyrus_config_dir = strdup(dir);
+  }
 }
 
 __attribute__((destructor))


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[45/50] qpid-proton git commit: PROTON-1566: [C++ binding] Reconnect - Implemented retry with exponential backoff

Posted by ac...@apache.org.
PROTON-1566: [C++ binding] Reconnect
- Implemented retry with exponential backoff


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/740b9509
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/740b9509
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/740b9509

Branch: refs/heads/go1
Commit: 740b95099f350980f7156821e65d9947147c80bc
Parents: b60f093
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Aug 31 10:47:36 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 31 10:54:31 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/CMakeLists.txt            |   2 +-
 .../cpp/include/proton/connection_options.hpp   |  16 ++-
 proton-c/bindings/cpp/include/proton/fwd.hpp    |   2 +-
 .../cpp/include/proton/reconnect_options.hpp    |  84 ++++++++++++++++
 .../cpp/include/proton/reconnect_timer.hpp      |  71 -------------
 .../bindings/cpp/src/connection_options.cpp     |  20 ++--
 proton-c/bindings/cpp/src/contexts.cpp          |   7 +-
 proton-c/bindings/cpp/src/include/contexts.hpp  |  17 +++-
 .../cpp/src/include/proactor_container_impl.hpp |  11 ++
 .../cpp/src/include/reconnect_options_impl.hpp  |  41 ++++++++
 .../cpp/src/proactor_container_impl.cpp         | 100 +++++++++++++++++--
 proton-c/bindings/cpp/src/reconnect_options.cpp |  43 ++++++++
 proton-c/bindings/cpp/src/reconnect_timer.cpp   |  64 ------------
 13 files changed, 312 insertions(+), 166 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 472105a..330858a 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -56,7 +56,7 @@ set(qpid-proton-cpp-source
   src/proton_bits.cpp
   src/receiver.cpp
   src/receiver_options.cpp
-  src/reconnect_timer.cpp
+  src/reconnect_options.cpp
   src/returned.cpp
   src/sasl.cpp
   src/scalar_base.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index 62af5f3..066e8cf 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -22,12 +22,12 @@
  *
  */
 
+#include "./duration.hpp"
 #include "./fwd.hpp"
-#include "./types_fwd.hpp"
 #include "./internal/config.hpp"
 #include "./internal/export.hpp"
 #include "./internal/pn_unique_ptr.hpp"
-#include "./duration.hpp"
+#include "./types_fwd.hpp"
 
 #include <proton/type_compat.h>
 
@@ -123,13 +123,6 @@ class connection_options {
     /// container::listen.
     PN_CPP_EXTERN connection_options& password(const std::string&);
 
-    /// @cond INTERNAL
-    // XXX settle questions about reconnect_timer - consider simply
-    // reconnect_options and making reconnect_timer internal
-    /// **Experimental**
-    PN_CPP_EXTERN connection_options& reconnect(const reconnect_timer&);
-    /// @endcond
-
     /// Set SSL client options.
     PN_CPP_EXTERN connection_options& ssl_client_options(const class ssl_client_options&);
 
@@ -153,6 +146,11 @@ class connection_options {
     /// **Unsettled API** - Set the SASL configuration path.
     PN_CPP_EXTERN connection_options& sasl_config_path(const std::string&);
 
+    /// **Experimental** - Options for reconnect on outgoing connections.
+    PN_CPP_EXTERN connection_options& reconnect(reconnect_options &);
+
+    
+
     /// Update option values from values set in other.
     PN_CPP_EXTERN connection_options& update(const connection_options& other);
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/include/proton/fwd.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/fwd.hpp b/proton-c/bindings/cpp/include/proton/fwd.hpp
index efbb91b..a394579 100644
--- a/proton-c/bindings/cpp/include/proton/fwd.hpp
+++ b/proton-c/bindings/cpp/include/proton/fwd.hpp
@@ -40,7 +40,7 @@ class listener;
 class receiver;
 class receiver_iterator;
 class receiver_options;
-class reconnect_timer;
+class reconnect_options;
 class sasl;
 class sender;
 class sender_iterator;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/include/proton/reconnect_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reconnect_options.hpp b/proton-c/bindings/cpp/include/proton/reconnect_options.hpp
new file mode 100644
index 0000000..e8ed02c
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/reconnect_options.hpp
@@ -0,0 +1,84 @@
+#ifndef PROTON_RECONNECT_OPTIONS_HPP
+#define PROTON_RECONNECT_OPTIONS_HPP
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "./internal/export.hpp"
+#include "./internal/pn_unique_ptr.hpp"
+#include "./duration.hpp"
+#include "./source.hpp"
+
+#include <string>
+
+namespace proton {
+
+/// **Experimental** - Options that determine a series of delays to
+/// coordinate reconnection attempts.  They may be open ended or
+/// limited in time.  They may be evenly spaced or increasing at an
+/// exponential rate.
+///
+/// Options can be "chained" (@see proton::connection_options).
+///
+/// Normal value semantics: copy or assign creates a separate copy of
+/// the options.
+class reconnect_options {
+  public:
+
+    /// Create an empty set of options.
+    PN_CPP_EXTERN reconnect_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN reconnect_options(const reconnect_options&);
+
+    PN_CPP_EXTERN ~reconnect_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN reconnect_options& operator=(const reconnect_options&);
+
+    /// Base value for recurring delay (default is 10 milliseconds).
+    PN_CPP_EXTERN reconnect_options& delay(duration);
+
+    /// Scaling multiplier for successive reconnect delays (default is 2.0)
+    PN_CPP_EXTERN reconnect_options& delay_multiplier(float);
+
+    /// Maximum delay between successive connect attempts (default
+    /// duration::FOREVER, i.e. no limit)
+    PN_CPP_EXTERN reconnect_options& max_delay(duration);
+
+    /// Maximum reconnect attempts (default 0, meaning no limit)
+    PN_CPP_EXTERN reconnect_options& max_attempts(int);
+
+    /// TODO: failover_urls
+
+
+  private:
+    class impl;
+    internal::pn_unique_ptr<impl> impl_;
+
+    /// @cond INTERNAL
+  friend class container;
+      /// @endcond
+};
+
+} // proton
+
+#endif // PROTON_RECONNECT_OPTIONS_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/include/proton/reconnect_timer.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reconnect_timer.hpp b/proton-c/bindings/cpp/include/proton/reconnect_timer.hpp
deleted file mode 100644
index 766feb7..0000000
--- a/proton-c/bindings/cpp/include/proton/reconnect_timer.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef PROTON_RECONNECT_TIMER_HPP
-#define PROTON_RECONNECT_TIMER_HPP
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-/// @cond INTERNAL
-/// XXX Needs more discussion
-
-#include "./internal/export.hpp"
-#include "./duration.hpp"
-#include "./timestamp.hpp"
-
-#include <proton/type_compat.h>
-
-namespace proton {
-
-/// **Experimental** - A class that generates a series of delays to
-/// coordinate reconnection attempts.  They may be open ended or
-/// limited in time.  They may be evenly spaced or doubling at an
-/// exponential rate.
-class reconnect_timer {
-  public:
-    PN_CPP_EXTERN reconnect_timer(uint32_t first = 0, int32_t max = -1, uint32_t increment = 100,
-                                  bool doubling = true, int32_t max_retries = -1, int32_t timeout = -1);
-
-    /// Indicate a successful connection, resetting the internal timer
-    /// values.
-    PN_CPP_EXTERN void reset();
-
-    /// Obtain the timer's computed time to delay before attempting a
-    /// reconnection attempt (in milliseconds).  -1 means that the
-    /// retry limit or timeout has been exceeded and reconnection
-    /// attempts should cease.
-    PN_CPP_EXTERN int next_delay(timestamp now);
-
-  private:
-    duration first_delay_;
-    duration max_delay_;
-    duration increment_;
-    bool doubling_;
-    int32_t max_retries_;
-    duration timeout_;
-    int32_t retries_;
-    duration next_delay_;
-    timestamp timeout_deadline_;
-};
-
-} // proton
-
-/// @endcond
-
-#endif // PROTON_RECONNECT_TIMER_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/connection_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_options.cpp b/proton-c/bindings/cpp/src/connection_options.cpp
index 0848c73..ff97764 100644
--- a/proton-c/bindings/cpp/src/connection_options.cpp
+++ b/proton-c/bindings/cpp/src/connection_options.cpp
@@ -18,11 +18,12 @@
  * under the License.
  *
  */
-#include "proton/fwd.hpp"
-#include "proton/connection.hpp"
 #include "proton/connection_options.hpp"
+
+#include "proton/connection.hpp"
+#include "proton/fwd.hpp"
 #include "proton/messaging_handler.hpp"
-#include "proton/reconnect_timer.hpp"
+#include "proton/reconnect_options.hpp"
 #include "proton/transport.hpp"
 #include "proton/ssl.hpp"
 #include "proton/sasl.hpp"
@@ -57,7 +58,7 @@ class connection_options::impl {
     option<std::string> virtual_host;
     option<std::string> user;
     option<std::string> password;
-    option<reconnect_timer> reconnect;
+    option<reconnect_options> reconnect;
     option<class ssl_client_options> ssl_client_options;
     option<class ssl_server_options> ssl_server_options;
     option<bool> sasl_enabled;
@@ -73,16 +74,15 @@ class connection_options::impl {
      * transport options (set once per transport over the life of the
      * connection).
      */
-    void apply_unbound(connection& c) {
+    void apply_unbound(connection& c, const connection_options& co) {
         pn_connection_t *pnc = unwrap(c);
 
         // Only apply connection options if uninit.
         bool uninit = c.uninitialized();
         if (!uninit) return;
 
-        bool outbound = !connection_context::get(pnc).listener_context_;
-        if (reconnect.set && outbound)
-            connection_context::get(pnc).reconnect.reset(new reconnect_timer(reconnect.value));
+        if (reconnect.set)
+            connection_context::get(pnc).reconnect_context_.reset(new reconnect_context(reconnect.value, co));
         if (container_id.set)
             pn_connection_set_container(pnc, container_id.value.c_str());
         if (virtual_host.set)
@@ -187,7 +187,7 @@ connection_options& connection_options::container_id(const std::string &id) { im
 connection_options& connection_options::virtual_host(const std::string &id) { impl_->virtual_host = id; return *this; }
 connection_options& connection_options::user(const std::string &user) { impl_->user = user; return *this; }
 connection_options& connection_options::password(const std::string &password) { impl_->password = password; return *this; }
-connection_options& connection_options::reconnect(const reconnect_timer &rc) { impl_->reconnect = rc; return *this; }
+connection_options& connection_options::reconnect(reconnect_options &r) { impl_->reconnect = r; return *this; }
 connection_options& connection_options::ssl_client_options(const class ssl_client_options &c) { impl_->ssl_client_options = c; return *this; }
 connection_options& connection_options::ssl_server_options(const class ssl_server_options &c) { impl_->ssl_server_options = c; return *this; }
 connection_options& connection_options::sasl_enabled(bool b) { impl_->sasl_enabled = b; return *this; }
@@ -196,7 +196,7 @@ connection_options& connection_options::sasl_allowed_mechs(const std::string &s)
 connection_options& connection_options::sasl_config_name(const std::string &n) { impl_->sasl_config_name = n; return *this; }
 connection_options& connection_options::sasl_config_path(const std::string &p) { impl_->sasl_config_path = p; return *this; }
 
-void connection_options::apply_unbound(connection& c) const { impl_->apply_unbound(c); }
+void connection_options::apply_unbound(connection& c) const { impl_->apply_unbound(c, *this); }
 void connection_options::apply_bound(connection& c) const { impl_->apply_bound(c); }
 messaging_handler* connection_options::handler() const { return impl_->handler.value; }
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/contexts.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.cpp b/proton-c/bindings/cpp/src/contexts.cpp
index 152828a..812d573 100644
--- a/proton-c/bindings/cpp/src/contexts.cpp
+++ b/proton-c/bindings/cpp/src/contexts.cpp
@@ -20,18 +20,19 @@
  */
 
 #include "contexts.hpp"
+
 #include "msg.hpp"
 #include "proton_bits.hpp"
 
 #include "proton/connection_options.hpp"
 #include "proton/error.hpp"
+#include "proton/reconnect_options.hpp"
 
 #include <proton/connection.h>
 #include <proton/object.h>
 #include <proton/link.h>
 #include <proton/listener.h>
 #include <proton/message.h>
-#include "proton/reconnect_timer.hpp"
 #include <proton/session.h>
 
 #include <typeinfo>
@@ -70,6 +71,10 @@ connection_context::connection_context() :
     container(0), default_session(0), link_gen(0), handler(0), listener_context_(0)
 {}
 
+reconnect_context::reconnect_context(const reconnect_options& ro, const connection_options& co) :
+    reconnect_options_(new reconnect_options(ro)), connection_options_(new connection_options(co)), retries_(0)
+{}
+
 listener_context::listener_context() : listen_handler_(0) {}
 
 connection_context& connection_context::get(pn_connection_t *c) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/include/contexts.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/contexts.hpp b/proton-c/bindings/cpp/src/include/contexts.hpp
index 0c829db..7920d70 100644
--- a/proton-c/bindings/cpp/src/include/contexts.hpp
+++ b/proton-c/bindings/cpp/src/include/contexts.hpp
@@ -35,7 +35,7 @@ struct pn_listener_t;
 namespace proton {
 
 class proton_handler;
-class reconnect_timer;
+class connector;
 
 namespace io {class link_namer;}
 
@@ -77,6 +77,7 @@ class context {
 };
 
 class listener_context;
+class reconnect_context;
 
 // Connection context used by all connections.
 class connection_context : public context {
@@ -90,11 +91,23 @@ class connection_context : public context {
     io::link_namer* link_gen;      // Link name generator.
 
     messaging_handler* handler;
-    internal::pn_unique_ptr<reconnect_timer> reconnect;
+    std::string connected_address_;
+    internal::pn_unique_ptr<reconnect_context> reconnect_context_;
     listener_context* listener_context_;
     work_queue work_queue_;
 };
 
+// This is not a context object on its own, but an optional part of connection
+class reconnect_context {
+  public:
+    reconnect_context(const reconnect_options& ro, const connection_options& co);
+
+    internal::pn_unique_ptr<const reconnect_options> reconnect_options_;
+    internal::pn_unique_ptr<const connection_options> connection_options_;
+    duration delay_;
+    int retries_;
+};
+
 class listener_context : public context {
   public:
     listener_context();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp b/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
index 0aa62a5..804908a 100644
--- a/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
+++ b/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
@@ -64,6 +64,10 @@ struct pn_event_t;
 
 namespace proton {
 
+namespace internal {
+class connector;
+}
+
 class container::impl {
   public:
     impl(container& c, const std::string& id, messaging_handler* = 0);
@@ -99,7 +103,12 @@ class container::impl {
     class container_work_queue;
     pn_listener_t* listen_common_lh(const std::string&);
     pn_connection_t* make_connection_lh(const url& url, const connection_options&);
+    void setup_connection_lh(const url& url, pn_connection_t *pnc);
     void start_connection(const url& url, pn_connection_t* c);
+    void reconnect(pn_connection_t* pnc);
+    duration next_delay(reconnect_context& rc);
+    bool setup_reconnect(pn_connection_t* pnc);
+    void reset_reconnect(pn_connection_t* pnc);
 
     // Event loop to run in each container thread
     void thread();
@@ -136,9 +145,11 @@ class container::impl {
     proton::sender_options sender_options_;
     proton::receiver_options receiver_options_;
     error_condition disconnect_error_;
+    int retries_;
 
     bool auto_stop_;
     bool stopping_;
+    friend class connector;
 };
 
 template <class T>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/include/reconnect_options_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/reconnect_options_impl.hpp b/proton-c/bindings/cpp/src/include/reconnect_options_impl.hpp
new file mode 100644
index 0000000..fc90508
--- /dev/null
+++ b/proton-c/bindings/cpp/src/include/reconnect_options_impl.hpp
@@ -0,0 +1,41 @@
+#ifndef PROTON_CPP_RECONNECT_OPTIONSIMPL_H
+#define PROTON_CPP_RECONNECT_OPTIONSIMPL_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "proton/duration.hpp"
+
+namespace proton {
+
+class reconnect_options::impl {
+  public:
+    impl() : delay(10), delay_multiplier(2.0), max_delay(duration::FOREVER), max_attempts(0) {}
+
+    duration delay;
+    float    delay_multiplier;
+    duration max_delay;
+    int      max_attempts;
+};
+
+}
+
+#endif  /*!PROTON_CPP_RECONNECT_OPTIONSIMPL_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index 9870210..ff4d4bb 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -24,6 +24,7 @@
 #include "proton/function.hpp"
 #include "proton/listener.hpp"
 #include "proton/listen_handler.hpp"
+#include "proton/reconnect_options.hpp"
 #include "proton/url.hpp"
 
 #include "proton/connection.h"
@@ -33,6 +34,7 @@
 
 #include "contexts.hpp"
 #include "messaging_adapter.hpp"
+#include "reconnect_options_impl.hpp"
 #include "proton_bits.hpp"
 
 #include <assert.h>
@@ -152,6 +154,15 @@ void container::impl::remove_work_queue(container::impl::container_work_queue* l
     work_queues_.erase(l);
 }
 
+void container::impl::setup_connection_lh(const url& url, pn_connection_t *pnc) {
+    pn_connection_set_container(pnc, id_.c_str());
+    pn_connection_set_hostname(pnc, url.host().c_str());
+    if (!url.user().empty())
+        pn_connection_set_user(pnc, url.user().c_str());
+    if (!url.password().empty())
+        pn_connection_set_password(pnc, url.password().c_str());
+}
+
 pn_connection_t* container::impl::make_connection_lh(
     const url& url,
     const connection_options& user_opts)
@@ -169,14 +180,10 @@ pn_connection_t* container::impl::make_connection_lh(
     cc.handler = mh;
     cc.work_queue_ = new container::impl::connection_work_queue(*container_.impl_, pnc);
 
-    pn_connection_set_container(pnc, id_.c_str());
-    pn_connection_set_hostname(pnc, url.host().c_str());
-    if (!url.user().empty())
-        pn_connection_set_user(pnc, url.user().c_str());
-    if (!url.password().empty())
-        pn_connection_set_password(pnc, url.password().c_str());
-
+    cc.connected_address_ = url;
+    setup_connection_lh(url, pnc);
     make_wrapper(pnc).open(opts);
+
     return pnc;                 // 1 refcount from pn_connection()
 }
 
@@ -186,6 +193,70 @@ void container::impl::start_connection(const url& url, pn_connection_t *pnc) {
     pn_proactor_connect(proactor_, pnc, caddr); // Takes ownership of pnc
 }
 
+void container::impl::reconnect(pn_connection_t* pnc) {
+    connection_context& cc = connection_context::get(pnc);
+    reconnect_context* rc = cc.reconnect_context_.get();
+
+    // Figure out next connection url to try
+    const proton::url url(cc.connected_address_);
+
+    cc.connected_address_ = url;
+    setup_connection_lh(url, pnc);
+    make_wrapper(pnc).open(*rc->connection_options_);
+    start_connection(cc.connected_address_, pnc);
+    rc->retries_++;
+}
+
+duration container::impl::next_delay(reconnect_context& rc) {
+    // If we've not retried before do it immediately
+    if (rc.retries_==0) return duration(0);
+
+    const reconnect_options::impl& roi = *rc.reconnect_options_->impl_;
+    if (rc.retries_==1) {
+        rc.delay_ = roi.delay;
+    } else {
+        rc.delay_ = std::min(roi.max_delay, rc.delay_ * roi.delay_multiplier);
+    }
+    return rc.delay_;
+}
+
+void container::impl::reset_reconnect(pn_connection_t* pnc) {
+    connection_context& cc = connection_context::get(pnc);
+    reconnect_context* rc = cc.reconnect_context_.get();
+
+    if (rc) rc->retries_ = 0;
+}
+
+bool container::impl::setup_reconnect(pn_connection_t* pnc) {
+    connection_context& cc = connection_context::get(pnc);
+    reconnect_context* rc = cc.reconnect_context_.get();
+
+    // If reconnect not enabled just fail
+    if (!rc) return false;
+
+    const reconnect_options::impl& roi = *rc->reconnect_options_->impl_;
+
+    // If too many reconnect attempts just fail
+    if ( roi.max_attempts != 0 && rc->retries_ >= roi.max_attempts) {
+        pn_transport_t* t = pn_connection_transport(pnc);
+        pn_condition_t* condition = pn_transport_condition(t);
+        pn_condition_format(condition, "proton:io", "Too many reconnect attempts (%d)", rc->retries_);
+        return false;
+    }
+
+    // Recover connection from proactor
+    pn_proactor_release_connection(pnc);
+
+    // Figure out delay till next reconnect
+    duration delay = next_delay(*rc);
+
+    // Schedule reconnect - can do this on container work queue as no one can have the connection
+    // now anyway
+    schedule(delay, make_work(&container::impl::reconnect, this, pnc));
+
+    return true;
+}
+
 returned<connection> container::impl::connect(
     const std::string& addr,
     const proton::connection_options& user_opts)
@@ -417,6 +488,21 @@ bool container::impl::handle(pn_event_t* event) {
 
         return false;
     }
+    case PN_CONNECTION_REMOTE_OPEN: {
+        // This is the only event that we get indicating that the connection succeeded so
+        // it's the only place to reset the reconnection logic.
+        //
+        // Just note we have a connection then process normally
+        pn_connection_t* c = pn_event_connection(event);
+        reset_reconnect(c);
+        break;
+    }
+    case PN_TRANSPORT_CLOSED: {
+        // If reconnect is turned on then handle closed on error here with reconnect attempt
+        pn_connection_t* c = pn_event_connection(event);
+        pn_transport_t* t = pn_event_transport(event);
+        if (pn_condition_is_set(pn_transport_condition(t)) && setup_reconnect(c)) return false;
+    }
     default:
         break;
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/reconnect_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/reconnect_options.cpp b/proton-c/bindings/cpp/src/reconnect_options.cpp
new file mode 100644
index 0000000..ef0d497
--- /dev/null
+++ b/proton-c/bindings/cpp/src/reconnect_options.cpp
@@ -0,0 +1,43 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "proton/reconnect_options.hpp"
+#include "reconnect_options_impl.hpp"
+
+namespace proton {
+
+reconnect_options::reconnect_options() : impl_(new impl()) {}
+reconnect_options::reconnect_options(const reconnect_options& x) : impl_(new impl()) {
+    *this = x;
+}
+reconnect_options::~reconnect_options() {}
+
+reconnect_options& reconnect_options::operator=(const reconnect_options& x) {
+    *impl_ = *x.impl_;
+    return *this;
+}
+
+reconnect_options& reconnect_options::delay(duration d) { impl_->delay = d; return *this; }
+reconnect_options& reconnect_options::delay_multiplier(float f) { impl_->delay_multiplier = f; return *this; }
+reconnect_options& reconnect_options::max_delay(duration d) { impl_->max_delay = d; return *this; }
+reconnect_options& reconnect_options::max_attempts(int i) { impl_->max_attempts = i; return *this; }
+
+} // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/740b9509/proton-c/bindings/cpp/src/reconnect_timer.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/reconnect_timer.cpp b/proton-c/bindings/cpp/src/reconnect_timer.cpp
deleted file mode 100644
index a299b0e..0000000
--- a/proton-c/bindings/cpp/src/reconnect_timer.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "proton/reconnect_timer.hpp"
-#include "proton/error.hpp"
-#include "msg.hpp"
-#include <proton/types.h>
-
-namespace proton {
-
-reconnect_timer::reconnect_timer(uint32_t first, int32_t max, uint32_t increment,
-                                 bool doubling, int32_t max_retries, int32_t timeout) :
-    first_delay_(first), max_delay_(max), increment_(increment), doubling_(doubling),
-    max_retries_(max_retries), timeout_(timeout), retries_(0), next_delay_(-1), timeout_deadline_(0)
-    {}
-
-void reconnect_timer::reset() {
-    retries_ = 0;
-    next_delay_ = 0;
-    timeout_deadline_ = 0;
-}
-
-int reconnect_timer::next_delay(timestamp now) {
-    retries_++;
-    if (max_retries_ >= 0 && retries_ > max_retries_)
-        return -1;
-
-    if (retries_ == 1) {
-        if (timeout_ >= duration(0))
-            timeout_deadline_ = now + timeout_;
-        next_delay_ = first_delay_;
-    } else if (retries_ == 2) {
-        next_delay_ = next_delay_ + increment_;
-    } else {
-        next_delay_ = next_delay_ + ( doubling_ ? next_delay_ : increment_ );
-    }
-    if (timeout_deadline_ != timestamp(0) && now >= timeout_deadline_)
-        return -1;
-    if (max_delay_ >= duration(0) && next_delay_ > max_delay_)
-        next_delay_ = max_delay_;
-    if (timeout_deadline_ != timestamp(0) && (now + next_delay_ > timeout_deadline_))
-        next_delay_ = timeout_deadline_ - now;
-    return next_delay_.milliseconds();
-}
-
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[32/50] qpid-proton git commit: PROTON-1554: Remove thread-safe template, simplify returned<>

Posted by ac...@apache.org.
PROTON-1554: Remove thread-safe template, simplify returned<>

Removed the thread-safe template.

Simplified and documented returned<>: It can *only* be converted to proton
object, and only in a single-threaded application.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/f1ee2681
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/f1ee2681
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/f1ee2681

Branch: refs/heads/go1
Commit: f1ee268163ce80c2b9dc3dcb7ec00151f5c6b486
Parents: ed756d8
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Aug 24 16:49:08 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Sat Aug 26 13:16:50 2017 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp                         |   2 +-
 examples/cpp/client.cpp                         |   1 -
 examples/cpp/connection_options.cpp             |   1 -
 examples/cpp/flow_control.cpp                   |   1 -
 examples/cpp/helloworld.cpp                     |   1 -
 examples/cpp/helloworld_direct.cpp              |   1 -
 examples/cpp/queue_browser.cpp                  |   1 -
 examples/cpp/scheduled_send.cpp                 |   2 +-
 examples/cpp/scheduled_send_03.cpp              |   1 -
 examples/cpp/selected_recv.cpp                  |   1 -
 examples/cpp/server.cpp                         |   1 -
 examples/cpp/service_bus.cpp                    |   2 +-
 examples/cpp/simple_recv.cpp                    |   1 -
 examples/cpp/simple_send.cpp                    |   1 -
 examples/cpp/ssl.cpp                            |   1 -
 examples/cpp/ssl_client_cert.cpp                |   1 -
 proton-c/bindings/cpp/CMakeLists.txt            |   2 +-
 proton-c/bindings/cpp/docs/headers.dox          |   2 -
 .../bindings/cpp/include/proton/connection.hpp  |   5 +-
 .../bindings/cpp/include/proton/container.hpp   |  28 +++-
 .../bindings/cpp/include/proton/delivery.hpp    |   2 +-
 proton-c/bindings/cpp/include/proton/fwd.hpp    |   2 -
 .../cpp/include/proton/internal/object.hpp      |   5 +-
 .../cpp/include/proton/io/connection_driver.hpp |   1 -
 .../bindings/cpp/include/proton/receiver.hpp    |   3 +-
 .../bindings/cpp/include/proton/returned.hpp    |  62 +++++++
 proton-c/bindings/cpp/include/proton/sender.hpp |   1 -
 .../bindings/cpp/include/proton/session.hpp     |   1 -
 .../bindings/cpp/include/proton/thread_safe.hpp | 165 -------------------
 .../bindings/cpp/include/proton/work_queue.hpp  |   6 +-
 .../bindings/cpp/src/connection_driver_test.cpp |   2 +-
 proton-c/bindings/cpp/src/container.cpp         |   1 -
 proton-c/bindings/cpp/src/container_test.cpp    |   1 -
 .../bindings/cpp/src/include/proton_bits.hpp    |   6 +
 .../cpp/src/proactor_container_impl.cpp         |   9 +-
 proton-c/bindings/cpp/src/returned.cpp          |  41 +++++
 proton-c/bindings/cpp/src/thread_safe_test.cpp  | 108 ------------
 tests/tools/apps/cpp/reactor_send.cpp           |   1 -
 38 files changed, 155 insertions(+), 318 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index 198b449..a236bb1 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -35,9 +35,9 @@
 #include <proton/source_options.hpp>
 #include <proton/target.hpp>
 #include <proton/target_options.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/transport.hpp>
+#include <proton/work_queue.hpp>
 
 #include <deque>
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 7139155..81a9a32 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -28,7 +28,6 @@
 #include <proton/messaging_handler.hpp>
 #include <proton/receiver_options.hpp>
 #include <proton/source_options.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/connection_options.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/connection_options.cpp b/examples/cpp/connection_options.cpp
index f718060..a696c6d 100644
--- a/examples/cpp/connection_options.cpp
+++ b/examples/cpp/connection_options.cpp
@@ -24,7 +24,6 @@
 #include <proton/container.hpp>
 #include <proton/default_container.hpp>
 #include <proton/messaging_handler.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/transport.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/flow_control.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/flow_control.cpp b/examples/cpp/flow_control.cpp
index c0b8739..7b1474e 100644
--- a/examples/cpp/flow_control.cpp
+++ b/examples/cpp/flow_control.cpp
@@ -31,7 +31,6 @@
 #include <proton/messaging_handler.hpp>
 #include <proton/receiver_options.hpp>
 #include <proton/sender.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index 4aa5cdd..404d822 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -25,7 +25,6 @@
 #include <proton/delivery.hpp>
 #include <proton/message.hpp>
 #include <proton/messaging_handler.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/url.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index 9331587..f879edd 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -26,7 +26,6 @@
 #include <proton/message.hpp>
 #include <proton/messaging_handler.hpp>
 #include <proton/sender.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/queue_browser.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/queue_browser.cpp b/examples/cpp/queue_browser.cpp
index 583277e..ef158b5 100644
--- a/examples/cpp/queue_browser.cpp
+++ b/examples/cpp/queue_browser.cpp
@@ -27,7 +27,6 @@
 #include <proton/messaging_handler.hpp>
 #include <proton/receiver_options.hpp>
 #include <proton/source_options.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/url.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/scheduled_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/scheduled_send.cpp b/examples/cpp/scheduled_send.cpp
index 2914c44..4c71482 100644
--- a/examples/cpp/scheduled_send.cpp
+++ b/examples/cpp/scheduled_send.cpp
@@ -22,11 +22,11 @@
 #include "options.hpp"
 
 #include <proton/container.hpp>
+#include <proton/connection.hpp>
 #include <proton/default_container.hpp>
 #include <proton/message.hpp>
 #include <proton/messaging_handler.hpp>
 #include <proton/sender.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/work_queue.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/scheduled_send_03.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/scheduled_send_03.cpp b/examples/cpp/scheduled_send_03.cpp
index 008853c..20972e4 100644
--- a/examples/cpp/scheduled_send_03.cpp
+++ b/examples/cpp/scheduled_send_03.cpp
@@ -29,7 +29,6 @@
 #include <proton/message.hpp>
 #include <proton/messaging_handler.hpp>
 #include <proton/sender.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/work_queue.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/selected_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/selected_recv.cpp b/examples/cpp/selected_recv.cpp
index a48ef0e..771fb29 100644
--- a/examples/cpp/selected_recv.cpp
+++ b/examples/cpp/selected_recv.cpp
@@ -26,7 +26,6 @@
 #include <proton/messaging_handler.hpp>
 #include <proton/receiver_options.hpp>
 #include <proton/source_options.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/url.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index 449ce6e..573b3a0 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -27,7 +27,6 @@
 #include <proton/message.hpp>
 #include <proton/message_id.hpp>
 #include <proton/messaging_handler.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/url.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/service_bus.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/service_bus.cpp b/examples/cpp/service_bus.cpp
index 6b57f8d..2c7a682 100644
--- a/examples/cpp/service_bus.cpp
+++ b/examples/cpp/service_bus.cpp
@@ -94,9 +94,9 @@ Done. No more messages.
 #include <proton/sender.hpp>
 #include <proton/sender_options.hpp>
 #include <proton/source_options.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/url.hpp>
+#include <proton/work_queue.hpp>
 
 #include <iostream>
 #include <sstream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index 145eef9..93b4868 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -30,7 +30,6 @@
 #include <proton/message.hpp>
 #include <proton/message_id.hpp>
 #include <proton/messaging_handler.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/value.hpp>
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 358bbec..ebc02cb 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -28,7 +28,6 @@
 #include <proton/message.hpp>
 #include <proton/message_id.hpp>
 #include <proton/messaging_handler.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/types.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/ssl.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl.cpp b/examples/cpp/ssl.cpp
index 166bd61..e24961f 100644
--- a/examples/cpp/ssl.cpp
+++ b/examples/cpp/ssl.cpp
@@ -30,7 +30,6 @@
 #include <proton/message.hpp>
 #include <proton/messaging_handler.hpp>
 #include <proton/ssl.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/transport.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/examples/cpp/ssl_client_cert.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_client_cert.cpp b/examples/cpp/ssl_client_cert.cpp
index 8ca2dc2..c6c7666 100644
--- a/examples/cpp/ssl_client_cert.cpp
+++ b/examples/cpp/ssl_client_cert.cpp
@@ -28,7 +28,6 @@
 #include <proton/messaging_handler.hpp>
 #include <proton/sasl.hpp>
 #include <proton/ssl.hpp>
-#include <proton/thread_safe.hpp>
 #include <proton/tracker.hpp>
 #include <proton/transport.hpp>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 21ff26c..472105a 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -57,6 +57,7 @@ set(qpid-proton-cpp-source
   src/receiver.cpp
   src/receiver_options.cpp
   src/reconnect_timer.cpp
+  src/returned.cpp
   src/sasl.cpp
   src/scalar_base.cpp
   src/sender.cpp
@@ -169,7 +170,6 @@ endmacro(add_cpp_test)
 
 add_cpp_test(codec_test)
 add_cpp_test(connection_driver_test)
-add_cpp_test(thread_safe_test)
 add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
 add_cpp_test(message_test)
 add_cpp_test(map_test)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/docs/headers.dox
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/headers.dox b/proton-c/bindings/cpp/docs/headers.dox
index 0ff7220..7e9d79c 100644
--- a/proton-c/bindings/cpp/docs/headers.dox
+++ b/proton-c/bindings/cpp/docs/headers.dox
@@ -14,7 +14,6 @@
 /// @file proton/duration.hpp Time duration data type
 /// @file proton/error_condition.hpp AMQP error condition
 /// @file proton/error.hpp Base exception type thrown by proton functions
-/// @file proton/event_loop.hpp
 /// @file proton/function.hpp
 /// @file proton/fwd.hpp
 /// @file proton/link.hpp
@@ -42,7 +41,6 @@
 /// @file proton/target.hpp
 /// @file proton/target_options.hpp
 /// @file proton/terminus.hpp
-/// @file proton/thread_safe.hpp
 /// @file proton/timestamp.hpp
 /// @file proton/tracker.hpp
 /// @file proton/transfer.hpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp
index ef75a4e..10ea61b 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -109,10 +109,10 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     PN_CPP_EXTERN receiver open_receiver(const std::string &addr,
                                          const receiver_options &);
 
-    /// @copydoc container::sender_options
+    /// @see proton::container::sender_options()
     PN_CPP_EXTERN class sender_options sender_options() const;
 
-    /// @copydoc container::receiver_options
+    /// @see container::receiver_options()
     PN_CPP_EXTERN class receiver_options receiver_options() const;
 
     /// Return all sessions on this connection.
@@ -142,7 +142,6 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     /// @cond INTERNAL
   friend class internal::factory<connection>;
   friend class container;
-  friend class proton::thread_safe<connection>;
     /// @endcond
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index 859d70c..64e52ad 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -23,7 +23,7 @@
  */
 
 #include "./fwd.hpp"
-#include "./thread_safe.hpp"
+#include "./returned.hpp"
 #include "./types_fwd.hpp"
 
 #include "./internal/config.hpp"
@@ -76,9 +76,14 @@ class PN_CPP_CLASS_EXTERN container {
     /// The handler in the composed options is used to call
     /// proton::messaging_handler::on_connection_open() when the remote peer's
     /// open response is received.
+    ///
+    /// @return A returned<connection>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<connection> connect(const std::string& url, const connection_options &);
 
     /// Connect to `url` and send an open request to the remote peer.
+    /// @return A returned<connection>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<connection> connect(const std::string& url);
 
     /// Start listening on url.
@@ -135,12 +140,16 @@ class PN_CPP_CLASS_EXTERN container {
     PN_CPP_EXTERN void stop();
 
     /// Open a connection and sender for `url`.
+    /// @return A returned<sender>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<sender> open_sender(const std::string &url);
 
     /// Open a connection and sender for `url`.
     ///
     /// Supplied sender options will override the container's
     /// template options.
+    /// @return A returned<sender>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<sender> open_sender(const std::string &url,
                                          const proton::sender_options &o);
 
@@ -148,6 +157,8 @@ class PN_CPP_CLASS_EXTERN container {
     ///
     /// Supplied connection options will override the
     /// container's template options.
+    /// @return A returned<sender>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<sender> open_sender(const std::string &url,
                                          const connection_options &c);
 
@@ -155,11 +166,17 @@ class PN_CPP_CLASS_EXTERN container {
     ///
     /// Supplied sender or connection options will override the
     /// container's template options.
+    ///
+    /// @return A returned<sender>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<sender> open_sender(const std::string &url,
                                          const proton::sender_options &o,
                                          const connection_options &c);
 
     /// Open a connection and receiver for `url`.
+    ///
+    /// @return A returned<receiver>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url);
 
 
@@ -167,6 +184,9 @@ class PN_CPP_CLASS_EXTERN container {
     ///
     /// Supplied receiver options will override the container's
     /// template options.
+    ///
+    /// @return A returned<receiver>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url,
                                              const proton::receiver_options &o);
 
@@ -174,6 +194,9 @@ class PN_CPP_CLASS_EXTERN container {
     ///
     /// Supplied receiver or connection options will override the
     /// container's template options.
+    ///
+    /// @return A returned<receiver>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url,
                                              const connection_options &c);
 
@@ -181,6 +204,9 @@ class PN_CPP_CLASS_EXTERN container {
     ///
     /// Supplied receiver or connection options will override the
     /// container's template options.
+    ///
+    /// @return A returned<receiver>
+    /// @copydetails returned
     PN_CPP_EXTERN returned<receiver> open_receiver(const std::string&url,
                                              const proton::receiver_options &o,
                                              const connection_options &c);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/delivery.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/delivery.hpp b/proton-c/bindings/cpp/include/proton/delivery.hpp
index 7c89f0c..7a38bca 100644
--- a/proton-c/bindings/cpp/include/proton/delivery.hpp
+++ b/proton-c/bindings/cpp/include/proton/delivery.hpp
@@ -46,7 +46,7 @@ class delivery : public transfer {
 
     // XXX ATM the following don't reflect the differing behaviors we
     // get from the different delivery modes. - Deferred
-    
+
     /// Settle with ACCEPTED state.
     PN_CPP_EXTERN void accept();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/fwd.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/fwd.hpp b/proton-c/bindings/cpp/include/proton/fwd.hpp
index 5ade5fd..efbb91b 100644
--- a/proton-c/bindings/cpp/include/proton/fwd.hpp
+++ b/proton-c/bindings/cpp/include/proton/fwd.hpp
@@ -64,8 +64,6 @@ class connection_driver;
 }
 
 template <class T> class returned;
-template <class T> class thread_safe;
-
 }
 
 #endif // PROTON_FWD_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/internal/object.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/internal/object.hpp b/proton-c/bindings/cpp/include/proton/internal/object.hpp
index d492b80..442b09d 100644
--- a/proton-c/bindings/cpp/include/proton/internal/object.hpp
+++ b/proton-c/bindings/cpp/include/proton/internal/object.hpp
@@ -31,7 +31,7 @@
 
 namespace proton {
 
-template <class T> class thread_safe;
+template <class T> class returned;
 
 namespace internal {
 
@@ -101,7 +101,8 @@ template <class T> class object : private comparable<object<T> > {
     friend bool operator==(const object& a, const object& b) { return a.object_ == b.object_; }
     friend bool operator<(const object& a, const object& b) { return a.object_ < b.object_; }
     friend std::ostream& operator<<(std::ostream& o, const object& a) { o << a.object_.inspect(); return o; }
-    template <class U> friend class proton::thread_safe;
+
+  template <class U> friend class proton::returned;
 };
 
 /// Factory class used internally to make wrappers and extract proton objects

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
index 44275bc..f9774ac 100644
--- a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
+++ b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
@@ -179,7 +179,6 @@ PN_CPP_CLASS_EXTERN connection_driver {
     PN_CPP_EXTERN bool dispatch();
 
     /// Get the AMQP connection associated with this connection_driver.
-    /// The event_loop is availabe via proton::thread_safe<connection>(connection())
     PN_CPP_EXTERN proton::connection connection() const;
 
     /// Get the transport associated with this connection_driver.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp b/proton-c/bindings/cpp/include/proton/receiver.hpp
index f92ac96..b995e6f 100644
--- a/proton-c/bindings/cpp/include/proton/receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver.hpp
@@ -76,12 +76,11 @@ PN_CPP_CLASS_EXTERN receiver : public link {
     /// @cond INTERNAL
   friend class internal::factory<receiver>;
   friend class receiver_iterator;
-  friend class thread_safe<receiver>;
     /// @endcond
 };
 
 /// @cond INTERNAL
-    
+
 /// An iterator of receivers.
 class receiver_iterator : public internal::iter_base<receiver, receiver_iterator> {
     explicit receiver_iterator(receiver r, pn_session_t* s = 0) :

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/returned.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/returned.hpp b/proton-c/bindings/cpp/include/proton/returned.hpp
new file mode 100644
index 0000000..25b5c91
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/returned.hpp
@@ -0,0 +1,62 @@
+#ifndef PROTON_RETURNED_HPP
+#define PROTON_RETURNED_HPP
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "./internal/object.hpp"
+#include "./connection.hpp"
+#include "./receiver.hpp"
+#include "./sender.hpp"
+
+/// @file
+/// Return type for container functions
+
+namespace proton {
+
+namespace internal {
+template <class T> class factory;
+}
+
+/// Return type for container functions
+///
+/// @note returned value is *thread-unsafe*.
+/// A single-threaded application can assign the returned<T> value to a plain T.
+/// A multi-threaded application *must* ignore the returned value, as it may already
+/// be invalid by the time the function returns. Multi-threaded applications
+/// can access the value in @ref messaging_handler functions.
+///
+template <class T>
+class returned
+{
+  public:
+    operator T() const;
+
+  private:
+    typename T::pn_type* ptr_;
+    returned(const T&);
+    returned& operator=(const returned&);
+    template <class U> friend class internal::factory;
+};
+
+} // proton
+
+#endif  /*!PROTON_RETURNED_HPP*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp b/proton-c/bindings/cpp/include/proton/sender.hpp
index f8c1e66..b01f21c 100644
--- a/proton-c/bindings/cpp/include/proton/sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender.hpp
@@ -71,7 +71,6 @@ PN_CPP_CLASS_EXTERN sender : public link {
     /// @cond INTERNAL
   friend class internal::factory<sender>;
   friend class sender_iterator;
-  friend class thread_safe<sender>;
     /// @endcond
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/session.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/session.hpp b/proton-c/bindings/cpp/include/proton/session.hpp
index 8d4184b..c66aa05 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -99,7 +99,6 @@ PN_CPP_CLASS_EXTERN session : public internal::object<pn_session_t>, public endp
     /// @cond INTERNAL
   friend class internal::factory<session>;
   friend class session_iterator;
-  friend class thread_safe<session>;
     /// @endcond
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/thread_safe.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/thread_safe.hpp b/proton-c/bindings/cpp/include/proton/thread_safe.hpp
deleted file mode 100644
index 0b38883..0000000
--- a/proton-c/bindings/cpp/include/proton/thread_safe.hpp
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef PROTON_THREAD_SAFE_HPP
-#define PROTON_THREAD_SAFE_HPP
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "./fwd.hpp"
-#include "./internal/config.hpp"
-#include "./connection.hpp"
-#include "./function.hpp"
-#include "./internal/object.hpp"
-#include "./internal/type_traits.hpp"
-#include "./work_queue.hpp"
-
-#include <functional>
-
-namespace proton {
-
-namespace internal {
-template <class T> struct endpoint_traits;
-template<> struct endpoint_traits<connection> {};
-template<> struct endpoint_traits<session> {};
-template<> struct endpoint_traits<link> {};
-template<> struct endpoint_traits<sender> {};
-template<> struct endpoint_traits<receiver> {};
-}
-
-/// **Experimental** - A thread-safe object wrapper.
-///
-/// The proton::object subclasses (proton::connection, proton::sender etc.) are
-/// reference-counted wrappers for C structs. They are not safe for concurrent use,
-/// not even to copy or assign.
-///
-/// A pointer to thread_safe<> can be used from any thread to get the
-/// proton::event_loop for the object's connection. The object will not be
-/// destroyed until the thread_safe<> is deleted. You can use std::shared_ptr,
-/// std::unique_ptr or any other memory management technique to manage the
-/// thread_safe<>.
-///
-/// Use make_thread_safe(), make_shared_thread_safe(), make_unique_thread_safe() to
-/// create a thread_safe<>
-///
-/// @see @ref mt_page
-template <class T>
-class thread_safe : private internal::pn_ptr_base, private internal::endpoint_traits<T> {
-    typedef typename T::pn_type pn_type;
-
-  public:
-    /// @cond INTERNAL
-    static void operator delete(void*) {}
-    /// @endcond
-
-    ~thread_safe() {
-        if (ptr()) {
-            if (!!work_queue().impl_) schedule_work(&work_queue(), &decref, (void*)ptr());
-            else decref(ptr());
-        }
-    }
-
-    /// Get the work queue for this object.
-    class work_queue& work_queue() { return work_queue::get(ptr()); }
-
-    /// Get the thread-unsafe proton object wrapped by this thread_safe<T>
-    T unsafe() { return T(ptr()); }
-
-  private:
-    static thread_safe* create(const T& obj) { return new (obj.pn_object()) thread_safe(); }
-    static void* operator new(size_t, pn_type* p) { return p; }
-    static void operator delete(void*, pn_type*) {}
-    thread_safe() { incref(ptr()); }
-    pn_type* ptr() { return reinterpret_cast<pn_type*>(this); }
-
-
-    // Non-copyable.
-    thread_safe(const thread_safe&);
-    thread_safe& operator=(const thread_safe&);
-
-    /// @cond INTERNAL
-  friend class returned<T>;
-    /// @endcond
-};
-
-// A return value for functions returning a thread_safe<> object.
-//
-// Temporary return value only, you should release() to get a plain pointer or
-// assign to a smart pointer type.
-template <class T>
-class returned : private internal::endpoint_traits<T>
-{
-  public:
-    /// Take ownership
-    explicit returned(thread_safe<T>* p) : ptr_(p) {}
-    /// Create an owned thread_safe<T>
-    explicit returned(const T& obj) : ptr_(thread_safe<T>::create(obj)) {}
-    /// Transfer ownership.
-    /// Use the same "cheat" as std::auto_ptr, calls x.release() even though x is const.
-    returned(const returned& x) : ptr_(const_cast<returned&>(x).release()) {}
-    /// Delete if still owned.
-    ~returned() { if (ptr_) delete ptr_; }
-
-    /// Release ownership.
-    thread_safe<T>* release() const { thread_safe<T>* p = ptr_; ptr_ = 0; return p; }
-
-    /// Get the raw pointer, caller must not delete.
-    thread_safe<T>* get() const { return ptr_; }
-
-    /// Implicit conversion to target, usable only in a safe context.
-    operator T() { return ptr_->unsafe(); }
-
-#if PN_CPP_HAS_SHARED_PTR
-    /// Release to a std::shared_ptr
-    operator std::shared_ptr<thread_safe<T> >() {
-        return std::shared_ptr<thread_safe<T> >(release());
-    }
-#endif
-#if PN_CPP_HAS_UNIQUE_PTR
-    /// Release to a std::unique_ptr
-    operator std::unique_ptr<thread_safe<T> >() {
-        return std::unique_ptr<thread_safe<T> >(release());
-    }
-#endif
-
-  private:
-    void operator=(const returned&);
-    mutable thread_safe<T>* ptr_;
-};
-
-/// Make a thread-safe wrapper for `obj`.
-template <class T> returned<T> make_thread_safe(const T& obj) { return returned<T>(obj); }
-
-#if PN_CPP_HAS_SHARED_PTR
-/// Create a thread-safe shared_ptr to `obj`.
-template <class T> std::shared_ptr<thread_safe<T> > make_shared_thread_safe(const T& obj) {
-    return make_thread_safe(obj);
-}
-#endif
-#if PN_CPP_HAS_UNIQUE_PTR
-/// Create a thread-safe unique_ptr to `obj`.
-template <class T> std::unique_ptr<thread_safe<T> > make_unique_thread_safe(const T& obj) {
-    return make_thread_safe(obj);
-}
-
-#endif
-
-} // proton
-
-#endif // PROTON_THREAD_SAFE_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/include/proton/work_queue.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/work_queue.hpp b/proton-c/bindings/cpp/include/proton/work_queue.hpp
index 844680b..30d8395 100644
--- a/proton-c/bindings/cpp/include/proton/work_queue.hpp
+++ b/proton-c/bindings/cpp/include/proton/work_queue.hpp
@@ -40,10 +40,10 @@ namespace proton {
 /// **Experimental** - A work queue for serial execution.
 ///
 /// Event handler functions associated with a single proton::connection are called in sequence.
-/// The connection's @ref work_queue allows you to "inject" extra @ref work from any thread,
+/// The connection's proton::work_queue allows you to "inject" extra @ref work from any thread,
 /// and have it executed in the same sequence.
 ///
-/// You may also create arbitrary @ref work_queue objects backed by a @ref container that allow
+/// You may also create arbitrary proton::work_queue objects backed by a @ref container that allow
 /// other objects to have their own serialised work queues that can have work injected safely
 /// from other threads. The @ref container ensures that the work is correctly serialised.
 ///
@@ -113,7 +113,6 @@ class PN_CPP_CLASS_EXTERN work_queue {
     /// @cond INTERNAL
   friend class container;
   friend class io::connection_driver;
-  template <class T> friend class thread_safe;
     /// @endcond
 };
 
@@ -347,6 +346,7 @@ void schedule_work(WQ wq, duration dn, F f, A a, B b, C c, D d) {
 #else
 // The C++11 version is *much* simpler and even so more general!
 // These definitions encompass everything in the C++03 section
+
 template <class WQ, class... Rest>
 bool schedule_work(WQ wq, Rest&&... r) {
     return wq->add(std::bind(std::forward<Rest>(r)...));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/connection_driver_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_driver_test.cpp b/proton-c/bindings/cpp/src/connection_driver_test.cpp
index 7fcde46..d174454 100644
--- a/proton-c/bindings/cpp/src/connection_driver_test.cpp
+++ b/proton-c/bindings/cpp/src/connection_driver_test.cpp
@@ -22,6 +22,7 @@
 #include "proton_bits.hpp"
 
 #include "proton/container.hpp"
+#include "proton/connection.hpp"
 #include "proton/io/connection_driver.hpp"
 #include "proton/io/link_namer.hpp"
 #include "proton/link.hpp"
@@ -31,7 +32,6 @@
 #include "proton/sender.hpp"
 #include "proton/sender_options.hpp"
 #include "proton/source_options.hpp"
-#include "proton/thread_safe.hpp"
 #include "proton/transport.hpp"
 #include "proton/types_fwd.hpp"
 #include "proton/uuid.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/container.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container.cpp b/proton-c/bindings/cpp/src/container.cpp
index 35f645c..c82e1a8 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -25,7 +25,6 @@
 #include "proton/error_condition.hpp"
 #include "proton/listen_handler.hpp"
 #include "proton/listener.hpp"
-#include "proton/thread_safe.hpp"
 
 #include "proactor_container_impl.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/container_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_test.cpp b/proton-c/bindings/cpp/src/container_test.cpp
index d210268..498b217 100644
--- a/proton-c/bindings/cpp/src/container_test.cpp
+++ b/proton-c/bindings/cpp/src/container_test.cpp
@@ -26,7 +26,6 @@
 #include "proton/messaging_handler.hpp"
 #include "proton/listener.hpp"
 #include "proton/listen_handler.hpp"
-#include "proton/thread_safe.hpp"
 
 #include <cstdlib>
 #include <ctime>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/include/proton_bits.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/proton_bits.hpp b/proton-c/bindings/cpp/src/include/proton_bits.hpp
index fdd79b5..035ffb7 100644
--- a/proton-c/bindings/cpp/src/include/proton_bits.hpp
+++ b/proton-c/bindings/cpp/src/include/proton_bits.hpp
@@ -124,6 +124,7 @@ class factory {
 public:
     static T wrap(typename wrapped<T>::type* t) { return t; }
     static typename wrapped<T>::type* unwrap(const T& t) { return t.pn_object(); }
+    static returned<T> make_returned(const T& t) { return returned<T>(t); }
 };
 
 template <class T> struct context {};
@@ -150,6 +151,11 @@ U make_wrapper(typename internal::wrapped<U>::type* t) { return internal::factor
 template <class T>
 typename internal::wrapped<T>::type* unwrap(const T& t) { return internal::factory<T>::unwrap(t); }
 
+template <class T>
+returned<T> make_returned(const T& t) {
+    return internal::factory<T>::make_returned(t);
+}
+
 }
 
 #endif // PROTON_BITS_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index b900d6f..1389306 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -24,7 +24,6 @@
 #include "proton/function.hpp"
 #include "proton/listener.hpp"
 #include "proton/listen_handler.hpp"
-#include "proton/thread_safe.hpp"
 #include "proton/url.hpp"
 
 #include "proton/connection.h"
@@ -188,13 +187,13 @@ proton::connection container::impl::connect_common(
     return conn;
 }
 
-proton::returned<proton::connection> container::impl::connect(
+returned<proton::connection> container::impl::connect(
     const std::string& addr,
     const proton::connection_options& user_opts)
 {
     connection conn = connect_common(addr, user_opts);
     GUARD(lock_);
-    return make_thread_safe(conn);
+    return make_returned(conn);
 }
 
 returned<sender> container::impl::open_sender(const std::string &url, const proton::sender_options &o1, const connection_options &o2) {
@@ -203,7 +202,7 @@ returned<sender> container::impl::open_sender(const std::string &url, const prot
     connection conn = connect_common(url, o2);
 
     GUARD(lock_);
-    return make_thread_safe(conn.default_session().open_sender(proton::url(url).path(), lopts));
+    return make_returned(conn.default_session().open_sender(proton::url(url).path(), lopts));
 }
 
 returned<receiver> container::impl::open_receiver(const std::string &url, const proton::receiver_options &o1, const connection_options &o2) {
@@ -212,7 +211,7 @@ returned<receiver> container::impl::open_receiver(const std::string &url, const
     connection conn = connect_common(url, o2);
 
     GUARD(lock_);
-    return make_thread_safe(
+    return make_returned(
         conn.default_session().open_receiver(proton::url(url).path(), lopts));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/returned.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/returned.cpp b/proton-c/bindings/cpp/src/returned.cpp
new file mode 100644
index 0000000..2e1a4b2
--- /dev/null
+++ b/proton-c/bindings/cpp/src/returned.cpp
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "proton_bits.hpp"
+
+#include <proton/returned.hpp>
+#include <proton/connection.hpp>
+#include <proton/sender.hpp>
+#include <proton/receiver.hpp>
+
+namespace proton {
+
+template <class T> returned<T>::returned(const T& t) : ptr_(unwrap(t)) {}
+
+template <class T> returned<T>::operator T() const {
+    return internal::factory<T>::wrap(ptr_);
+}
+
+// Explicit instantiations for allowed types
+
+template class PN_CPP_CLASS_EXTERN returned<connection>;
+template class PN_CPP_CLASS_EXTERN returned<sender>;
+template class PN_CPP_CLASS_EXTERN returned<receiver>;
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/proton-c/bindings/cpp/src/thread_safe_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/thread_safe_test.cpp b/proton-c/bindings/cpp/src/thread_safe_test.cpp
deleted file mode 100644
index 3a72f7f..0000000
--- a/proton-c/bindings/cpp/src/thread_safe_test.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/// Test reference counting for object wrappers, threads_safe<> wrappers and returned<> wrappers.
-///
-
-#include "test_bits.hpp"
-#include "proton_bits.hpp"
-
-#include "proton/thread_safe.hpp"
-#include "proton/io/connection_driver.hpp"
-
-#include <proton/connection.h>
-
-namespace {
-
-using namespace std;
-using namespace proton;
-
-void test_new() {
-    pn_connection_t* c = 0;
-    thread_safe<connection>* p = 0;
-    {
-        io::connection_driver e;
-        c = unwrap(e.connection());
-        int r = pn_refcount(c);
-        ASSERT(r >= 1); // engine may have internal refs (transport, collector).
-        p = make_thread_safe(e.connection()).release();
-        ASSERT_EQUAL(r+1, pn_refcount(c));
-        delete p;
-        ASSERT_EQUAL(r, pn_refcount(c));
-        p = make_thread_safe(e.connection()).release();
-    }
-    ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, thread_safe keeping c alive.
-    delete p;
-
-#if PN_CPP_HAS_SHARED_PTR
-    {
-        std::shared_ptr<thread_safe<connection> > sp;
-        {
-            io::connection_driver e;
-            c = unwrap(e.connection());
-            sp = make_shared_thread_safe(e.connection());
-        }
-        ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, sp keeping c alive.
-    }
-#endif
-#if PN_CPP_HAS_UNIQUE_PTR
-    {
-        std::unique_ptr<thread_safe<connection> > up;
-        {
-            io::connection_driver e;
-            c = unwrap(e.connection());
-            up = make_unique_thread_safe(e.connection());
-        }
-        ASSERT_EQUAL(1, pn_refcount(c)); // Engine gone, sp keeping c alive.
-    }
-#endif
-}
-
-void test_convert() {
-    // Verify refcounts as expected with conversion between proton::object
-    // and thread_safe.
-    connection c;
-    pn_connection_t* pc = 0;
-    {
-        io::connection_driver eng;
-        c = eng.connection();
-        pc = unwrap(c);         // Unwrap in separate scope to avoid confusion from temp values.
-    }
-    {
-        ASSERT_EQUAL(1, pn_refcount(pc));
-        returned<connection> pptr = make_thread_safe(c);
-        ASSERT_EQUAL(2, pn_refcount(pc));
-        returned<connection> pp2 = pptr;
-        ASSERT(!pptr.release()); // Transferred to pp2
-        ASSERT_EQUAL(2, pn_refcount(pc));
-        connection c2 = pp2;        // Transfer and convert to target
-        ASSERT_EQUAL(3, pn_refcount(pc)); // c, c2, thread_safe.
-        ASSERT(c == c2);
-    }
-    ASSERT_EQUAL(1, pn_refcount(pc)); // only c is left
-}
-
-}
-
-int main(int, char**) {
-    int failed = 0;
-    RUN_TEST(failed, test_new());
-    RUN_TEST(failed, test_convert());
-    return failed;
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f1ee2681/tests/tools/apps/cpp/reactor_send.cpp
----------------------------------------------------------------------
diff --git a/tests/tools/apps/cpp/reactor_send.cpp b/tests/tools/apps/cpp/reactor_send.cpp
index 7841a5e..62ac4ce 100644
--- a/tests/tools/apps/cpp/reactor_send.cpp
+++ b/tests/tools/apps/cpp/reactor_send.cpp
@@ -32,7 +32,6 @@
 #include "proton/messaging_handler.hpp"
 #include "proton/receiver_options.hpp"
 #include "proton/sender.hpp"
-#include "proton/thread_safe.hpp"
 #include "proton/tracker.hpp"
 #include "proton/value.hpp"
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[12/50] qpid-proton git commit: PROTON-1533: Fix swig deprecation warnings

Posted by ac...@apache.org.
PROTON-1533: Fix swig deprecation warnings


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/bdac005a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/bdac005a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/bdac005a

Branch: refs/heads/go1
Commit: bdac005a999ffded075eafc61877515edf236b38
Parents: 1b8dae7
Author: Justin Ross <jr...@apache.org>
Authored: Wed Aug 9 09:28:35 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Wed Aug 9 09:28:35 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/node/CMakeLists.txt   |  2 +-
 proton-c/bindings/perl/CMakeLists.txt   |  2 +-
 proton-c/bindings/php/CMakeLists.txt    |  2 +-
 proton-c/bindings/python/CMakeLists.txt |  2 +-
 proton-c/bindings/ruby/CMakeLists.txt   |  2 +-
 tools/cmake/Modules/FindSWIG.cmake      | 43 ++++++++++++++++++++++++++++
 6 files changed, 48 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/proton-c/bindings/node/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/node/CMakeLists.txt b/proton-c/bindings/node/CMakeLists.txt
index 3bea9f7..333cfd7 100644
--- a/proton-c/bindings/node/CMakeLists.txt
+++ b/proton-c/bindings/node/CMakeLists.txt
@@ -57,7 +57,7 @@ include_directories("${NODE_ROOT_DIR}/deps/uv/include")
 set(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
 set(CMAKE_SWIG_FLAGS "-node;-I${CMAKE_CURRENT_SOURCE_DIR}/../../include")
 set_source_files_properties(javascript.i PROPERTIES CPLUSPLUS ON)
-swig_add_module(cproton javascript javascript.i)
+swig_add_library(cproton LANGUAGE javascript SOURCES javascript.i)
 set_target_properties (cproton PROPERTIES LINKER_LANGUAGE CXX)
 list(APPEND SWIG_MODULE_cproton_javascript_EXTRA_DEPS
   ${CMAKE_CURRENT_SOURCE_DIR}/../../proton-c/include/proton/cproton.i

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/proton-c/bindings/perl/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/perl/CMakeLists.txt b/proton-c/bindings/perl/CMakeLists.txt
index 744e812..28f07bf 100644
--- a/proton-c/bindings/perl/CMakeLists.txt
+++ b/proton-c/bindings/perl/CMakeLists.txt
@@ -53,7 +53,7 @@ list(APPEND SWIG_MODULE_cproton_perl_EXTRA_DEPS
     ${CMAKE_SOURCE_DIR}/proton-c/include/proton/cproton.i
     ${PROTON_HEADERS}
 )
-swig_add_module(cproton_perl perl perl.i)
+swig_add_library(cproton_perl LANGUAGE perl SOURCES perl.i)
 set_target_properties(cproton_perl PROPERTIES PREFIX "")
 swig_link_libraries(cproton_perl ${BINDING_DEPS} ${PERL_LIBRARY})
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/proton-c/bindings/php/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/CMakeLists.txt b/proton-c/bindings/php/CMakeLists.txt
index 558269d..696dc38 100644
--- a/proton-c/bindings/php/CMakeLists.txt
+++ b/proton-c/bindings/php/CMakeLists.txt
@@ -34,7 +34,7 @@ list(APPEND SWIG_MODULE_cproton_EXTRA_DEPS
     ${CMAKE_SOURCE_DIR}/proton-c/include/proton/cproton.i
     ${PROTON_HEADERS}
 )
-swig_add_module(cproton php ${CMAKE_CURRENT_SOURCE_DIR}/php.i)
+swig_add_library(cproton LANGUAGE php SOURCES php.i)
 set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "${PHP_INCLUDES}")
 swig_link_libraries(cproton ${BINDING_DEPS})
 # PHP modules must be linked with unresolved symbols as they are presumably satisfied only when loaded by php itself

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/proton-c/bindings/python/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/CMakeLists.txt b/proton-c/bindings/python/CMakeLists.txt
index f8c9241..05c2426 100644
--- a/proton-c/bindings/python/CMakeLists.txt
+++ b/proton-c/bindings/python/CMakeLists.txt
@@ -40,7 +40,7 @@ list(APPEND SWIG_MODULE_cproton_EXTRA_DEPS
     ${PROTON_HEADERS}
 )
 
-swig_add_module(cproton python cproton.i)
+swig_add_library(cproton LANGUAGE python SOURCES cproton.i)
 swig_link_libraries(cproton ${BINDING_DEPS} ${PYTHON_LIBRARIES})
 set_target_properties(${SWIG_MODULE_cproton_REAL_NAME}
     PROPERTIES

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/proton-c/bindings/ruby/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/CMakeLists.txt b/proton-c/bindings/ruby/CMakeLists.txt
index 05c2a72..c14e4f4 100644
--- a/proton-c/bindings/ruby/CMakeLists.txt
+++ b/proton-c/bindings/ruby/CMakeLists.txt
@@ -26,7 +26,7 @@ list(APPEND SWIG_MODULE_cproton-ruby_EXTRA_DEPS
 )
 
 include_directories (${RUBY_INCLUDE_PATH})
-swig_add_module(cproton-ruby ruby ruby.i)
+swig_add_library(cproton-ruby LANGUAGE ruby SOURCES ruby.i)
 swig_link_libraries(cproton-ruby ${BINDING_DEPS} ${RUBY_LIBRARY})
 
 # set a compiler macro to relay the Ruby version to the extension.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdac005a/tools/cmake/Modules/FindSWIG.cmake
----------------------------------------------------------------------
diff --git a/tools/cmake/Modules/FindSWIG.cmake b/tools/cmake/Modules/FindSWIG.cmake
new file mode 100644
index 0000000..979ebab
--- /dev/null
+++ b/tools/cmake/Modules/FindSWIG.cmake
@@ -0,0 +1,43 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+include(${CMAKE_ROOT}/Modules/FindSWIG.cmake)
+
+if (NOT COMMAND swig_add_library)
+  macro (SWIG_ADD_LIBRARY name)
+    set(options "")
+    set(oneValueArgs LANGUAGE TYPE)
+    set(multiValueArgs SOURCES)
+    cmake_parse_arguments(_SAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    if (NOT DEFINED _SAM_LANGUAGE)
+      message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing LANGUAGE argument")
+    endif ()
+
+    if (NOT DEFINED _SAM_SOURCES)
+      message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing SOURCES argument")
+    endif ()
+
+    if (DEFINED _SAM_TYPE AND NOT _SAM_LANGUAGE STREQUAL "module")
+      message(FATAL_ERROR "SWIG_ADD_LIBRARY: This fallback impl of swig_add_library supports the module type only")
+    endif ()
+
+    swig_add_module(${name} ${_SAM_LANGUAGE} ${_SAM_SOURCES})
+  endmacro ()
+endif (NOT COMMAND swig_add_library)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[15/50] qpid-proton git commit: PROTON-1519 ruby: Integer mapping does not work with Ruby 2.4

Posted by ac...@apache.org.
PROTON-1519 ruby: Integer mapping does not work with Ruby 2.4

Ruby < 2.4 had separate Fixnum, Bignum subclasses of Integer. Ruby 2.4 makes
them all the same class, this breaks class-equality type mapping in mapping.rb.

Replaced all uses of Fixnum/Bignum with Integer. Type-mapping now uses
superclass match - type X maps if X is known OR if any superclass of X is known.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b4e1dd08
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b4e1dd08
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b4e1dd08

Branch: refs/heads/go1
Commit: b4e1dd08fa9c19707180d5e5f059ed13600a48d1
Parents: 9eaca61
Author: Jason Frey <fr...@gmail.com>
Authored: Tue Jul 18 11:49:23 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Aug 11 09:51:27 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/codec/data.rb        | 65 ++++++++++----------
 proton-c/bindings/ruby/lib/codec/mapping.rb     |  6 +-
 proton-c/bindings/ruby/lib/core/connection.rb   |  8 +--
 proton-c/bindings/ruby/lib/core/delivery.rb     |  2 +-
 proton-c/bindings/ruby/lib/core/disposition.rb  |  4 +-
 proton-c/bindings/ruby/lib/core/link.rb         | 20 +++---
 proton-c/bindings/ruby/lib/core/message.rb      |  9 ++-
 proton-c/bindings/ruby/lib/core/receiver.rb     |  6 +-
 proton-c/bindings/ruby/lib/core/sasl.rb         |  4 +-
 proton-c/bindings/ruby/lib/core/sender.rb       |  6 +-
 proton-c/bindings/ruby/lib/core/session.rb      | 10 +--
 proton-c/bindings/ruby/lib/core/ssl_domain.rb   |  2 +-
 proton-c/bindings/ruby/lib/core/terminus.rb     | 10 +--
 proton-c/bindings/ruby/lib/core/transport.rb    | 34 +++++-----
 proton-c/bindings/ruby/lib/handler/acking.rb    |  2 +-
 .../ruby/lib/handler/messaging_handler.rb       |  2 +-
 .../bindings/ruby/lib/messenger/messenger.rb    |  2 +-
 proton-c/bindings/ruby/lib/reactor/reactor.rb   |  4 +-
 18 files changed, 97 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/codec/data.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/codec/data.rb b/proton-c/bindings/ruby/lib/codec/data.rb
index 010177d..01799fd 100644
--- a/proton-c/bindings/ruby/lib/codec/data.rb
+++ b/proton-c/bindings/ruby/lib/codec/data.rb
@@ -82,13 +82,12 @@ module Qpid::Proton::Codec
 
     # Creates a new instance with the specified capacity.
     #
-    # @param capacity [Fixnum, Object] The initial capacity or content.
+    # @param capacity [Integer, Object] The initial capacity or content.
     #
     def initialize(capacity = 16)
-      if (!capacity.nil?) &&
-         (capacity.is_a?(Fixnum) ||
-          capacity.is_a?(Bignum))
-        @data = Cproton.pn_data(capacity)
+      # TODO aconway 2017-08-11: error prone, confusion between capacity and Integer content.
+      if capacity.is_a?(Integer)
+        @data = Cproton.pn_data(capacity.to_i)
         @free = true
       else
         @data = capacity
@@ -165,7 +164,7 @@ module Qpid::Proton::Codec
 
     # Returns the numeric type code of the current node.
     #
-    # @return [Fixnum] The current node type.
+    # @return [Integer] The current node type.
     # @return [nil] If there is no current node.
     #
     def type_code
@@ -175,7 +174,7 @@ module Qpid::Proton::Codec
 
     # Return the type object for the current node
     #
-    # @param [Fixnum] The object type.
+    # @param [Integer] The object type.
     #
     # @see #type_code
     #
@@ -319,7 +318,7 @@ module Qpid::Proton::Codec
     # is the descriptor and may be of any type.
     #
     # @param described [Boolean] True if the array is described.
-    # @param element_type [Fixnum] The AMQP type for each element of the array.
+    # @param element_type [Integer] The AMQP type for each element of the array.
     #
     # @example
     #
@@ -489,7 +488,7 @@ module Qpid::Proton::Codec
 
     # Puts an unsigned byte value.
     #
-    # @param value [Fixnum] The unsigned byte value.
+    # @param value [Integer] The unsigned byte value.
     #
     def ubyte=(value)
       check(Cproton.pn_data_put_ubyte(@data, value))
@@ -498,7 +497,7 @@ module Qpid::Proton::Codec
     # If the current node is an unsigned byte, returns its value. Otherwise,
     # it returns 0.
     #
-    # @return [Fixnum] The unsigned byte value.
+    # @return [Integer] The unsigned byte value.
     #
     def ubyte
       Cproton.pn_data_get_ubyte(@data)
@@ -506,7 +505,7 @@ module Qpid::Proton::Codec
 
     # Puts a byte value.
     #
-    # @param value [Fixnum] The byte value.
+    # @param value [Integer] The byte value.
     #
     def byte=(value)
       check(Cproton.pn_data_put_byte(@data, value))
@@ -515,7 +514,7 @@ module Qpid::Proton::Codec
     # If the current node is an byte, returns its value. Otherwise,
     # it returns 0.
     #
-    # @return [Fixnum] The byte value.
+    # @return [Integer] The byte value.
     #
     def byte
       Cproton.pn_data_get_byte(@data)
@@ -523,7 +522,7 @@ module Qpid::Proton::Codec
 
     # Puts an unsigned short value.
     #
-    # @param value [Fixnum] The unsigned short value
+    # @param value [Integer] The unsigned short value
     #
     def ushort=(value)
       check(Cproton.pn_data_put_ushort(@data, value))
@@ -532,7 +531,7 @@ module Qpid::Proton::Codec
     # If the current node is an unsigned short, returns its value. Otherwise,
     # it returns 0.
     #
-    # @return [Fixnum] The unsigned short value.
+    # @return [Integer] The unsigned short value.
     #
     def ushort
       Cproton.pn_data_get_ushort(@data)
@@ -540,7 +539,7 @@ module Qpid::Proton::Codec
 
     # Puts a short value.
     #
-    # @param value [Fixnum] The short value.
+    # @param value [Integer] The short value.
     #
     def short=(value)
       check(Cproton.pn_data_put_short(@data, value))
@@ -549,7 +548,7 @@ module Qpid::Proton::Codec
     # If the current node is a short, returns its value. Otherwise,
     # returns a 0.
     #
-    # @return [Fixnum] The short value.
+    # @return [Integer] The short value.
     #
     def short
       Cproton.pn_data_get_short(@data)
@@ -557,7 +556,7 @@ module Qpid::Proton::Codec
 
     # Puts an unsigned integer value.
     #
-    # @param value [Fixnum] the unsigned integer value
+    # @param value [Integer] the unsigned integer value
     #
     def uint=(value)
       raise TypeError if value.nil?
@@ -568,7 +567,7 @@ module Qpid::Proton::Codec
     # If the current node is an unsigned int, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The unsigned integer value.
+    # @return [Integer] The unsigned integer value.
     #
     def uint
       Cproton.pn_data_get_uint(@data)
@@ -586,7 +585,7 @@ module Qpid::Proton::Codec
     # If the current node is an integer, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The integer value.
+    # @return [Integer] The integer value.
     #
     def int
       Cproton.pn_data_get_int(@data)
@@ -594,7 +593,7 @@ module Qpid::Proton::Codec
 
     # Puts a character value.
     #
-    # @param value [Fixnum] The character value.
+    # @param value [Integer] The character value.
     #
     def char=(value)
       check(Cproton.pn_data_put_char(@data, value))
@@ -603,7 +602,7 @@ module Qpid::Proton::Codec
     # If the current node is a character, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The character value.
+    # @return [Integer] The character value.
     #
     def char
       Cproton.pn_data_get_char(@data)
@@ -611,7 +610,7 @@ module Qpid::Proton::Codec
 
     # Puts an unsigned long value.
     #
-    # @param value [Fixnum] The unsigned long value.
+    # @param value [Integer] The unsigned long value.
     #
     def ulong=(value)
       raise TypeError if value.nil?
@@ -622,7 +621,7 @@ module Qpid::Proton::Codec
     # If the current node is an unsigned long, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The unsigned long value.
+    # @return [Integer] The unsigned long value.
     #
     def ulong
       Cproton.pn_data_get_ulong(@data)
@@ -630,7 +629,7 @@ module Qpid::Proton::Codec
 
     # Puts a long value.
     #
-    # @param value [Fixnum] The long value.
+    # @param value [Integer] The long value.
     #
     def long=(value)
       check(Cproton.pn_data_put_long(@data, value))
@@ -638,14 +637,14 @@ module Qpid::Proton::Codec
 
     # If the current node is a long, returns its value. Otherwise, returns 0.
     #
-    # @return [Fixnum] The long value.
+    # @return [Integer] The long value.
     def long
       Cproton.pn_data_get_long(@data)
     end
 
     # Puts a timestamp value.
     #
-    # @param value [Fixnum] The timestamp value.
+    # @param value [Integer] The timestamp value.
     #
     def timestamp=(value)
       value = value.to_i if (!value.nil? && value.is_a?(Time))
@@ -655,7 +654,7 @@ module Qpid::Proton::Codec
     # If the current node is a timestamp, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The timestamp value.
+    # @return [Integer] The timestamp value.
     #
     def timestamp
       Cproton.pn_data_get_timestamp(@data)
@@ -697,7 +696,7 @@ module Qpid::Proton::Codec
 
     # Puts a decimal32 value.
     #
-    # @param value [Fixnum] The decimal32 value.
+    # @param value [Integer] The decimal32 value.
     #
     def decimal32=(value)
       check(Cproton.pn_data_put_decimal32(@data, value))
@@ -706,7 +705,7 @@ module Qpid::Proton::Codec
     # If the current node is a decimal32, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The decimal32 value.
+    # @return [Integer] The decimal32 value.
     #
     def decimal32
       Cproton.pn_data_get_decimal32(@data)
@@ -714,7 +713,7 @@ module Qpid::Proton::Codec
 
     # Puts a decimal64 value.
     #
-    # @param value [Fixnum] The decimal64 value.
+    # @param value [Integer] The decimal64 value.
     #
     def decimal64=(value)
       check(Cproton.pn_data_put_decimal64(@data, value))
@@ -723,7 +722,7 @@ module Qpid::Proton::Codec
     # If the current node is a decimal64, returns its value. Otherwise,
     # it returns 0.
     #
-    # @return [Fixnum] The decimal64 value.
+    # @return [Integer] The decimal64 value.
     #
     def decimal64
       Cproton.pn_data_get_decimal64(@data)
@@ -731,7 +730,7 @@ module Qpid::Proton::Codec
 
     # Puts a decimal128 value.
     #
-    # @param value [Fixnum] The decimal128 value.
+    # @param value [Integer] The decimal128 value.
     #
     def decimal128=(value)
       raise TypeError, "invalid decimal128 value: #{value}" if value.nil?
@@ -744,7 +743,7 @@ module Qpid::Proton::Codec
     # If the current node is a decimal128, returns its value. Otherwise,
     # returns 0.
     #
-    # @return [Fixnum] The decimal128 value.
+    # @return [Integer] The decimal128 value.
     #
     def decimal128
       value = ""

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/codec/mapping.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/codec/mapping.rb b/proton-c/bindings/ruby/lib/codec/mapping.rb
index f392b9c..421aadc 100644
--- a/proton-c/bindings/ruby/lib/codec/mapping.rb
+++ b/proton-c/bindings/ruby/lib/codec/mapping.rb
@@ -34,7 +34,7 @@ module Qpid::Proton::Codec
     #
     # * code    - the AMQP code for this type
     # * name    - the AMQP name for this type
-    # * klasses - the Ruby classes for this type
+    # * klasses - native Ruby classes that are mapped to this AMQP type
     # * getter  - overrides the get method for the type
     def initialize(code, name, klasses = nil, getter = nil)
 
@@ -77,7 +77,7 @@ module Qpid::Proton::Codec
     end
 
     def self.for_class(klass) # :nodoc:
-      @@by_class[klass]
+      klass and (@@by_class[klass] or self.for_class(klass.superclass))
     end
 
     def self.for_code(code)
@@ -96,7 +96,7 @@ module Qpid::Proton::Codec
   INT        = Mapping.new(Cproton::PN_INT, "int")
   CHAR       = Mapping.new(Cproton::PN_CHAR, "char")
   ULONG      = Mapping.new(Cproton::PN_ULONG, "ulong")
-  LONG       = Mapping.new(Cproton::PN_LONG, "long", RUBY_VERSION < "2.4" ? [Fixnum, Bignum] : [Integer])
+  LONG       = Mapping.new(Cproton::PN_LONG, "long", [Integer])
   TIMESTAMP  = Mapping.new(Cproton::PN_TIMESTAMP, "timestamp", [Date, Time])
   FLOAT      = Mapping.new(Cproton::PN_FLOAT, "float")
   DOUBLE     = Mapping.new(Cproton::PN_DOUBLE, "double", [Float])

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/connection.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/connection.rb b/proton-c/bindings/ruby/lib/core/connection.rb
index 252193d..c1bcaf3 100644
--- a/proton-c/bindings/ruby/lib/core/connection.rb
+++ b/proton-c/bindings/ruby/lib/core/connection.rb
@@ -224,7 +224,7 @@ module Qpid::Proton
     # @see Endpoint#LOCAL_CLOSED
     # @see Endpoint#LOCAL_MASK
     #
-    # @return [Fixnum] The state flags.
+    # @return [Integer] The state flags.
     #
     def state
       Cproton.pn_connection_state(@impl)
@@ -248,7 +248,7 @@ module Qpid::Proton
     # remote flags, then a match occurs if a*any* of the local or remote flags
     # are set, respectively.
     #
-    # @param mask [Fixnum] The state mask to be matched.
+    # @param mask [Integer] The state mask to be matched.
     #
     # @return [Session] The first matching session, or nil if none matched.
     #
@@ -272,7 +272,7 @@ module Qpid::Proton
     # then a match occurs if *any* of the local ore remote flags are set,
     # respectively.
     #
-    # @param mask [Fixnum] The state mask to be matched.
+    # @param mask [Integer] The state mask to be matched.
     #
     # @return [Link] The first matching link, or nil if none matched.
     #
@@ -307,7 +307,7 @@ module Qpid::Proton
 
     # Returns the code for a connection error.
     #
-    # @return [Fixnum] The error code.
+    # @return [Integer] The error code.
     #
     def error
       Cproton.pn_error_code(Cproton.pn_connection_error(@impl))

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/delivery.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/delivery.rb b/proton-c/bindings/ruby/lib/core/delivery.rb
index 5c0b25c..8849840 100644
--- a/proton-c/bindings/ruby/lib/core/delivery.rb
+++ b/proton-c/bindings/ruby/lib/core/delivery.rb
@@ -104,7 +104,7 @@ module Qpid::Proton
 
     # @!attribute [r] pending
     #
-    # @return [Fixnum] Return the amount of pending message data for the
+    # @return [Integer] Return the amount of pending message data for the
     # delivery.
     #
     proton_caller :pending

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/disposition.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/disposition.rb b/proton-c/bindings/ruby/lib/core/disposition.rb
index 20dafd7..daa7069 100644
--- a/proton-c/bindings/ruby/lib/core/disposition.rb
+++ b/proton-c/bindings/ruby/lib/core/disposition.rb
@@ -62,13 +62,13 @@ module Qpid::Proton
 
     # @!attribute section_number
     #
-    # @return [Fixnum] The section number of the disposition.
+    # @return [Integer] The section number of the disposition.
     #
     proton_accessor :section_number
 
     # @!attribute section_offset
     #
-    #  @return [Fixnum] The section offset of the disposition.
+    #  @return [Integer] The section offset of the disposition.
     #
     proton_accessor :section_offset
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/link.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/link.rb b/proton-c/bindings/ruby/lib/core/link.rb
index 86a307a..97f30f6 100644
--- a/proton-c/bindings/ruby/lib/core/link.rb
+++ b/proton-c/bindings/ruby/lib/core/link.rb
@@ -113,7 +113,7 @@ module Qpid::Proton
     # the link until enough credit is obtained from the receiver to send them
     # over the wire. In this case the balance reported will go negative.
     #
-    # @return [Fixnum] The credit balance.
+    # @return [Integer] The credit balance.
     #
     # @see #flow
     #
@@ -130,7 +130,7 @@ module Qpid::Proton
     # @see #queued
     # @see #credit
     #
-    # @return [Fixnum] The remove view of the credit.
+    # @return [Integer] The remove view of the credit.
     #
     proton_caller :remote_credit
 
@@ -142,7 +142,7 @@ module Qpid::Proton
     # deliveries that might be able to be sent if sufficient credit were issued
     # by the receiving link endpoint.
     #
-    # @return [Fixnum] The available deliveries hint.
+    # @return [Integer] The available deliveries hint.
     #
     # @see Sender#offered
     #
@@ -156,7 +156,7 @@ module Qpid::Proton
     # be insufficient credit to send them to the receiver, or they simply may
     # not have yet had a chance to be written to the wire.
     #
-    # @return [Fixnum] The number of queued deliveries.
+    # @return [Integer] The number of queued deliveries.
     #
     # @see #credit
     #
@@ -203,7 +203,7 @@ module Qpid::Proton
     # When invoked on a Receiver, this operation will return and reset the
     # number of credits the sender has released back to it.
     #
-    # @return [Fixnum] The number of credits drained.
+    # @return [Integer] The number of credits drained.
     #
     proton_caller :drained
 
@@ -243,7 +243,7 @@ module Qpid::Proton
 
     # Returns the next link that matches the given state mask.
     #
-    # @param state_mask [Fixnum] The state mask.
+    # @param state_mask [Integer] The state mask.
     #
     # @return [Sender, Receiver] The next link.
     #
@@ -328,7 +328,7 @@ module Qpid::Proton
 
     # Sets the local sender settle mode.
     #
-    # @param mode [Fixnum] The settle mode.
+    # @param mode [Integer] The settle mode.
     #
     # @see #SND_UNSETTLED
     # @see #SND_SETTLED
@@ -340,7 +340,7 @@ module Qpid::Proton
 
     # Returns the local sender settle mode.
     #
-    # @return [Fixnum] The local sender settle mode.
+    # @return [Integer] The local sender settle mode.
     #
     # @see #snd_settle_mode
     #
@@ -350,7 +350,7 @@ module Qpid::Proton
 
     # Sets the local receiver settle mode.
     #
-    # @param mode [Fixnum] The settle mode.
+    # @param mode [Integer] The settle mode.
     #
     # @see #RCV_FIRST
     # @see #RCV_SECOND
@@ -361,7 +361,7 @@ module Qpid::Proton
 
     # Returns the local receiver settle mode.
     #
-    # @return [Fixnum] The local receiver settle mode.
+    # @return [Integer] The local receiver settle mode.
     #
     def rcv_settle_mode
       Cproton.pn_link_rcv_settle_mode(@impl)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/message.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/message.rb b/proton-c/bindings/ruby/lib/core/message.rb
index 53e7092..26a3ae2 100644
--- a/proton-c/bindings/ruby/lib/core/message.rb
+++ b/proton-c/bindings/ruby/lib/core/message.rb
@@ -224,7 +224,7 @@ module Qpid::Proton
     # * priority - the priority value
     #
     def priority=(priority)
-      raise TypeError.new("invalid priority: #{priority}") if priority.nil? || !([Float, Fixnum].include?(priority.class))
+      raise TypeError.new("invalid priority: #{priority}") if not priority.is_a?(Numeric)
       raise RangeError.new("priority out of range: #{priority}") if ((priority > 255) || (priority < 0))
       Cproton.pn_message_set_priority(@impl, priority.floor)
     end
@@ -242,8 +242,8 @@ module Qpid::Proton
     # * time - the time in milliseconds
     #
     def ttl=(time)
-      raise TypeError.new("invalid ttl: #{time}") if time.nil? || !([Float, Fixnum].include?(time.class))
-      raise RangeError.new("time out of range: #{time}") if ((time < 0))
+      raise TypeError.new("invalid ttl: #{time}") if not time.is_a?(Numeric)
+      raise RangeError.new("ttl out of range: #{time}") if ((time.to_i < 0))
       Cproton.pn_message_set_ttl(@impl, time.floor)
     end
 
@@ -275,9 +275,8 @@ module Qpid::Proton
     # * count - the delivery count
     #
     def delivery_count=(count)
-      raise ::ArgumentError.new("invalid count: #{count}") if count.nil? || !([Float, Fixnum].include?(count.class))
+      raise ::ArgumentError.new("invalid count: #{count}") if not count.is_a?(Numeric)
       raise RangeError.new("count out of range: #{count}") if count < 0
-
       Cproton.pn_message_set_delivery_count(@impl, count.floor)
     end
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/receiver.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/receiver.rb b/proton-c/bindings/ruby/lib/core/receiver.rb
index ca7c5e1..2be36ab 100644
--- a/proton-c/bindings/ruby/lib/core/receiver.rb
+++ b/proton-c/bindings/ruby/lib/core/receiver.rb
@@ -58,7 +58,7 @@ module Qpid::Proton
 
     # Grants credit for incoming deliveries.
     #
-    # @param n [Fixnum] The amount to increment the link credit.
+    # @param n [Integer] The amount to increment the link credit.
     #
     def flow(n)
       Cproton.pn_link_flow(@impl, n)
@@ -74,9 +74,9 @@ module Qpid::Proton
     # #receive until nil is returned, or verify that #partial? is false and
     # Delivery#pending is 0.
     #
-    # @param limit [Fixnum] The maximum bytes to receive.
+    # @param limit [Integer] The maximum bytes to receive.
     #
-    # @return [Fixnum, nil] The number of bytes received, or nil if the end of
+    # @return [Integer, nil] The number of bytes received, or nil if the end of
     # the stream was reached.t
     #
     # @see Deliver#pending To see how much buffer space is needed.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/sasl.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/sasl.rb b/proton-c/bindings/ruby/lib/core/sasl.rb
index 7870652..be57044 100644
--- a/proton-c/bindings/ruby/lib/core/sasl.rb
+++ b/proton-c/bindings/ruby/lib/core/sasl.rb
@@ -73,7 +73,7 @@ module Qpid::Proton
 
     # Returns the outcome of the SASL negotiation.
     #
-    # @return [Fixnum] The outcome.
+    # @return [Integer] The outcome.
     #
     def outcome
       outcome = Cprotn.pn_sasl_outcome(@impl)
@@ -83,7 +83,7 @@ module Qpid::Proton
 
     # Set the condition of the SASL negotiation.
     #
-    # @param outcome [Fixnum] The outcome.
+    # @param outcome [Integer] The outcome.
     #
     def done(outcome)
       Cproton.pn_sasl_done(@impl, outcome)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/sender.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/sender.rb b/proton-c/bindings/ruby/lib/core/sender.rb
index 9ddcaa0..a63ff9f 100644
--- a/proton-c/bindings/ruby/lib/core/sender.rb
+++ b/proton-c/bindings/ruby/lib/core/sender.rb
@@ -33,7 +33,7 @@ module Qpid::Proton
 
     # Signals the availability of deliveries.
     #
-    # @param n [Fixnum] The number of deliveries potentially available.
+    # @param n [Integer] The number of deliveries potentially available.
     #
     def offered(n)
       Cproton.pn_link_offered(@impl, n)
@@ -44,7 +44,7 @@ module Qpid::Proton
     # @param object [Object] The content to send.
     # @param tag [Object] The tag
     #
-    # @return [Fixnum] The number of bytes sent.
+    # @return [Integer] The number of bytes sent.
     #
     def send(object, tag = nil)
       if object.respond_to? :proton_send
@@ -58,7 +58,7 @@ module Qpid::Proton
     #
     # @param bytes [Array] The bytes to send.
     #
-    # @return n [Fixnum] The number of bytes sent.
+    # @return n [Integer] The number of bytes sent.
     #
     def stream(bytes)
       Cproton.pn_link_send(@impl, bytes)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/session.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/session.rb b/proton-c/bindings/ruby/lib/core/session.rb
index 2c9c3a1..1dbb9bd 100644
--- a/proton-c/bindings/ruby/lib/core/session.rb
+++ b/proton-c/bindings/ruby/lib/core/session.rb
@@ -41,7 +41,7 @@ module Qpid::Proton
     # negotatied frame size of the transport, it will be rounded up to one full
     # frame.
     #
-    # @return [Fixnum] The incoing capacity of the session, measured in bytes.
+    # @return [Integer] The incoing capacity of the session, measured in bytes.
     #
     proton_accessor :incoming_capacity
 
@@ -50,13 +50,13 @@ module Qpid::Proton
 
     # @!attribute [r] outgoing_bytes
     #
-    # @return [Fixnum] The number of outgoing bytes currently being buffered.
+    # @return [Integer] The number of outgoing bytes currently being buffered.
     #
     proton_caller :outgoing_bytes
 
     # @!attribute [r] incoming_bytes
     #
-    # @return [Fixnum] The number of incomign bytes currently being buffered.
+    # @return [Integer] The number of incomign bytes currently being buffered.
     #
     proton_caller :incoming_bytes
 
@@ -71,7 +71,7 @@ module Qpid::Proton
 
     # @!attribute [r] state
     #
-    # @return [Fixnum] The endpoint state.
+    # @return [Integer] The endpoint state.
     #
     proton_caller :state
 
@@ -104,7 +104,7 @@ module Qpid::Proton
     # When uses with Connection#session_head an application can access all of
     # the session son the connection that match the given state.
     #
-    # @param state_mask [Fixnum] The state mask to match.
+    # @param state_mask [Integer] The state mask to match.
     #
     # @return [Session, nil] The next session if one matches, or nil.
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/ssl_domain.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/ssl_domain.rb b/proton-c/bindings/ruby/lib/core/ssl_domain.rb
index ef3c03c..26b4e9d 100644
--- a/proton-c/bindings/ruby/lib/core/ssl_domain.rb
+++ b/proton-c/bindings/ruby/lib/core/ssl_domain.rb
@@ -123,7 +123,7 @@ module Qpid::Proton
     # call returns. SSL instances created before invoking this method will use
     # the domain's previous setting.
     #
-    # @param verify_mode [Fixnum] The level of validation to apply to the peer.
+    # @param verify_mode [Integer] The level of validation to apply to the peer.
     # @param trusted_CAs [String] The path to a database of trusted CAs that
     #   the server will advertise to the peer client if the server has been
     #   configured to verify its peer.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/terminus.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/terminus.rb b/proton-c/bindings/ruby/lib/core/terminus.rb
index 4bd22d7..fa2d8ab 100644
--- a/proton-c/bindings/ruby/lib/core/terminus.rb
+++ b/proton-c/bindings/ruby/lib/core/terminus.rb
@@ -73,7 +73,7 @@ module Qpid::Proton
 
     # @!attribute type
     #
-    # @return [Fixnum] The terminus type.
+    # @return [Integer] The terminus type.
     #
     # @see SOURCE
     # @see TARGET
@@ -89,7 +89,7 @@ module Qpid::Proton
 
     # @!attribute durability
     #
-    # @return [Fixnum] The durability mode of the terminus.
+    # @return [Integer] The durability mode of the terminus.
     #
     # @see NONDURABLE
     # @see CONFIGURATION
@@ -99,7 +99,7 @@ module Qpid::Proton
 
     # @!attribute expiry_policy
     #
-    # @return [Fixnum] The expiry policy.
+    # @return [Integer] The expiry policy.
     #
     # @see EXPIRE_WITH_LINK
     # @see EXPIRE_WITH_SESSION
@@ -110,7 +110,7 @@ module Qpid::Proton
 
     # @!attribute timeout
     #
-    # @return [Fixnum] The timeout period.
+    # @return [Integer] The timeout period.
     #
     proton_accessor :timeout
 
@@ -122,7 +122,7 @@ module Qpid::Proton
 
     # @!attribute distribution_mode
     #
-    # @return [Fixnum] The distribution mode.
+    # @return [Integer] The distribution mode.
     #
     # @see DIST_MODE_UNSPECIFIED
     # @see DIST_MODE_COPY

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/core/transport.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/transport.rb b/proton-c/bindings/ruby/lib/core/transport.rb
index 9ba5dc8..c3cacc7 100644
--- a/proton-c/bindings/ruby/lib/core/transport.rb
+++ b/proton-c/bindings/ruby/lib/core/transport.rb
@@ -89,37 +89,37 @@ module Qpid::Proton
 
     # @!attribute channel_max
     #
-    # @return [Fixnum] The maximum allowed channel.
+    # @return [Integer] The maximum allowed channel.
     #
     proton_accessor :channel_max
 
     # @!attribute [r] remote_channel_max
     #
-    # @return [Fixnum] The maximum allowed channel of a transport's remote peer.
+    # @return [Integer] The maximum allowed channel of a transport's remote peer.
     #
     proton_caller :remote_channel_max
 
     # @!attribute max_frame_size
     #
-    # @return [Fixnum] The maximum frame size.
+    # @return [Integer] The maximum frame size.
     #
     proton_accessor :max_frame_size
 
     # @!attribute [r] remote_max_frame_size
     #
-    # @return [Fixnum] The maximum frame size of the transport's remote peer.
+    # @return [Integer] The maximum frame size of the transport's remote peer.
     #
     proton_reader :remote_max_frame_size
 
     # @!attribute idle_timeout
     #
-    # @return [Fixnum] The idle timeout.
+    # @return [Integer] The idle timeout.
     #
     proton_accessor :idle_timeout
 
     # @!attribute [r] remote_idle_timeout
     #
-    # @return [Fixnum] The idle timeout for the transport's remote peer.
+    # @return [Integer] The idle timeout for the transport's remote peer.
     #
     proton_accessor :remote_idle_timeout
 
@@ -135,7 +135,7 @@ module Qpid::Proton
     # Calls to #process may alter the value of this value. See #process for
     # more details
     #
-    # @return [Fixnum] The amount of free space for input following the
+    # @return [Integer] The amount of free space for input following the
     # transport's tail pointer.
     #
     proton_caller :capacity
@@ -170,7 +170,7 @@ module Qpid::Proton
     #
     # Calls to #pop may alter the value of this pointer as well.
     #
-    # @return [Fixnum] The number of pending output bytes following the header
+    # @return [Integer] The number of pending output bytes following the header
     # pointer.
     #
     # @raise [TransportError] If any error other than an end of stream occurs.
@@ -188,13 +188,13 @@ module Qpid::Proton
 
     # @!attribute [r] frames_output
     #
-    # @return [Fixnum] The number of frames output by a transport.
+    # @return [Integer] The number of frames output by a transport.
     #
     proton_reader :frames_output
 
     # @!attribute [r] frames_input
     #
-    # @return [Fixnum] The number of frames input by a transport.
+    # @return [Integer] The number of frames input by a transport.
     #
     proton_reader :frames_input
 
@@ -218,7 +218,7 @@ module Qpid::Proton
 
     # Creates a new transport instance.
     #
-    # @param mode [Fixnum] The transport mode, either CLIENT or SERVER
+    # @param mode [Integer] The transport mode, either CLIENT or SERVER
     # @param impl [pn_transport_t] Should not be used.
     #
     # @raise [TransportError] If the mode is invalid.
@@ -268,7 +268,7 @@ module Qpid::Proton
 
     # Updates the transports trace flags.
     #
-    # @param level [Fixnum] The trace level.
+    # @param level [Integer] The trace level.
     #
     # @see TRACE_OFF
     # @see TRACE_RAW
@@ -302,7 +302,7 @@ module Qpid::Proton
     #
     # @param data [String] The bytes to be pushed.
     #
-    # @return [Fixnum] The number of bytes pushed.
+    # @return [Integer] The number of bytes pushed.
     #
     def push(data)
       Cproton.pn_transport_push(@impl, data, data.length)
@@ -315,7 +315,7 @@ module Qpid::Proton
     # pointer. It may also change the value for #tail, as well as the amount of
     # free space reported by #capacity.
     #
-    # @param size [Fixnum] The number of bytes to process.
+    # @param size [Integer] The number of bytes to process.
     #
     # @raise [TransportError] If an error occurs.
     #
@@ -335,7 +335,7 @@ module Qpid::Proton
 
     # Returns the specified number of bytes from the transport's buffers.
     #
-    # @param size [Fixnum] The number of bytes to return.
+    # @param size [Integer] The number of bytes to return.
     #
     # @return [String] The data peeked.
     #
@@ -351,7 +351,7 @@ module Qpid::Proton
     # Removes the specified number of bytes from the pending output queue
     # following the transport's head pointer.
     #
-    # @param size [Fixnum] The number of bytes to remove.
+    # @param size [Integer] The number of bytes to remove.
     #
     def pop(size)
       Cproton.pn_transport_pop(@impl, size)
@@ -378,7 +378,7 @@ module Qpid::Proton
     #
     # @param now [Time] The timestamp.
     #
-    # @return [Fixnum] If non-zero, the expiration time of the next pending
+    # @return [Integer] If non-zero, the expiration time of the next pending
     #   timer event for the transport. The caller must invoke #tick again at
     #   least once at or before this deadline occurs.
     #

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/handler/acking.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/acking.rb b/proton-c/bindings/ruby/lib/handler/acking.rb
index 2c94cfe..1c4f69d 100644
--- a/proton-c/bindings/ruby/lib/handler/acking.rb
+++ b/proton-c/bindings/ruby/lib/handler/acking.rb
@@ -58,7 +58,7 @@ module Qpid::Proton::Handler
     # is specified.
     #
     # @param delivery [Qpid::Proton::Delivery] The delivery.
-    # @param state [Fixnum] The delivery state.
+    # @param state [Integer] The delivery state.
     #
     def settle(delivery, state = nil)
       delivery.update(state) unless state.nil?

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/handler/messaging_handler.rb b/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
index b4a0bcf..3278452 100644
--- a/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
+++ b/proton-c/bindings/ruby/lib/handler/messaging_handler.rb
@@ -29,7 +29,7 @@ module Qpid::Proton::Handler
 
     # Creates a new instance.
     #
-    # @param [Fixnum] prefetch
+    # @param [Integer] prefetch
     # @param [Boolean] auto_accept
     # @param [Boolean] auto_settle
     # @param [Boolean] peer_close_is_error

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/messenger/messenger.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/messenger/messenger.rb b/proton-c/bindings/ruby/lib/messenger/messenger.rb
index 70a01de..79a9bcf 100644
--- a/proton-c/bindings/ruby/lib/messenger/messenger.rb
+++ b/proton-c/bindings/ruby/lib/messenger/messenger.rb
@@ -694,7 +694,7 @@ module Qpid::Proton::Messenger
     end
 
     def valid_window?(window)
-      !window.nil? && [Float, Fixnum].include?(window.class)
+      !window.nil? && window.is_a?(Numeric)
     end
 
   end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e1dd08/proton-c/bindings/ruby/lib/reactor/reactor.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/reactor/reactor.rb b/proton-c/bindings/ruby/lib/reactor/reactor.rb
index a0ff7e0..a84a716 100644
--- a/proton-c/bindings/ruby/lib/reactor/reactor.rb
+++ b/proton-c/bindings/ruby/lib/reactor/reactor.rb
@@ -89,7 +89,7 @@ module Qpid::Proton::Reactor
 
     # Returns the timeout period.
     #
-    # @return [Fixnum] The timeout period, in seconds.
+    # @return [Integer] The timeout period, in seconds.
     #
     def timeout
       millis_to_timeout(Cproton.pn_reactor_get_timeout(@impl))
@@ -97,7 +97,7 @@ module Qpid::Proton::Reactor
 
     # Sets the timeout period.
     #
-    # @param timeout [Fixnum] The timeout, in seconds.
+    # @param timeout [Integer] The timeout, in seconds.
     #
     def timeout=(timeout)
       Cproton.pn_reactor_set_timeout(@impl, timeout_to_millis(timeout))


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[37/50] qpid-proton git commit: PROTON-1543: Various improvements to the C++ API docs

Posted by ac...@apache.org.
PROTON-1543: Various improvements to the C++ API docs

 - Fix see-alsos in source and target options
 - Extend docs for connection options; fill in missing docs related to
   work queues
 - Fix references to multithread examples
 - Some copyedits


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/540622ed
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/540622ed
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/540622ed

Branch: refs/heads/go1
Commit: 540622ed46eab6cda148043682f4fa11f0f42367
Parents: 38b27b5
Author: Justin Ross <jr...@apache.org>
Authored: Tue Aug 29 19:56:37 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Tue Aug 29 19:56:37 2017 -0700

----------------------------------------------------------------------
 examples/cpp/README.dox                         | 22 ++++---
 proton-c/bindings/cpp/docs/mt.md                | 21 +++----
 .../bindings/cpp/include/proton/connection.hpp  | 23 ++++----
 .../cpp/include/proton/connection_options.hpp   | 59 +++++++++++--------
 .../cpp/include/proton/source_options.hpp       |  3 +-
 .../cpp/include/proton/target_options.hpp       |  3 +-
 .../bindings/cpp/include/proton/work_queue.hpp  | 60 +++++++++++++-------
 7 files changed, 111 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/examples/cpp/README.dox
----------------------------------------------------------------------
diff --git a/examples/cpp/README.dox b/examples/cpp/README.dox
index 551efde..b475b2a 100644
--- a/examples/cpp/README.dox
+++ b/examples/cpp/README.dox
@@ -7,17 +7,9 @@
 //
 // then open proton-c/bindings/cpp/docs/html/tutorial.html in your browser.
 
-// DEVELOPER NOTE: if you add or modify examples, please add/update a short
+// DEVELOPER NOTE: If you add or modify examples, please add/update a short
 // description below and (if appropriate) extend/update tutorial.dox.
 
-/** example sub directory
-
-The example sub-directory has utilities classes to make the example simpler,
-these classes are not directly related to the use of proton so are in a separate
-`example` directory and namespace.
-
-*/
-
 /** @example helloworld.cpp
 
 Connects to a broker on 127.0.0.1:5672, establishes a subscription
@@ -139,12 +131,18 @@ Also provides some general notes on Service Bus usage.
 
 */
 
-/** @example send_recv_mt.cpp
+/** @example multithreaded_client.cpp
 
-A multi-threaded sender and receiver.
+A multithreaded sender and receiver.
 
 __Requires C++11__
 
 */
 
-*/
\ No newline at end of file
+/** @example multithreaded_client_flow_control.cpp
+
+A multithreaded sender and receiver enhanced for flow control.
+
+__Requires C++11__
+
+*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/docs/mt.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/mt.md b/proton-c/bindings/cpp/docs/mt.md
index e316f81..4e908bd 100644
--- a/proton-c/bindings/cpp/docs/mt.md
+++ b/proton-c/bindings/cpp/docs/mt.md
@@ -1,6 +1,7 @@
 # Multithreaded Proton applications {#mt_page}
 
-For examples see @ref broker.cpp and @ref send_recv_mt.cpp
+For examples see @ref broker.cpp, @ref multithreaded_client.cpp, and
+@ref multithreaded_client_flow_control.cpp.
 
 Most classes in namespace @ref proton are not thread-safe. Objects
 belonging to a single connection (`proton::connection`,
@@ -12,17 +13,17 @@ A multithreaded container calls event-handling functions for each
 connection *sequentially* but can process *different* connections
 concurrently in different threads. If you use a separate
 `proton::messaging_handler` for each connection, then event-handling
-functions can can use their parameters and the handler's own data
+functions can use their parameters and the handler's own data
 members without locks. The handler functions will never be called
 concurrently. You can set the handlers for each connection using
 `proton::container::connect()` and `proton::container::listen()`.
 
-The example @ref broker.cpp is a broker that can be run in single or
-multi-threaded mode.  It creates a new handler for each incoming
-connection to manage the state of that connection's `proton::sender` and
-`proton::receiver` links. The handler needs no lock because it only deals with
-state in the context of one connection.
-
-The example @ref send_recv_mt.cpp shows how application threads can
-communicate safely with proton handler threads.
+The example @ref broker.cpp is a broker that can be run in single- or
+multithreaded mode.  It creates a new handler for each incoming
+connection to manage the state of that connection's `proton::sender`
+and `proton::receiver` links. The handler needs no lock because it
+only deals with state in the context of one connection.
 
+The examples @ref multithreaded_client.cpp and @ref
+multithreaded_client_flow_control.cpp show how application threads can
+communicate safely with Proton handler threads.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/include/proton/connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp
index 10ea61b..7888508 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -57,7 +57,7 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     ///
     /// @throw proton::error if this connection is not managed by a
     /// container
-    PN_CPP_EXTERN class container &container() const;
+    PN_CPP_EXTERN class container& container() const;
 
     /// Get the work_queue for the connection.
     PN_CPP_EXTERN class work_queue& work_queue() const;
@@ -81,7 +81,7 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     PN_CPP_EXTERN void open();
 
     /// @copydoc open
-    PN_CPP_EXTERN void open(const connection_options &);
+    PN_CPP_EXTERN void open(const connection_options&);
 
     PN_CPP_EXTERN void close();
     PN_CPP_EXTERN void close(const error_condition&);
@@ -90,24 +90,24 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     PN_CPP_EXTERN session open_session();
 
     /// @copydoc open_session
-    PN_CPP_EXTERN session open_session(const session_options &);
+    PN_CPP_EXTERN session open_session(const session_options&);
 
     /// Get the default session.  A default session is created on the
     /// first call and reused for the lifetime of the connection.
     PN_CPP_EXTERN session default_session();
 
     /// Open a sender for `addr` on default_session().
-    PN_CPP_EXTERN sender open_sender(const std::string &addr);
+    PN_CPP_EXTERN sender open_sender(const std::string& addr);
 
     /// @copydoc open_sender
-    PN_CPP_EXTERN sender open_sender(const std::string &addr, const sender_options &);
+    PN_CPP_EXTERN sender open_sender(const std::string& addr, const sender_options&);
 
     /// Open a receiver for `addr` on default_session().
-    PN_CPP_EXTERN receiver open_receiver(const std::string &addr);
+    PN_CPP_EXTERN receiver open_receiver(const std::string& addr);
 
     /// @copydoc open_receiver
-    PN_CPP_EXTERN receiver open_receiver(const std::string &addr,
-                                         const receiver_options &);
+    PN_CPP_EXTERN receiver open_receiver(const std::string& addr,
+                                         const receiver_options&);
 
     /// @see proton::container::sender_options()
     PN_CPP_EXTERN class sender_options sender_options() const;
@@ -124,17 +124,18 @@ PN_CPP_CLASS_EXTERN connection : public internal::object<pn_connection_t>, publi
     /// Return all senders on this connection.
     PN_CPP_EXTERN sender_range senders() const;
 
-    /// Get the maximum frame size.
+    /// Get the maximum frame size allowed by the remote peer.
     ///
     /// @see @ref connection_options::max_frame_size
     PN_CPP_EXTERN uint32_t max_frame_size() const;
 
-    /// Get the maximum number of open sessions.
+    /// Get the maximum number of open sessions allowed by the remote
+    /// peer.
     ///
     /// @see @ref connection_options::max_sessions
     PN_CPP_EXTERN uint16_t max_sessions() const;
 
-    /// Get the idle timeout.
+    /// Get the idle timeout set by the remote peer.
     ///
     /// @see @ref connection_options::idle_timeout
     PN_CPP_EXTERN uint32_t idle_timeout() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index 2769a7e..c0ff457 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -79,54 +79,63 @@ class connection_options {
 
     /// Set a connection handler.
     ///
-    /// The handler must not be deleted until messaging_handler::on_transport_close() is called.
+    /// The handler must not be deleted until
+    /// messaging_handler::on_transport_close() is called.
     PN_CPP_EXTERN connection_options& handler(class messaging_handler&);
 
-    /// Set the maximum frame size.
+    /// Set the maximum frame size.  It is unlimited by default.
     PN_CPP_EXTERN connection_options& max_frame_size(uint32_t max);
 
-    /// Set the maximum number of open sessions.
+    /// Set the maximum number of open sessions.  The default value is 32767.
     PN_CPP_EXTERN connection_options& max_sessions(uint16_t max);
 
-    // XXX document relationship to heartbeat interval
-    /// Set the idle timeout.
+    /// Set the idle timeout.  By default, none is set.
+    ///
+    /// If set, the local peer will disconnect if it does not receive
+    /// AMQP frames before the timeout expires.  This serves as
+    /// "heartbeating", a way to detect dead peers even in the
+    /// presence of a live TCP connection.
     PN_CPP_EXTERN connection_options& idle_timeout(duration);
 
     /// Set the container ID.
-    PN_CPP_EXTERN connection_options& container_id(const std::string &id);
+    PN_CPP_EXTERN connection_options& container_id(const std::string& id);
 
     /// Set the virtual host name for the connection. If making a
     /// client connection by SSL/TLS, this name is also used for
     /// certificate verification and Server Name Indication.  For
     /// client connections, it defaults to the host name used to set
-    /// up the connection.  It is not set by default for server
-    /// connections.
-    PN_CPP_EXTERN connection_options& virtual_host(const std::string &name);
+    /// up the connection.  For server connections, it is not set by
+    /// default.
+    PN_CPP_EXTERN connection_options& virtual_host(const std::string& name);
 
-    /// Set the user name used to authenticate the connection.
+    /// Set the user name used to authenticate the connection.  It is
+    /// unset by default.
     ///
-    /// This will override any user name that is specified in the url
-    /// used for container::connect.
-    /// It will be ignored if the connection is created by container::listen as
-    /// a listening connection's identity is provided by the remote client.
-    PN_CPP_EXTERN connection_options& user(const std::string& user);
-
-    /// Set the password used to authenticate the connection
-    /// It will be ignored if the connection is created by container::listen.
-    PN_CPP_EXTERN connection_options& password(const std::string& pass);
+    /// This value overrides any user name that is specified in the
+    /// URL used for container::connect.  It is ignored if the
+    /// connection is created by container::listen because a listening
+    /// connection's identity is provided by the remote client.
+    PN_CPP_EXTERN connection_options& user(const std::string&);
+
+    /// Set the password used to authenticate the connection.  It has
+    /// no default value.
+    ///
+    /// This value is ignored if the connection is created by
+    /// container::listen.
+    PN_CPP_EXTERN connection_options& password(const std::string&);
 
     /// @cond INTERNAL
     // XXX settle questions about reconnect_timer - consider simply
     // reconnect_options and making reconnect_timer internal
     /// **Experimental**
-    PN_CPP_EXTERN connection_options& reconnect(const reconnect_timer &);
+    PN_CPP_EXTERN connection_options& reconnect(const reconnect_timer&);
     /// @endcond
 
     /// Set SSL client options.
-    PN_CPP_EXTERN connection_options& ssl_client_options(const class ssl_client_options &);
+    PN_CPP_EXTERN connection_options& ssl_client_options(const class ssl_client_options&);
 
     /// Set SSL server options.
-    PN_CPP_EXTERN connection_options& ssl_server_options(const class ssl_server_options &);
+    PN_CPP_EXTERN connection_options& ssl_server_options(const class ssl_server_options&);
 
     /// Enable or disable SASL.
     PN_CPP_EXTERN connection_options& sasl_enabled(bool);
@@ -137,13 +146,13 @@ class connection_options {
     PN_CPP_EXTERN connection_options& sasl_allow_insecure_mechs(bool);
 
     /// Specify the allowed mechanisms for use on the connection.
-    PN_CPP_EXTERN connection_options& sasl_allowed_mechs(const std::string &);
+    PN_CPP_EXTERN connection_options& sasl_allowed_mechs(const std::string&);
 
     /// **Experimental** - Set the SASL configuration name.
-    PN_CPP_EXTERN connection_options& sasl_config_name(const std::string &);
+    PN_CPP_EXTERN connection_options& sasl_config_name(const std::string&);
 
     /// **Experimental** - Set the SASL configuration path.
-    PN_CPP_EXTERN connection_options& sasl_config_path(const std::string &);
+    PN_CPP_EXTERN connection_options& sasl_config_path(const std::string&);
 
     /// Update option values from values set in other.
     PN_CPP_EXTERN connection_options& update(const connection_options& other);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/include/proton/source_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/source_options.hpp b/proton-c/bindings/cpp/include/proton/source_options.hpp
index f7dde48..19e3cdf 100644
--- a/proton-c/bindings/cpp/include/proton/source_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/source_options.hpp
@@ -33,7 +33,8 @@ namespace proton {
 
 /// Options for creating a source node for a sender or receiver.
 ///
-/// Options can be "chained" (@see proton::connection_options).
+/// Options can be "chained".  For more information see @ref
+/// proton::connection_options.
 ///
 /// Normal value semantics: copy or assign creates a separate copy of
 /// the options.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/include/proton/target_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/target_options.hpp b/proton-c/bindings/cpp/include/proton/target_options.hpp
index 547dbbe..0f2245b 100644
--- a/proton-c/bindings/cpp/include/proton/target_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/target_options.hpp
@@ -33,7 +33,8 @@ namespace proton {
 
 /// Options for creating a target node for a sender or receiver.
 ///
-/// Options can be "chained" (see proton::connection_options).
+/// Options can be "chained".  For more information see @ref
+/// proton::connection_options.
 ///
 /// Normal value semantics: copy or assign creates a separate copy of
 /// the options.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540622ed/proton-c/bindings/cpp/include/proton/work_queue.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/work_queue.hpp b/proton-c/bindings/cpp/include/proton/work_queue.hpp
index 30d8395..2d728fd 100644
--- a/proton-c/bindings/cpp/include/proton/work_queue.hpp
+++ b/proton-c/bindings/cpp/include/proton/work_queue.hpp
@@ -37,31 +37,27 @@ struct pn_link_t;
 
 namespace proton {
 
-/// **Experimental** - A work queue for serial execution.
-///
-/// Event handler functions associated with a single proton::connection are called in sequence.
-/// The connection's proton::work_queue allows you to "inject" extra @ref work from any thread,
-/// and have it executed in the same sequence.
-///
-/// You may also create arbitrary proton::work_queue objects backed by a @ref container that allow
-/// other objects to have their own serialised work queues that can have work injected safely
-/// from other threads. The @ref container ensures that the work is correctly serialised.
-///
-/// The @ref work class represents the work to be queued and can be created from a function
-/// that takes no parameters and returns no value.
-///
-
+/// **Experimental** - Work to be queued on a @ref work_queue.  It can
+/// be created from a function that takes no parameters and returns no
+/// value.
 class work {
   public:
 #if PN_CPP_HAS_STD_FUNCTION
+    /// **Experimental**
     work(void_function0& f): item_( [&f]() { f(); }) {}
+
+    /// **Experimental** - Construct a unit of work from a
+    /// std::function.
     template <class T>
     work(T f): item_(f) {}
 
+    /// **Experimental**
     void operator()() { item_(); }
 #else
+    /// **Experimetnal**
     work(void_function0& f): item_(&f) {}
 
+    /// **Experimetnal**
     void operator()() { (*item_)(); }
 #endif
     ~work() {}
@@ -75,28 +71,48 @@ class work {
 #endif
 };
 
+/// **Experimental** - A work queue for serial execution.
+///
+/// Event handler functions associated with a single
+/// proton::connection are called in sequence.  The connection's
+/// proton::work_queue allows you to "inject" extra @ref work from any
+/// thread, and have it executed in the same sequence.
+///
+/// You may also create arbitrary proton::work_queue objects backed by
+/// a @ref container that allow other objects to have their own
+/// serialised work queues that can have work injected safely from
+/// other threads. The @ref container ensures that the work is
+/// correctly serialised.
+///
+/// The @ref work class represents the work to be queued and can be
+/// created from a function that takes no parameters and returns no
+/// value.
 class PN_CPP_CLASS_EXTERN work_queue {
-    /// @cond internal
+    /// @cond INTERNAL
     class impl;
     work_queue& operator=(impl* i);
     /// @endcond
 
   public:
-    /// Create work_queue
+    /// **Experimental** - Create a work_queue.
     PN_CPP_EXTERN work_queue();
+
+    /// **Experimental** - Create a work_queue backed by `container`.
     PN_CPP_EXTERN work_queue(container&);
 
     PN_CPP_EXTERN ~work_queue();
 
-    /// Add work to the work queue: f() will be called serialised with other work in the queue:
-    /// deferred and possibly in another thread.
+    /// **Experimental** - Add work to the work queue: f() will be
+    /// called serialised with other work in the queue: deferred and
+    /// possibly in another thread.
     ///
     /// @return true if f() has or will be called, false if the event_loop is ended
     /// or f() cannot be injected for any other reason.
     PN_CPP_EXTERN bool add(work f);
 
-    /// Add work to the work queue after duration: f() will be called after the duration
-    /// serialised with other work in the queue: possibly in another thread.
+    /// **Experimental** - Add work to the work queue after duration:
+    /// f() will be called after the duration serialised with other
+    /// work in the queue: possibly in another thread.
     ///
     /// The scheduled execution is "best effort" and it is possible that after the elapsed duration
     /// the work will not be able to be injected into the serialised context - there will be no
@@ -347,20 +363,24 @@ void schedule_work(WQ wq, duration dn, F f, A a, B b, C c, D d) {
 // The C++11 version is *much* simpler and even so more general!
 // These definitions encompass everything in the C++03 section
 
+/// **Experimental**
 template <class WQ, class... Rest>
 bool schedule_work(WQ wq, Rest&&... r) {
     return wq->add(std::bind(std::forward<Rest>(r)...));
 }
 
+/// **Experimental**
 template <class WQ, class... Rest>
 void schedule_work(WQ wq, duration d, Rest&&... r) {
     wq->schedule(d, std::bind(std::forward<Rest>(r)...));
 }
 
+/// **Experimental**
 template <class... Rest>
 work make_work(Rest&&... r) {
     return std::bind(std::forward<Rest>(r)...);
 }
+
 #endif
 
 } // proton


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[10/50] qpid-proton git commit: PROTON-1530: delegate unhandled events

Posted by ac...@apache.org.
PROTON-1530: delegate unhandled events


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/fb439633
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/fb439633
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/fb439633

Branch: refs/heads/go1
Commit: fb439633ea999ecd2f0967bc94c03c276a2820c4
Parents: ca88f34
Author: Gordon Sim <gs...@redhat.com>
Authored: Fri Aug 4 18:10:45 2017 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Fri Aug 4 18:10:45 2017 +0100

----------------------------------------------------------------------
 proton-c/bindings/python/proton/reactor.py | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fb439633/proton-c/bindings/python/proton/reactor.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py
index 5f6d8cb..4beede0 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -864,6 +864,11 @@ class Container(Reactor):
                     if hasattr(event.delivery, "transaction"):
                         event.transaction = event.delivery.transaction
                         event.delivery.transaction.handle_outcome(event)
+
+                def on_unhandled(self, method, event):
+                    if handler:
+                        event.dispatch(handler)
+
             context._txn_ctrl = self.create_sender(context, None, name='txn-ctrl', handler=InternalTransactionHandler())
             context._txn_ctrl.target.type = Terminus.COORDINATOR
             context._txn_ctrl.target.capabilities.put_object(symbol(u'amqp:local-transactions'))


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[36/50] qpid-proton git commit: PROTON-1557: c++ fix race conditions in proactor_container_impl

Posted by ac...@apache.org.
PROTON-1557: c++ fix race conditions in proactor_container_impl

Fixed:
- using of option member variables outside of guard.
- reference couting of pn_ objects outside of handler after pn_proactor_connect
- creating returned<> wrappers from raw pointers.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/38b27b50
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/38b27b50
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/38b27b50

Branch: refs/heads/go1
Commit: 38b27b5035658454be9ddc2bae80c589576960f2
Parents: bd10259
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Aug 29 18:08:01 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Aug 29 18:29:45 2017 -0400

----------------------------------------------------------------------
 examples/cpp/multithreaded_client.cpp           | 30 ++++----
 .../cpp/multithreaded_client_flow_control.cpp   | 35 +++++----
 .../bindings/cpp/include/proton/returned.hpp    | 15 ++--
 .../cpp/src/include/proactor_container_impl.hpp |  3 +-
 .../bindings/cpp/src/include/proton_bits.hpp    | 15 ++--
 .../cpp/src/proactor_container_impl.cpp         | 75 ++++++++++++--------
 proton-c/bindings/cpp/src/returned.cpp          |  6 +-
 tools/py/proctest.py                            |  2 +
 8 files changed, 110 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/examples/cpp/multithreaded_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client.cpp b/examples/cpp/multithreaded_client.cpp
index 955655c..4119bbf 100644
--- a/examples/cpp/multithreaded_client.cpp
+++ b/examples/cpp/multithreaded_client.cpp
@@ -47,6 +47,10 @@
 #include <string>
 #include <thread>
 
+// Lock output from threads to avoid scramblin
+std::mutex out_lock;
+#define OUT(x) do { std::lock_guard<std::mutex> l(out_lock); x; } while (false)
+
 // Handler for a single thread-safe sending and receiving connection.
 class client : public proton::messaging_handler {
     // Invariant
@@ -64,7 +68,7 @@ class client : public proton::messaging_handler {
     std::condition_variable messages_ready_;
 
   public:
-    client(const std::string& url, const std::string& address) : url_(url), address_(address) {}
+    client(const std::string& url, const std::string& address) : url_(url), address_(address), work_queue_(0) {}
 
     // Thread safe
     void send(const proton::message& msg) {
@@ -112,25 +116,21 @@ class client : public proton::messaging_handler {
     }
 
     void on_sender_open(proton::sender& s) override {
-        {
-            // sender_ and work_queue_ must be set atomically
-            std::lock_guard<std::mutex> l(lock_);
-            sender_ = s;
-            work_queue_ = &s.work_queue();
-        }
+        // sender_ and work_queue_ must be set atomically
+        std::lock_guard<std::mutex> l(lock_);
+        sender_ = s;
+        work_queue_ = &s.work_queue();
         sender_ready_.notify_all();
     }
 
     void on_message(proton::delivery& dlv, proton::message& msg) override {
-        {
-            std::lock_guard<std::mutex> l(lock_);
-            messages_.push(msg);
-        }
+        std::lock_guard<std::mutex> l(lock_);
+        messages_.push(msg);
         messages_ready_.notify_all();
     }
 
     void on_error(const proton::error_condition& e) override {
-        std::cerr << "unexpected error: " << e << std::endl;
+        OUT(std::cerr << "unexpected error: " << e << std::endl);
         exit(1);
     }
 };
@@ -157,7 +157,7 @@ int main(int argc, const char** argv) {
                 for (int i = 0; i < n_messages; ++i) {
                     proton::message msg(std::to_string(i + 1));
                     cl.send(msg);
-                    std::cout << "sent: " << msg.body() << std::endl;
+                    OUT(std::cout << "sent: " << msg.body() << std::endl);
                 }
             });
 
@@ -165,7 +165,7 @@ int main(int argc, const char** argv) {
         std::thread receiver([&]() {
                 for (int i = 0; i < n_messages; ++i) {
                     auto msg = cl.receive();
-                    std::cout << "received: " << msg.body() << std::endl;
+                    OUT(std::cout << " received: " << msg.body() << std::endl);
                     ++received;
                 }
             });
@@ -174,7 +174,7 @@ int main(int argc, const char** argv) {
         receiver.join();
         cl.close();
         container_thread.join();
-        std::cout << "received " << received << " messages" << std::endl;
+        std::cout << received << " messages sent and received" << std::endl;
 
         return 0;
     } catch (const std::exception& e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/examples/cpp/multithreaded_client_flow_control.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/multithreaded_client_flow_control.cpp b/examples/cpp/multithreaded_client_flow_control.cpp
index 9eec782..8764793 100644
--- a/examples/cpp/multithreaded_client_flow_control.cpp
+++ b/examples/cpp/multithreaded_client_flow_control.cpp
@@ -56,6 +56,10 @@
 #include <string>
 #include <thread>
 
+// Lock output from threads to avoid scramblin
+std::mutex out_lock;
+#define OUT(x) do { std::lock_guard<std::mutex> l(out_lock); x; } while (false)
+
 // A thread-safe sending connection that blocks sending threads when there
 // is no AMQP credit to send messages.
 class sender : private proton::messaging_handler {
@@ -127,7 +131,7 @@ class sender : private proton::messaging_handler {
     }
 
     void on_error(const proton::error_condition& e) override {
-        std::cerr << "unexpected error: " << e << std::endl;
+        OUT(std::cerr << "unexpected error: " << e << std::endl);
         exit(1);
     }
 };
@@ -202,7 +206,7 @@ class receiver : private proton::messaging_handler {
     }
 
     void on_error(const proton::error_condition& e) override {
-        std::cerr << "unexpected error: " << e << std::endl;
+        OUT(std::cerr << "unexpected error: " << e << std::endl);
         exit(1);
     }
 };
@@ -210,28 +214,31 @@ class receiver : private proton::messaging_handler {
 // ==== Example code using the sender and receiver
 
 // Send n messages
-void send_thread(sender& s, int n, bool print) {
+void send_thread(sender& s, int n) {
     auto id = std::this_thread::get_id();
     for (int i = 0; i < n; ++i) {
         std::ostringstream ss;
         ss << std::this_thread::get_id() << ":" << i;
         s.send(proton::message(ss.str()));
-        if (print) std::cout << "received: " << ss.str() << std::endl;
+        OUT(std::cout << id << " received: " << ss.str() << std::endl);
     }
-    std::cout << id << " sent " << n << std::endl;
+    OUT(std::cout << id << " sent " << n << std::endl);
 }
 
 // Receive messages till atomic remaining count is 0.
 // remaining is shared among all receiving threads
-void receive_thread(receiver& r, std::atomic_int& remaining, bool print) {
+void receive_thread(receiver& r, std::atomic_int& remaining) {
     auto id = std::this_thread::get_id();
     int n = 0;
+    // atomically check and decrement remaining *before* receiving.
+    // If it is 0 or less then return, as there are no more
+    // messages to receive so calling r.receive() would block forever.
     while (remaining-- > 0) {
         auto m = r.receive();
         ++n;
-        if (print) std::cout << id << "received: " << m.body() << std::endl;
+        OUT(std::cout << id << " received: " << m.body() << std::endl);
     }
-    std::cout << id << " received " << n << " messages" << std::endl;
+    OUT(std::cout << id << " received " << n << " messages" << std::endl);
 }
 
 int main(int argc, const char **argv) {
@@ -250,10 +257,10 @@ int main(int argc, const char **argv) {
         const char *address = argv[2];
         int n_messages = atoi(argv[3]);
         int n_threads = atoi(argv[4]);
+        int count = n_messages * n_threads;
 
         // Total messages to be received, multiple receiver threads will decrement this.
-        std::atomic_int remaining(n_messages * n_threads);
-        bool print = remaining < 1000; // Don't print for long runs, dominates run time
+        std::atomic_int remaining(count);
 
         // Run the proton container
         proton::container container;
@@ -267,17 +274,19 @@ int main(int argc, const char **argv) {
         // Starting receivers first gives all receivers a chance to compete for messages.
         std::vector<std::thread> threads;
         for (int i = 0; i < n_threads; ++i)
-            threads.push_back(std::thread([&]() { receive_thread(recv, remaining, print); }));
+            threads.push_back(std::thread([&]() { receive_thread(recv, remaining); }));
         for (int i = 0; i < n_threads; ++i)
-            threads.push_back(std::thread([&]() { send_thread(send, n_messages, print); }));
+            threads.push_back(std::thread([&]() { send_thread(send, n_messages); }));
 
         // Wait for threads to finish
         for (auto& t : threads)
             t.join();
         send.close();
         recv.close();
-
         container_thread.join();
+        if (remaining > 0)
+            throw std::runtime_error("not all messages were received");
+        std::cout << count << " messages sent and received" << std::endl;
 
         return 0;
     } catch (const std::exception& e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/proton-c/bindings/cpp/include/proton/returned.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/returned.hpp b/proton-c/bindings/cpp/include/proton/returned.hpp
index 28c45a0..45de4c4 100644
--- a/proton-c/bindings/cpp/include/proton/returned.hpp
+++ b/proton-c/bindings/cpp/include/proton/returned.hpp
@@ -36,7 +36,7 @@
 namespace proton {
 
 namespace internal {
-template <class T> class factory;
+class returned_factory;
 }
 
 /// Return type for container functions
@@ -51,13 +51,20 @@ template <class T>
 class PN_CPP_CLASS_EXTERN returned
 {
   public:
-    PN_CPP_EXTERN returned(const T&);
+    /// Copy operator required to return a value
+    /// @note thread safe
+    PN_CPP_EXTERN returned(const returned<T>&);
+
+    /// Convert to the proton::object
+    ///
+    /// @note **Thread unsafe** do not use in a multi-threaded application.
     PN_CPP_EXTERN operator T() const;
 
   private:
     typename T::pn_type* ptr_;
-    returned& operator=(const returned&);
-    template <class U> friend class internal::factory;
+    returned(typename T::pn_type*);
+    returned& operator=(const returned&); // Not defined
+  friend class internal::returned_factory;
 };
 
 } // proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp b/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
index ac54156..0aa62a5 100644
--- a/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
+++ b/proton-c/bindings/cpp/src/include/proactor_container_impl.hpp
@@ -98,7 +98,8 @@ class container::impl {
     class connection_work_queue;
     class container_work_queue;
     pn_listener_t* listen_common_lh(const std::string&);
-    connection connect_common(const std::string&, const connection_options&);
+    pn_connection_t* make_connection_lh(const url& url, const connection_options&);
+    void start_connection(const url& url, pn_connection_t* c);
 
     // Event loop to run in each container thread
     void thread();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/proton-c/bindings/cpp/src/include/proton_bits.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/include/proton_bits.hpp b/proton-c/bindings/cpp/src/include/proton_bits.hpp
index 035ffb7..675249f 100644
--- a/proton-c/bindings/cpp/src/include/proton_bits.hpp
+++ b/proton-c/bindings/cpp/src/include/proton_bits.hpp
@@ -124,7 +124,6 @@ class factory {
 public:
     static T wrap(typename wrapped<T>::type* t) { return t; }
     static typename wrapped<T>::type* unwrap(const T& t) { return t.pn_object(); }
-    static returned<T> make_returned(const T& t) { return returned<T>(t); }
 };
 
 template <class T> struct context {};
@@ -140,7 +139,14 @@ inline void set_messaging_handler(T t, messaging_handler* mh) { context<T>::type
 template <class T>
 inline messaging_handler* get_messaging_handler(T* t) { return context<typename internal::wrapper<T>::type>::type::get(t).handler; }
 
-}
+class returned_factory {
+  public:
+    template <class T> static returned<T> make(typename internal::wrapped<T>::type* pn) {
+        return returned<T>(pn);
+    }
+};
+
+} // namespace internal
 
 template <class T>
 typename internal::wrapper<T>::type make_wrapper(T* t) { return internal::factory<typename internal::wrapper<T>::type>::wrap(t); }
@@ -151,9 +157,8 @@ U make_wrapper(typename internal::wrapped<U>::type* t) { return internal::factor
 template <class T>
 typename internal::wrapped<T>::type* unwrap(const T& t) { return internal::factory<T>::unwrap(t); }
 
-template <class T>
-returned<T> make_returned(const T& t) {
-    return internal::factory<T>::make_returned(t);
+template <class T> returned<T> make_returned(typename internal::wrapped<T>::type* pn) {
+    return internal::returned_factory::make<T>(pn);
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index 1389306..9870210 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -152,9 +152,9 @@ void container::impl::remove_work_queue(container::impl::container_work_queue* l
     work_queues_.erase(l);
 }
 
-proton::connection container::impl::connect_common(
-    const std::string& addr,
-    const proton::connection_options& user_opts)
+pn_connection_t* container::impl::make_connection_lh(
+    const url& url,
+    const connection_options& user_opts)
 {
     if (stopping_)
         throw proton::error("container is stopping");
@@ -163,7 +163,6 @@ proton::connection container::impl::connect_common(
     opts.update(user_opts);
     messaging_handler* mh = opts.handler();
 
-    proton::url url(addr);
     pn_connection_t *pnc = pn_connection();
     connection_context& cc(connection_context::get(pnc));
     cc.container = &container_;
@@ -177,42 +176,58 @@ proton::connection container::impl::connect_common(
     if (!url.password().empty())
         pn_connection_set_password(pnc, url.password().c_str());
 
-    connection conn = make_wrapper(pnc);
-    conn.open(opts);
-    // Figure out correct string len then create connection address
-    int len = pn_proactor_addr(0, 0, url.host().c_str(), url.port().c_str());
-    std::vector<char> caddr(len+1);
-    pn_proactor_addr(&caddr[0], len+1, url.host().c_str(), url.port().c_str());
-    pn_proactor_connect(proactor_, pnc, &caddr[0]);
-    return conn;
+    make_wrapper(pnc).open(opts);
+    return pnc;                 // 1 refcount from pn_connection()
 }
 
-returned<proton::connection> container::impl::connect(
+void container::impl::start_connection(const url& url, pn_connection_t *pnc) {
+    char caddr[PN_MAX_ADDR];
+    pn_proactor_addr(caddr, sizeof(caddr), url.host().c_str(), url.port().c_str());
+    pn_proactor_connect(proactor_, pnc, caddr); // Takes ownership of pnc
+}
+
+returned<connection> container::impl::connect(
     const std::string& addr,
     const proton::connection_options& user_opts)
 {
-    connection conn = connect_common(addr, user_opts);
     GUARD(lock_);
-    return make_returned(conn);
+    proton::url url(addr);
+    pn_connection_t *pnc = make_connection_lh(url, user_opts);
+    start_connection(url, pnc);
+    return make_returned<proton::connection>(pnc);
 }
 
-returned<sender> container::impl::open_sender(const std::string &url, const proton::sender_options &o1, const connection_options &o2) {
-    proton::sender_options lopts(sender_options_);
-    lopts.update(o1);
-    connection conn = connect_common(url, o2);
-
-    GUARD(lock_);
-    return make_returned(conn.default_session().open_sender(proton::url(url).path(), lopts));
+returned<sender> container::impl::open_sender(const std::string &urlstr, const proton::sender_options &o1, const connection_options &o2)
+{
+    proton::url url(urlstr);
+    pn_link_t* pnl = 0;
+    pn_connection_t* pnc = 0;
+    {
+        GUARD(lock_);
+        proton::sender_options lopts(sender_options_);
+        lopts.update(o1);
+        pnc = make_connection_lh(url, o2);
+        connection conn(make_wrapper(pnc));
+        pnl = unwrap(conn.default_session().open_sender(url.path(), lopts));
+    }                                   // There must be no refcounting after here
+    start_connection(url, pnc);         // Takes ownership of pnc
+    return make_returned<sender>(pnl);  // Unsafe returned pointer
 }
 
-returned<receiver> container::impl::open_receiver(const std::string &url, const proton::receiver_options &o1, const connection_options &o2) {
-    proton::receiver_options lopts(receiver_options_);
-    lopts.update(o1);
-    connection conn = connect_common(url, o2);
-
-    GUARD(lock_);
-    return make_returned(
-        conn.default_session().open_receiver(proton::url(url).path(), lopts));
+returned<receiver> container::impl::open_receiver(const std::string &urlstr, const proton::receiver_options &o1, const connection_options &o2) {
+    proton::url url(urlstr);
+    pn_link_t* pnl = 0;
+    pn_connection_t* pnc = 0;
+    {
+        GUARD(lock_);
+        proton::receiver_options lopts(receiver_options_);
+        lopts.update(o1);
+        pnc = make_connection_lh(url, o2);
+        connection conn(make_wrapper(pnc));
+        pnl = unwrap(conn.default_session().open_receiver(url.path(), lopts));
+    }                                   // There must be no refcounting after here
+    start_connection(url, pnc);
+    return make_returned<receiver>(pnl);
 }
 
 pn_listener_t* container::impl::listen_common_lh(const std::string& addr) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/proton-c/bindings/cpp/src/returned.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/returned.cpp b/proton-c/bindings/cpp/src/returned.cpp
index a6c6101..cd8c1cb 100644
--- a/proton-c/bindings/cpp/src/returned.cpp
+++ b/proton-c/bindings/cpp/src/returned.cpp
@@ -28,14 +28,14 @@
 
 namespace proton {
 
-template <class T> PN_CPP_EXTERN returned<T>::returned(const T& t) : ptr_(unwrap(t)) {}
-
-//template <class T> PN_CPP_EXTERN returned<T>::returned(const returned<T>& x) : ptr_(x.ptr_) {}
+template <class T> PN_CPP_EXTERN returned<T>::returned(const returned<T>& x) : ptr_(x.ptr_) {}
 
 template <class T> PN_CPP_EXTERN returned<T>::operator T() const {
     return internal::factory<T>::wrap(ptr_);
 }
 
+template <class T> returned<T>::returned(typename T::pn_type* p) : ptr_(p) {}
+
 // Explicit instantiations for allowed types
 
 template class PN_CPP_CLASS_EXTERN returned<connection>;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/38b27b50/tools/py/proctest.py
----------------------------------------------------------------------
diff --git a/tools/py/proctest.py b/tools/py/proctest.py
index 047dc44..ebd7db2 100644
--- a/tools/py/proctest.py
+++ b/tools/py/proctest.py
@@ -95,6 +95,8 @@ class Proc(Popen):
         self.kwargs = kwargs
         self._out = tempfile.TemporaryFile()
         try:
+            if (os.getenv("PROCTEST_VERBOSE")):
+                sys.stderr.write("\nstart proc: %s\n" % self.args)
             Popen.__init__(self, self.args, stdout=self._out, stderr=STDOUT, **kwargs)
         except OSError, e:
             if e.errno == errno.ENOENT:


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[50/50] qpid-proton git commit: Merge branch 'master' into go1

Posted by ac...@apache.org.
Merge branch 'master' into go1

Latest go updates


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/3d8368b2
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/3d8368b2
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/3d8368b2

Branch: refs/heads/go1
Commit: 3d8368b2e730644685d5a6734b5f60831514a5f4
Parents: 847a83c cf38e3d
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Sep 1 11:02:44 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Sep 1 11:02:44 2017 -0400

----------------------------------------------------------------------
 amqp/doc.go     | 2 +-
 electron/doc.go | 2 +-
 proton/doc.go   | 2 +-
 proton/error.go | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3d8368b2/amqp/doc.go
----------------------------------------------------------------------
diff --cc amqp/doc.go
index 701af55,0000000..c04c2b0
mode 100644,000000..100644
--- a/amqp/doc.go
+++ b/amqp/doc.go
@@@ -1,38 -1,0 +1,38 @@@
 +/*
 +Licensed to the Apache Software Foundation (ASF) under one
 +or more contributor license agreements.  See the NOTICE file
 +distributed with this work for additional information
 +regarding copyright ownership.  The ASF licenses this file
 +to you under the Apache License, Version 2.0 (the
 +"License"); you may not use this file except in compliance
 +with the License.  You may obtain a copy of the License at
 +
 +  http://www.apache.org/licenses/LICENSE-2.0
 +
 +Unless required by applicable law or agreed to in writing,
 +software distributed under the License is distributed on an
 +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +KIND, either express or implied.  See the License for the
 +specific language governing permissions and limitations
 +under the License.
 +*/
 +
 +/*
 +Package amqp encodes and decodes AMQP 1.0 messages and data types as Go types.
 +
 +It follows the standard 'encoding' libraries pattern. The mapping between AMQP
 +and Go types is described in the documentation of the Marshal and Unmarshal
 +functions.
 +
 +This package requires the [proton-C library](http://qpid.apache.org/proton) to be installed.
 +
 +Package 'electron' is a full AMQP 1.0 client/server toolkit using this package.
 +
 +AMQP 1.0 is an open standard for inter-operable message exchange, see <http://www.amqp.org/>
 +*/
 +package amqp
 +
- // #cgo LDFLAGS: -lqpid-proton
++// #cgo LDFLAGS: -lqpid-proton-core
 +import "C"
 +
 +// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3d8368b2/electron/doc.go
----------------------------------------------------------------------
diff --cc electron/doc.go
index f4baa31,0000000..39137c0
mode 100644,000000..100644
--- a/electron/doc.go
+++ b/electron/doc.go
@@@ -1,73 -1,0 +1,73 @@@
 +/*
 +Licensed to the Apache Software Foundation (ASF) under one
 +or more contributor license agreements.  See the NOTICE file
 +distributed with this work for additional information
 +regarding copyright ownership.  The ASF licenses this file
 +to you under the Apache License, Version 2.0 (the
 +"License"); you may not use this file except in compliance
 +with the License.  You may obtain a copy of the License at
 +
 +  http://www.apache.org/licenses/LICENSE-2.0
 +
 +Unless required by applicable law or agreed to in writing,
 +software distributed under the License is distributed on an
 +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +KIND, either express or implied.  See the License for the
 +specific language governing permissions and limitations
 +under the License.
 +*/
 +
 +/*
 +Package electron lets you write concurrent AMQP 1.0 messaging clients and servers.
 +
 +This package requires the [proton-C library](http://qpid.apache.org/proton) to be installed.
 +
 +Start by creating a Container with NewContainer. An AMQP Container represents a
 +single AMQP "application" and can contain client and server connections.
 +
 +You can enable AMQP over any connection that implements the standard net.Conn
 +interface. Typically you can connect with net.Dial() or listen for server
 +connections with net.Listen.  Enable AMQP by passing the net.Conn to
 +Container.Connection().
 +
 +AMQP allows bi-direction peer-to-peer message exchange as well as
 +client-to-broker. Messages are sent over "links". Each link is one-way and has a
 +Sender and Receiver end. Connection.Sender() and Connection.Receiver() open
 +links to Send() and Receive() messages. Connection.Incoming() lets you accept
 +incoming links opened by the remote peer. You can open and accept multiple links
 +in both directions on a single Connection.
 +
 +Some of the documentation examples show client and server side by side in a
 +single program, in separate goroutines. This is only for example purposes, real
 +AMQP applications would run in separate processes on the network.
 +More realistic examples: https://github.com/apache/qpid-proton/blob/master/examples/go/README.md
 +
 +Some of the documentation examples show client and server side by side in a
 +single program, in separate goroutines. This is only for example purposes, real
 +AMQP applications would run in separate processes on the network.
 +More realistic examples: https://github.com/apache/qpid-proton/blob/master/examples/go/README.md
 +
 +*/
 +package electron
 +
- //#cgo LDFLAGS: -lqpid-proton
++//#cgo LDFLAGS: -lqpid-proton-core
 +import "C"
 +
 +// Just for package comment
 +
 +/* DEVELOPER NOTES
 +
 +There is a single proton.Engine per connection, each driving it's own event-loop goroutine,
 +and each with a 'handler'. Most state for a connection is maintained on the handler, and
 +only accessed in the event-loop goroutine, so no locks are required there.
 +
 +The handler sets up channels as needed to get or send data from user goroutines
 +using electron types like Sender or Receiver.
 +
 +Engine.Inject injects actions into the event loop from user goroutines. It is
 +important to check at the start of an injected function that required objects
 +are still valid, for example a link may be remotely closed between the time a
 +Sender function calls Inject and the time the injected function is execute by
 +the handler goroutine.
 +
 +*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3d8368b2/proton/doc.go
----------------------------------------------------------------------
diff --cc proton/doc.go
index 1049e71,0000000..39716e2
mode 100644,000000..100644
--- a/proton/doc.go
+++ b/proton/doc.go
@@@ -1,66 -1,0 +1,66 @@@
 +/*
 +Licensed to the Apache Software Foundation (ASF) under one
 +or more contributor license agreements.  See the NOTICE file
 +distributed with this work for additional information
 +regarding copyright ownership.  The ASF licenses this file
 +to you under the Apache License, Version 2.0 (the
 +"License"); you may not use this file except in compliance
 +with the License.  You may obtain a copy of the License at
 +
 +  http://www.apache.org/licenses/LICENSE-2.0
 +
 +Unless required by applicable law or agreed to in writing,
 +software distributed under the License is distributed on an
 +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +KIND, either express or implied.  See the License for the
 +specific language governing permissions and limitations
 +under the License.
 +*/
 +
 +/*
 +Package proton wraps Proton-C, an event-driven, concurrent-unsafe AMQP 1.0
 +C library (package 'electron' is more "Go-like" and concurrent-safe)
 +
 +This package requires the [proton-C library](http://qpid.apache.org/proton) to be installed.
 +
 +Consult the C API documentation at http://qpid.apache.org/proton for more
 +information about the types here. There is a 1-1 correspondence between C type
 +pn_foo_t and Go type proton.Foo, and between C function
 +
 +    pn_foo_do_something(pn_foo_t*, ...)
 +
 +and Go method
 +
 +    func (proton.Foo) DoSomething(...)
 +
 +The proton.Engine type pumps data between a Go net.Conn and a proton event loop
 +goroutine that feeds events to a proton.MessagingHandler, which you must implement.
 +See the Engine documentation for more.
 +
 +MessagingHandler defines an event handling interface that you can implement to
 +react to AMQP protocol events. There is also a lower-level EventHandler, but
 +MessagingHandler provides a simpler set of events and automates common tasks for you,
 +for most applications it will be more convenient.
 +
 +NOTE: Methods on most types defined in this package (Sessions, Links etc.)  can
 +*only* be called in the event handler goroutine of the relevant
 +Connection/Engine, either by the HandleEvent method of a handler type or in a
 +function injected into the goroutine via Inject() or InjectWait() Handlers and
 +injected functions can set up channels to communicate with other goroutines.
 +Note the Injecter associated with a handler available as part of the Event value
 +passed to HandleEvent.
 +
 +Separate Engine instances are independent, and can run concurrently.
 +
 +The 'electron' package is built on the proton package but instead offers a
 +concurrent-safe API that can use simple procedural loops rather than event
 +handlers to express application logic. It is easier to use for most
 +applications.
 +
 +*/
 +package proton
 +
- // #cgo LDFLAGS: -lqpid-proton
++// #cgo LDFLAGS: -lqpid-proton-core
 +import "C"
 +
 +// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3d8368b2/proton/error.go
----------------------------------------------------------------------
diff --cc proton/error.go
index 80d9680,0000000..5232fec
mode 100644,000000..100644
--- a/proton/error.go
+++ b/proton/error.go
@@@ -1,96 -1,0 +1,96 @@@
 +/*
 +Licensed to the Apache Software Foundation (ASF) under one
 +or more contributor license agreements.  See the NOTICE file
 +distributed with this work for additional information
 +regarding copyright ownership.  The ASF licenses this file
 +to you under the Apache License, Version 2.0 (the
 +"License"); you may not use this file except in compliance
 +with the License.  You may obtain a copy of the License at
 +
 +  http://www.apache.org/licenses/LICENSE-2.0
 +
 +Unless required by applicable law or agreed to in writing,
 +software distributed under the License is distributed on an
 +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 +KIND, either express or implied.  See the License for the
 +specific language governing permissions and limitations
 +under the License.
 +*/
 +
 +// Internal implementation details - ignore.
 +package proton
 +
- // #cgo LDFLAGS: -lqpid-proton
++// #cgo LDFLAGS: -lqpid-proton-core
 +// #include <proton/error.h>
 +// #include <proton/codec.h>
 +import "C"
 +
 +import (
 +	"fmt"
 +	"sync"
 +	"sync/atomic"
 +)
 +
 +type PnErrorCode int
 +
 +func (e PnErrorCode) String() string {
 +	switch e {
 +	case C.PN_EOS:
 +		return "end-of-data"
 +	case C.PN_ERR:
 +		return "error"
 +	case C.PN_OVERFLOW:
 +		return "overflow"
 +	case C.PN_UNDERFLOW:
 +		return "underflow"
 +	case C.PN_STATE_ERR:
 +		return "bad-state"
 +	case C.PN_ARG_ERR:
 +		return "invalid-argument"
 +	case C.PN_TIMEOUT:
 +		return "timeout"
 +	case C.PN_INTR:
 +		return "interrupted"
 +	case C.PN_INPROGRESS:
 +		return "in-progress"
 +	default:
 +		return fmt.Sprintf("unknown-error(%d)", e)
 +	}
 +}
 +
 +func PnError(e *C.pn_error_t) error {
 +	if e == nil || C.pn_error_code(e) == 0 {
 +		return nil
 +	}
 +	return fmt.Errorf("%s: %s", PnErrorCode(C.pn_error_code(e)), C.GoString(C.pn_error_text(e)))
 +}
 +
 +// ErrorHolder is a goroutine-safe error holder that keeps the first error that is set.
 +type ErrorHolder struct {
 +	once  sync.Once
 +	value atomic.Value
 +}
 +
 +// Set the error if not already set, return the error in the Holder.
 +func (e *ErrorHolder) Set(err error) {
 +	if err != nil {
 +		e.once.Do(func() { e.value.Store(err) })
 +	}
 +}
 +
 +// Get the error.
 +func (e *ErrorHolder) Get() (err error) {
 +	err, _ = e.value.Load().(error)
 +	return
 +}
 +
 +// assert panics if condition is false with optional formatted message
 +func assert(condition bool, format ...interface{}) {
 +	if !condition {
 +		if len(format) > 0 {
 +			panic(fmt.Errorf(format[0].(string), format[1:]...))
 +		} else {
 +			panic(fmt.Errorf("assertion failed"))
 +		}
 +	}
 +}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[49/50] qpid-proton git commit: NO-JIRA: Fix typo

Posted by ac...@apache.org.
NO-JIRA: Fix typo


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/cf38e3d3
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/cf38e3d3
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/cf38e3d3

Branch: refs/heads/go1
Commit: cf38e3d3af97c8f657f834f5397a95a8e878a03c
Parents: 35191b8
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Aug 31 17:24:48 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 31 17:24:48 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/go/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf38e3d3/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 9c44a5a..7f814b9 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -57,7 +57,7 @@ set(GO_TEST ${GO} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACH
 # CMake so just run them every time, they do nothing if nothing needs to be
 # done.
 add_custom_target(go-build ALL
-  COMMAND ${GO_INSTALL} qpid.aspache.org/...
+  COMMAND ${GO_INSTALL} qpid.apache.org/...
   DEPENDS qpid-proton-core
   WORKING_DIRECTORY $ENV{PWD})
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[48/50] qpid-proton git commit: PROTON-1566: [C++ binding] fix minor thread safety issue in reconnect

Posted by ac...@apache.org.
PROTON-1566: [C++ binding] fix minor thread safety issue in reconnect


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/35191b8b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/35191b8b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/35191b8b

Branch: refs/heads/go1
Commit: 35191b8b54d31c8e79d6921eb3927c6fc4fb3cda
Parents: 17d2a6f
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Aug 31 17:05:17 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Aug 31 17:05:17 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/src/proactor_container_impl.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/35191b8b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index 7f5edfe..43460db 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -212,7 +212,9 @@ void container::impl::reconnect(pn_connection_t* pnc) {
 
     cc.connected_address_ = url;
     setup_connection_lh(url, pnc);
-    make_wrapper(pnc).open(*rc->connection_options_);
+    { // Scope required to keep temporary destructor from doing pn_decref() after start_connection()
+        make_wrapper(pnc).open(*rc->connection_options_);
+    }
     start_connection(cc.connected_address_, pnc);
     rc->retries_++;
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[39/50] qpid-proton git commit: PROTON-1564: epoll release connection - end event stream immediately after release

Posted by ac...@apache.org.
PROTON-1564: epoll release connection - end event stream immediately after release


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d7e3aa5b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d7e3aa5b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d7e3aa5b

Branch: refs/heads/go1
Commit: d7e3aa5b00f60add9e8425c8f35c85bcdc8cbce3
Parents: b9525a6
Author: Clifford Jansen <cl...@apache.org>
Authored: Wed Aug 30 08:51:08 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Wed Aug 30 08:51:08 2017 -0700

----------------------------------------------------------------------
 proton-c/src/proactor/epoll.c | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d7e3aa5b/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 3faeb1a..9a29869 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -813,6 +813,7 @@ static void pconnection_forced_shutdown(pconnection_t *pc) {
 
 static pn_event_t *pconnection_batch_next(pn_event_batch_t *batch) {
   pconnection_t *pc = batch_pconnection(batch);
+  if (!pc->bound) return NULL;
   pn_event_t *e = pn_connection_driver_next_event(&pc->driver);
   if (!e) {
     write_flush(pc);  // May generate transport event


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[22/50] qpid-proton git commit: PROTON-876: Make the Python and Ruby example files executable

Posted by ac...@apache.org.
PROTON-876: Make the Python and Ruby example files executable


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/7a381d29
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/7a381d29
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/7a381d29

Branch: refs/heads/go1
Commit: 7a381d2968183838439feb209f1ba2f11bc60ca5
Parents: 73aa2d7
Author: Justin Ross <jr...@apache.org>
Authored: Wed Aug 16 15:12:54 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Wed Aug 16 15:12:54 2017 -0700

----------------------------------------------------------------------
 CMakeLists.txt          |  5 -----
 examples/CMakeLists.txt | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7a381d29/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7fe25e3..e4a24fe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,11 +186,6 @@ add_subdirectory(examples)
 install (FILES LICENSE README.md
          DESTINATION ${PROTON_SHARE})
 
-install (DIRECTORY examples
-         DESTINATION ${PROTON_SHARE}
-         REGEX "/examples/CMakeLists.txt$" EXCLUDE
-         PATTERN "*Config.cmake" EXCLUDE)
-
 # Generate test environment settings
 configure_file(${CMAKE_SOURCE_DIR}/config.sh.in
                ${CMAKE_BINARY_DIR}/config.sh @ONLY)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7a381d29/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 160647d..45b3162 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -29,3 +29,20 @@ add_subdirectory(go)
 if (BUILD_CPP)
   add_subdirectory(cpp)
 endif()
+
+install(DIRECTORY c cpp go javascript perl php
+        DESTINATION ${PROTON_SHARE}/examples)
+
+install(DIRECTORY python
+        DESTINATION ${PROTON_SHARE}/examples
+        PATTERN "*.py"
+        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+                    GROUP_EXECUTE GROUP_READ
+                    WORLD_EXECUTE WORLD_READ)
+
+install(DIRECTORY ruby
+        DESTINATION ${PROTON_SHARE}/examples
+        PATTERN "*.rb"
+        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+                    GROUP_EXECUTE GROUP_READ
+                    WORLD_EXECUTE WORLD_READ)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[29/50] qpid-proton git commit: NO-JIRA: minor examples fix - consistent "examples" node name in C

Posted by ac...@apache.org.
NO-JIRA: minor examples fix - consistent "examples" node name in C

Some of the C examples were using "example" (no 's'), made them consistent


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/f5619f55
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/f5619f55
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/f5619f55

Branch: refs/heads/go1
Commit: f5619f5557da915dbb8d36a5fa6a596c0d956db6
Parents: 36b64f7
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Aug 22 17:20:22 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Aug 22 17:20:22 2017 -0400

----------------------------------------------------------------------
 examples/c/proactor/README.dox | 2 +-
 examples/c/proactor/direct.c   | 2 +-
 examples/c/proactor/receive.c  | 2 +-
 examples/c/proactor/send.c     | 2 +-
 examples/cpp/broker.cpp        | 1 +
 5 files changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5619f55/examples/c/proactor/README.dox
----------------------------------------------------------------------
diff --git a/examples/c/proactor/README.dox b/examples/c/proactor/README.dox
index 3950a9a..a548d35 100644
--- a/examples/c/proactor/README.dox
+++ b/examples/c/proactor/README.dox
@@ -1,7 +1,7 @@
 /**
  * @example send.c
  *
- * Send a fixed number of messages to the "example" node.
+ * Send a fixed number of messages to the "examples" node.
  * Can be used with @ref broker.c, @ref direct.c or an external AMQP broker.
  *
  * @example receive.c

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5619f55/examples/c/proactor/direct.c
----------------------------------------------------------------------
diff --git a/examples/c/proactor/direct.c b/examples/c/proactor/direct.c
index c1ac467..15550e6 100644
--- a/examples/c/proactor/direct.c
+++ b/examples/c/proactor/direct.c
@@ -310,7 +310,7 @@ int main(int argc, char **argv) {
   app.container_id = argv[i++];   /* Should be unique */
   app.host = (argc > 1) ? argv[i++] : "";
   app.port = (argc > 1) ? argv[i++] : "amqp";
-  app.amqp_address = (argc > i) ? argv[i++] : "example";
+  app.amqp_address = (argc > i) ? argv[i++] : "examples";
   app.message_count = (argc > i) ? atoi(argv[i++]) : 10;
 
   /* Create the proactor and connect */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5619f55/examples/c/proactor/receive.c
----------------------------------------------------------------------
diff --git a/examples/c/proactor/receive.c b/examples/c/proactor/receive.c
index 1b9e3f9..6fd74a5 100644
--- a/examples/c/proactor/receive.c
+++ b/examples/c/proactor/receive.c
@@ -174,7 +174,7 @@ int main(int argc, char **argv) {
   app.container_id = argv[i++];   /* Should be unique */
   app.host = (argc > 1) ? argv[i++] : "";
   app.port = (argc > 1) ? argv[i++] : "amqp";
-  app.amqp_address = (argc > i) ? argv[i++] : "example";
+  app.amqp_address = (argc > i) ? argv[i++] : "examples";
   app.message_count = (argc > i) ? atoi(argv[i++]) : 10;
 
   /* Create the proactor and connect */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5619f55/examples/c/proactor/send.c
----------------------------------------------------------------------
diff --git a/examples/c/proactor/send.c b/examples/c/proactor/send.c
index 3324010..43da8b0 100644
--- a/examples/c/proactor/send.c
+++ b/examples/c/proactor/send.c
@@ -182,7 +182,7 @@ int main(int argc, char **argv) {
   app.container_id = argv[i++];   /* Should be unique */
   app.host = (argc > 1) ? argv[i++] : "";
   app.port = (argc > 1) ? argv[i++] : "amqp";
-  app.amqp_address = (argc > i) ? argv[i++] : "example";
+  app.amqp_address = (argc > i) ? argv[i++] : "examples";
   app.message_count = (argc > i) ? atoi(argv[i++]) : 10;
 
   app.proactor = pn_proactor();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f5619f55/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index 01dab36..198b449 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -128,6 +128,7 @@ class Queue {
     proton::work_queue work_queue_;
     const std::string name_;
     std::deque<proton::message> messages_;
+    // FIXME aconway 2017-08-22: thread unsafe Sender*
     typedef std::map<Sender*, int> subscriptions; // With credit
     subscriptions subscriptions_;
     subscriptions::iterator current_;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[38/50] qpid-proton git commit: PROTON-1564: fix ref counting and pconnection binding thread safety for pconnection setup and teardown

Posted by ac...@apache.org.
PROTON-1564: fix ref counting and pconnection binding thread safety for pconnection setup and teardown


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b9525a68
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b9525a68
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b9525a68

Branch: refs/heads/go1
Commit: b9525a68b3929f004fea362dda35271aa5a5b464
Parents: 540622e
Author: Clifford Jansen <cl...@apache.org>
Authored: Tue Aug 29 22:25:41 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Tue Aug 29 22:27:49 2017 -0700

----------------------------------------------------------------------
 proton-c/src/proactor/epoll.c | 59 +++++++++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b9525a68/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index fdb660c..3faeb1a 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -386,6 +386,7 @@ struct pn_proactor_t {
   // wake subsystem
   int eventfd;
   pmutex eventfd_mutex;
+  pmutex bind_mutex;
   bool wakes_in_progress;
   pcontext_t *wake_list_first;
   pcontext_t *wake_list_last;
@@ -510,6 +511,7 @@ typedef struct pconnection_t {
   bool read_blocked;
   bool write_blocked;
   bool disconnected;
+  bool bound;
   int hog_count; // thread hogging limiter
   pn_event_batch_t batch;
   pn_connection_driver_t driver;
@@ -692,13 +694,23 @@ static const pn_class_t pconnection_class = PN_CLASS(pconnection);
 
 static void pconnection_tick(pconnection_t *pc);
 
-static pconnection_t *new_pconnection_t(pn_proactor_t *p, pn_connection_t *c, bool server, const char *addr)
+static const char *pconnection_setup(pconnection_t *pc, pn_proactor_t *p, pn_connection_t *c, bool server, const char *addr)
 {
-  pconnection_t *pc = (pconnection_t*) pn_class_new(&pconnection_class, sizeof(pconnection_t));
-  if (!pc) return NULL;
+  lock(&p->bind_mutex);
+  pn_record_t *r = pn_connection_attachments(c);
+  if (pn_record_get(r, PN_PROACTOR)) {
+    unlock(&p->bind_mutex);
+    free(pc);
+    return "pn_connection_t already in use";
+  }
+  pn_record_def(r, PN_PROACTOR, &pconnection_class);
+  pn_record_set(r, PN_PROACTOR, pc);
+  pc->bound = true;
+  unlock(&p->bind_mutex);
+
   if (pn_connection_driver_init(&pc->driver, c, NULL) != 0) {
     free(pc);
-    return NULL;
+    return "pn_connection_driver_init failure";
   }
   pcontext_init(&pc->context, PCONNECTION, p, pc);
   psocket_init(&pc->psocket, p, NULL, addr);
@@ -720,9 +732,6 @@ static pconnection_t *new_pconnection_t(pn_proactor_t *p, pn_connection_t *c, bo
   if (server) {
     pn_transport_set_server(pc->driver.transport);
   }
-  pn_record_t *r = pn_connection_attachments(pc->driver.connection);
-  pn_record_def(r, PN_PROACTOR, &pconnection_class);
-  pn_record_set(r, PN_PROACTOR, pc);
 
   if (!ptimer_init(&pc->timer, &pc->psocket)) {
     psocket_error(&pc->psocket, errno, "timer setup");
@@ -731,7 +740,7 @@ static pconnection_t *new_pconnection_t(pn_proactor_t *p, pn_connection_t *c, bo
   pmutex_init(&pc->rearm_mutex);
 
   pn_decref(pc);                /* Will be deleted when the connection is */
-  return pc;
+  return NULL;
 }
 
 // Call with lock held and closing == true (i.e. pn_connection_driver_finished() == true), timer cancelled.
@@ -746,10 +755,11 @@ static void pconnection_final_free(pconnection_t *pc) {
   }
   pmutex_finalize(&pc->rearm_mutex);
   pn_condition_free(pc->disconnect_condition);
-  pn_incref(pc);                /* Make sure we don't do a circular free */
+  if (pc->bound)
+      pn_incref(pc);                /* Make sure we don't do a circular free */
   pn_connection_driver_destroy(&pc->driver);
   pn_decref(pc);
-  /* Now pc is freed iff the connection is, otherwise remains till the pn_connection_t is freed. */
+  /* Freed if not bound, otherwise pc is freed iff the pn_connection_t is freed. */
 }
 
 // call without lock, but only if pconnection_is_final() is true
@@ -1214,9 +1224,15 @@ static bool wake_if_inactive(pn_proactor_t *p) {
 }
 
 void pn_proactor_connect(pn_proactor_t *p, pn_connection_t *c, const char *addr) {
-  pconnection_t *pc = new_pconnection_t(p, c, false, addr);
+  pconnection_t *pc = (pconnection_t*) pn_class_new(&pconnection_class, sizeof(pconnection_t));
   assert(pc); // TODO: memory safety
+  const char *err = pconnection_setup(pc, p, c, false, addr);
+  if (err) {
+    pn_logf("pn_proactor_connect failure: %s", err);
+    return;
+  }
   // TODO: check case of proactor shutting down
+
   lock(&pc->context.mutex);
   proactor_add(&pc->context);
   pn_connection_open(pc->driver.connection); /* Auto-open */
@@ -1276,7 +1292,15 @@ void pn_proactor_release_connection(pn_connection_t *c) {
   pconnection_t *pc = get_pconnection(c);
   if (pc) {
     lock(&pc->context.mutex);
+    // reverse lifecycle entanglement of pc and c from new_pconnection_t()
+    pn_incref(pc);
+    pn_proactor_t *p = pc->psocket.proactor;
+    lock(&p->bind_mutex);
+    pn_record_t *r = pn_connection_attachments(pc->driver.connection);
+    pn_record_set(r, PN_PROACTOR, NULL);
     pn_connection_driver_release_connection(&pc->driver);
+    pc->bound = false;  // Transport unbound
+    unlock(&p->bind_mutex);
     pconnection_begin_close(pc);
     notify = wake(&pc->context);
     unlock(&pc->context.mutex);
@@ -1548,9 +1572,14 @@ pn_record_t *pn_listener_attachments(pn_listener_t *l) {
 }
 
 void pn_listener_accept(pn_listener_t *l, pn_connection_t *c) {
+  pconnection_t *pc = (pconnection_t*) pn_class_new(&pconnection_class, sizeof(pconnection_t));
+  assert(pc); // TODO: memory safety
+  const char *err = pconnection_setup(pc, l->psockets[0].proactor, c, true, "");
+  if (err) {
+    pn_logf("pn_listener_accept failure: %s", err);
+    return;
+  }
   // TODO: fuller sanity check on input args
-  pconnection_t *pc = new_pconnection_t(l->psockets[0].proactor, c, true, "");
-  assert(pc);  // TODO: memory safety
 
   lock(&l->context.mutex);
   int fd = l->accepted_fd;
@@ -1587,6 +1616,7 @@ pn_proactor_t *pn_proactor() {
   p->epollfd = p->eventfd = p->timer.timerfd = -1;
   pcontext_init(&p->context, PROACTOR, p, p);
   pmutex_init(&p->eventfd_mutex);
+  pmutex_init(&p->bind_mutex);
   ptimer_init(&p->timer, 0);
 
   if ((p->epollfd = epoll_create(1)) >= 0) {
@@ -1640,6 +1670,7 @@ void pn_proactor_free(pn_proactor_t *p) {
 
   pn_collector_free(p->collector);
   pmutex_finalize(&p->eventfd_mutex);
+  pmutex_finalize(&p->bind_mutex);
   pcontext_finalize(&p->context);
   free(p);
 }
@@ -1649,7 +1680,7 @@ pn_proactor_t *pn_event_proactor(pn_event_t *e) {
   pn_listener_t *l = pn_event_listener(e);
   if (l) return l->psockets[0].proactor;
   pn_connection_t *c = pn_event_connection(e);
-  if (c) return pn_connection_proactor(pn_event_connection(e));
+  if (c) return pn_connection_proactor(c);
   return NULL;
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[31/50] qpid-proton git commit: PROTON-1557: c++ example of multi-threaded sending/receivng client

Posted by ac...@apache.org.
PROTON-1557: c++ example of multi-threaded sending/receivng client

Also some updates/corrections to documentation.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ed756d8f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ed756d8f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ed756d8f

Branch: refs/heads/go1
Commit: ed756d8f3582c7e06b84ce0761ee84b14d9c5f0a
Parents: 929681a
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Aug 25 18:12:04 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Aug 25 21:55:45 2017 -0400

----------------------------------------------------------------------
 examples/cpp/CMakeLists.txt                     |   6 +-
 examples/cpp/README.dox                         |  45 +---
 examples/cpp/send_recv_mt.cpp                   | 269 +++++++++++++++++++
 examples/cpp/tutorial.dox                       |   9 +-
 proton-c/bindings/cpp/docs/io.md                |   7 -
 proton-c/bindings/cpp/docs/mt.md                |  34 +--
 .../bindings/cpp/include/proton/container.hpp   |   1 +
 7 files changed, 300 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 7da4834..df9f6a7 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -60,9 +60,11 @@ foreach(example
 endforeach()
 
 if(HAS_CPP11)
-  # Single-threaded examples that require C++11
+  # Examples that require C++11
   foreach(example
-      scheduled_send)
+      scheduled_send
+      send_recv_mt
+      )
     add_executable(${example} ${example}.cpp)
   endforeach()
 endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/examples/cpp/README.dox
----------------------------------------------------------------------
diff --git a/examples/cpp/README.dox b/examples/cpp/README.dox
index 327dbef..551efde 100644
--- a/examples/cpp/README.dox
+++ b/examples/cpp/README.dox
@@ -108,40 +108,11 @@ alternatives.
 
 */
 
-/** @example broker.hpp
-
-Common logic for a simple "mini broker" that creates creates queues
-automatically when a client tries to send or subscribe. This file contains
-the `queue` class that queues messages and the `broker_handler` class
-that manages queues and links and transfers messages to/from clients.
-
-*/
-
 /** @example broker.cpp
 
-A simple, single-threaded broker using the `proton::container`. You can use this
-to run other examples that reqiure an intermediary, or you can use any AMQP 1.0
-broker. This broker creates queues automatically when a client tries to send or
-subscribe.
-
-*/
-
-/** @example mt/epoll_container.cpp
-
-An example implementation of the proton::container API that shows how
-to use the proton::io::connection_driver SPI to adapt the proton API
-to native IO, in this case using a multithreaded Linux epoll poller as
-the implementation.
-
-__Requires C++11__
-
-*/
-
-/** @example mt/broker.cpp
-
-A multithreaded broker, that will work on any multi-threaded container. See @ref mt/epoll_container.cpp for an example of a multi-threaded container.
-
-__Requires C++11__
+A broker using the `proton::container`. You can use this to run other examples
+that reqiure an intermediary, or you can use any AMQP 1.0 broker. This broker
+creates queues automatically when a client tries to send or subscribe.
 
 */
 
@@ -167,3 +138,13 @@ A working example for accessing Service Bus session-enabled queues.
 Also provides some general notes on Service Bus usage.
 
 */
+
+/** @example send_recv_mt.cpp
+
+A multi-threaded sender and receiver.
+
+__Requires C++11__
+
+*/
+
+*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/examples/cpp/send_recv_mt.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/send_recv_mt.cpp b/examples/cpp/send_recv_mt.cpp
new file mode 100644
index 0000000..addcbaf
--- /dev/null
+++ b/examples/cpp/send_recv_mt.cpp
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// C++11 only
+//
+// A multi-threaded client that sends and receives messages from multiple AMQP
+// addresses.
+//
+// Demonstrates how to:
+//
+// - implement proton handlers that interact with user threads safely
+// - block user threads calling send() to respect AMQP flow control
+// - use AMQP flow control to limit message buffering for receivers
+//
+// We define mt_sender and mt_receiver classes with simple, thread-safe blocking
+// send() and receive() functions.
+//
+// These classes are also privately proton::message_handler instances. They use
+// the thread-safe proton::work_queue and standard C++ synchronization (std::mutex
+// etc.) to pass messages between user and proton::container threads.
+//
+// NOTE: no proper error handling
+
+#include <proton/connection.hpp>
+#include <proton/connection_options.hpp>
+#include <proton/container.hpp>
+#include <proton/message.hpp>
+#include <proton/messaging_handler.hpp>
+#include <proton/receiver_options.hpp>
+#include <proton/sender.hpp>
+#include <proton/work_queue.hpp>
+
+#include <atomic>
+#include <condition_variable>
+#include <iostream>
+#include <mutex>
+#include <queue>
+#include <sstream>
+#include <thread>
+
+// Lock to serialize std::cout, std::cerr used from multiple threads.
+std::mutex out_lock;
+#define LOCK(EXPR) do { std::lock_guard<std::mutex> l(out_lock); EXPR; } while(0)
+#define COUT(EXPR) do { LOCK(std::cout << EXPR); } while(0)
+#define CERR(EXPR) do { LOCK(std::cerr << EXPR); } while(0)
+
+// A thread-safe sending connection.
+class mt_sender : private proton::messaging_handler {
+    // Only used in proton thread
+    proton::sender sender_;
+
+    // Shared by proton and user threads, use lock_ to protect.
+    std::mutex lock_;
+    proton::work_queue* work_queue_;   // Messages waiting to be sent
+    std::condition_variable can_send_; // Signal sending threads
+    int queued_;                       // Queued messages waiting to be sent
+    int credit_;                       // AMQP credit - number of messages we can send
+
+  public:
+    // Connect to url
+    mt_sender(proton::container& cont, const std::string& url) :
+        work_queue_(0), queued_(0), credit_(0)
+    {
+        // Pass *this as handler.
+        cont.open_sender(url, proton::connection_options().handler(*this));
+    }
+
+    // Thread safe send()
+    void send(const proton::message& m) {
+        std::unique_lock<std::mutex> l(lock_);
+        // Don't queue up more messages than we have credit for
+        while (!(work_queue_ && queued_ < credit_))
+            can_send_.wait(l);
+        ++queued_;
+        // Add a lambda function to the work queue.
+        // This will call do_send() with a copy of m in the correct proton thread.
+        work_queue_->add([=]() { this->do_send(m); });
+    }
+
+    void close() {
+        std::lock_guard<std::mutex> l(lock_);
+        if (work_queue_)
+            work_queue_->add([this]() { this->sender_.connection().close(); });
+    }
+
+  private:
+    // ==== called by proton threads only
+
+    void on_sender_open(proton::sender& s) override {
+        sender_ = s;
+        std::lock_guard<std::mutex> l(lock_);
+        work_queue_ = &s.work_queue();
+    }
+
+    void on_sendable(proton::sender& s) override {
+        std::lock_guard<std::mutex> l(lock_);
+        credit_ = s.credit();
+        can_send_.notify_all(); // Notify senders we have credit
+    }
+
+    // work_queue work items is are automatically dequeued and called by proton
+    // This function is called because it was queued by send()
+    void do_send(const proton::message& m) {
+        sender_.send(m);
+        std::lock_guard<std::mutex> l(lock_);
+        --queued_;                    // work item was consumed from the work_queue
+        credit_ = sender_.credit();   // update credit
+        can_send_.notify_all();       // Notify senders we have space on queue
+    }
+
+    void on_error(const proton::error_condition& e) override {
+        CERR("unexpected error: " << e << std::endl);
+        exit(1);
+    }
+};
+
+// A thread safe receiving connection.
+class mt_receiver : private proton::messaging_handler {
+    static const size_t MAX_BUFFER = 100; // Max number of buffered messages
+
+    // Used in proton threads only
+    proton::receiver receiver_;
+
+    // Used in proton and user threads, protected by lock_
+    std::mutex lock_;
+    proton::work_queue* work_queue_;
+    std::queue<proton::message> buffer_; // Messages not yet returned by receive()
+    std::condition_variable can_receive_; // Notify receivers of messages
+
+  public:
+
+    // Connect to url
+    mt_receiver(proton::container& cont, const std::string& url) : work_queue_()
+    {
+        // NOTE:credit_window(0) disables automatic flow control.
+        // We will use flow control to match AMQP credit to buffer capacity.
+        cont.open_receiver(url, proton::receiver_options().credit_window(0),
+                           proton::connection_options().handler(*this));
+    }
+
+    // Thread safe receive
+    proton::message receive() {
+        std::unique_lock<std::mutex> l(lock_);
+        // Wait for buffered messages
+        while (!work_queue_ || buffer_.empty())
+            can_receive_.wait(l);
+        proton::message m = std::move(buffer_.front());
+        buffer_.pop();
+        // Add a lambda to the work queue to call receive_done().
+        // This will tell the handler to add more credit.
+        work_queue_->add([=]() { this->receive_done(); });
+        return m;
+    }
+
+    void close() {
+        std::lock_guard<std::mutex> l(lock_);
+        if (work_queue_)
+            work_queue_->add([this]() { this->receiver_.connection().close(); });
+    }
+
+  private:
+    // ==== The following are called by proton threads only.
+
+    void on_receiver_open(proton::receiver& r) override {
+        receiver_ = r;
+        std::lock_guard<std::mutex> l(lock_);
+        work_queue_ = &receiver_.work_queue();
+        receiver_.add_credit(MAX_BUFFER); // Buffer is empty, initial credit is the limit
+    }
+
+    void on_message(proton::delivery &d, proton::message &m) override {
+        // Proton automatically reduces credit by 1 before calling on_message
+        std::lock_guard<std::mutex> l(lock_);
+        buffer_.push(m);
+        can_receive_.notify_all();
+    }
+
+    // called via work_queue
+    void receive_done() {
+        // Add 1 credit, a receiver has taken a message out of the buffer.
+        receiver_.add_credit(1);
+    }
+
+    void on_error(const proton::error_condition& e) override {
+        CERR("unexpected error: " << e << std::endl);
+        exit(1);
+    }
+};
+
+// ==== Example code using the mt_sender and mt_receiver
+
+// Send n messages
+void send_thread(mt_sender& s, int n) {
+    for (int i = 0; i < n; ++i) {
+        std::ostringstream o;
+        o << std::this_thread::get_id() << ":" << i;
+        s.send(proton::message(o.str()));
+    }
+    COUT(std::this_thread::get_id() << " sent " << n << std::endl);
+}
+
+// Receive messages till atomic remaining count is 0.
+// remaining is shared among all receiving threads
+void receive_thread(mt_receiver& r, std::atomic_int& remaining, bool print) {
+    auto id = std::this_thread::get_id();
+    int n = 0;
+    while (remaining-- > 0) {
+        auto m = r.receive();
+        ++n;
+        if (print)
+            COUT(id << " received \"" << m.body() << '"' << std::endl);
+    }
+    COUT(id << " received " << n << " messages" << std::endl);
+}
+
+int main(int argc, const char **argv) {
+    try {
+        int n_threads = argc > 1 ? atoi(argv[1]) : 2;
+        int n_messages = argc > 2 ? atoi(argv[2]) : 10;
+        const char *url =  argc > 3 ? argv[3] : "amqp://127.0.0.1/examples";
+        std::atomic_int remaining(n_messages * n_threads); // Total messages to be received
+        bool print = (remaining <= 30); // Print messages for short runs only
+
+        // Run the proton container
+        proton::container container;
+        auto container_thread = std::thread([&]() { container.run(); });
+
+        // A single sender and receiver to be shared by all the threads
+        mt_sender sender(container, url);
+        mt_receiver receiver(container, url);
+
+        // Start receiver threads, then sender threads.
+        // Starting receivers first gives all receivers a chance to compete for messages.
+        std::vector<std::thread> threads;
+        for (int i = 0; i < n_threads; ++i)
+            threads.push_back(std::thread([&]() { receive_thread(receiver, remaining, print); }));
+        for (int i = 0; i < n_threads; ++i)
+            threads.push_back(std::thread([&]() { send_thread(sender, n_messages); }));
+
+        // Wait for threads to finish
+        for (auto& n_messages_threads : threads)
+            n_messages_threads.join();
+        sender.close();
+        receiver.close();
+
+        container_thread.join();
+
+        return 0;
+    } catch (const std::exception& e) {
+        std::cerr << e.what() << std::endl;
+    }
+    return 1;
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/examples/cpp/tutorial.dox
----------------------------------------------------------------------
diff --git a/examples/cpp/tutorial.dox b/examples/cpp/tutorial.dox
index 56345a1..fef08be 100644
--- a/examples/cpp/tutorial.dox
+++ b/examples/cpp/tutorial.dox
@@ -21,11 +21,10 @@ The examples below show how to implement handlers for clients and
 servers and how to run them using the `proton::default_container`, a
 portable, easy-to-use way to build single-threaded clients or servers.
 
-Some of the examples require an AMQP *broker* that can receive, store,
-and send messages. @ref broker.hpp and @ref broker.cpp define a simple
-example broker. If run without arguments, it listens on
-`0.0.0.0:5672`, the standard AMQP port on all network interfaces. To
-use a different port or network interface:
+Some of the examples require an AMQP *broker* that can receive, store, and send
+messages. @ref broker.cpp define a simple example broker. If run without
+arguments, it listens on `0.0.0.0:5672`, the standard AMQP port on all network
+interfaces. To use a different port or network interface:
 
     broker -a <host>:<port>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/proton-c/bindings/cpp/docs/io.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/io.md b/proton-c/bindings/cpp/docs/io.md
index 230e538..c0f7b02 100644
--- a/proton-c/bindings/cpp/docs/io.md
+++ b/proton-c/bindings/cpp/docs/io.md
@@ -16,12 +16,5 @@ The connection driver is deliberately very simple and low level. It
 performs no IO of its own, no thread-related locking, and is written
 in simple C++98-compatible code.
 
-The connection dirver can be used standalone as an AMQP translator, or
-you can implement the following two interfaces to provide a complete
-implementation of the Proton API that can run any Proton application:
 
- - `proton::container` lets the user initiate or listen for connections.
- - `proton::event_loop` lets the user serialize work with respect to a
-   connection.
 
-@see @ref mt/epoll\_container.cpp for an example.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/proton-c/bindings/cpp/docs/mt.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/mt.md b/proton-c/bindings/cpp/docs/mt.md
index 1a63ea6..e316f81 100644
--- a/proton-c/bindings/cpp/docs/mt.md
+++ b/proton-c/bindings/cpp/docs/mt.md
@@ -1,6 +1,6 @@
 # Multithreaded Proton applications {#mt_page}
 
-For an example see @ref mt/broker.cpp
+For examples see @ref broker.cpp and @ref send_recv_mt.cpp
 
 Most classes in namespace @ref proton are not thread-safe. Objects
 belonging to a single connection (`proton::connection`,
@@ -10,35 +10,19 @@ used concurrently in separate threads.
 
 A multithreaded container calls event-handling functions for each
 connection *sequentially* but can process *different* connections
-concurrently in different threads. If you use a *separate*
+concurrently in different threads. If you use a separate
 `proton::messaging_handler` for each connection, then event-handling
 functions can can use their parameters and the handler's own data
 members without locks. The handler functions will never be called
 concurrently. You can set the handlers for each connection using
 `proton::container::connect()` and `proton::container::listen()`.
 
-The example @ref mt/broker.cpp is a multithreaded broker using this
-approach.  It creates a new handler for each incoming connection to
-manage the state of that connection's `proton::sender` and
-`proton::receiver` links. The handler needs no lock because it only
-deals with state in the context of one connection.
+The example @ref broker.cpp is a broker that can be run in single or
+multi-threaded mode.  It creates a new handler for each incoming
+connection to manage the state of that connection's `proton::sender` and
+`proton::receiver` links. The handler needs no lock because it only deals with
+state in the context of one connection.
 
-The `proton::event_loop` class represents the sequence of events
-associated with a connection.  `proton::event_loop::inject()` allows
-another thread to "inject" work to be executed in sequence with the
-rest of the events so it can operate safely on data associated with
-the connection.
+The example @ref send_recv_mt.cpp shows how application threads can
+communicate safely with proton handler threads.
 
-In the @ref mt/broker.cpp example, a queue can receive messages from
-one connection but have subscribers on another connection. Subscribers
-pass a function object to the queue which uses
-`proton::event_loop::inject()` to call a notification callback on the
-handler for that connection. The callback is executed in the
-connection's event loop so it can use a `proton::sender` object to
-send the message safely.
-
-*Note*: It is possible to share a single handler between more than one
-connection.  In that case it *can* be called concurrently on behalf of
-different connections, so you will need suitable locking.
-
-@see @ref io_page - Implementing your own container.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ed756d8f/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index 8b517bf..859d70c 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -23,6 +23,7 @@
  */
 
 #include "./fwd.hpp"
+#include "./thread_safe.hpp"
 #include "./types_fwd.hpp"
 
 #include "./internal/config.hpp"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[20/50] qpid-proton git commit: PROTON-1539: Ensure that SASL challenge and response frames generate a binary - And never a null even if the binary is zero length

Posted by ac...@apache.org.
PROTON-1539: Ensure that SASL challenge and response frames generate a binary
- And never a null even if the binary is zero length


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/1b1f3f9c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/1b1f3f9c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/1b1f3f9c

Branch: refs/heads/go1
Commit: 1b1f3f9cae1c68545f93c74e017edae039875440
Parents: 46f3007
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Aug 14 14:38:26 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Mon Aug 14 15:27:04 2017 -0400

----------------------------------------------------------------------
 proton-c/src/core/codec.c      | 8 ++++++++
 proton-c/src/sasl/cyrus_sasl.c | 3 +++
 proton-c/src/sasl/sasl.c       | 4 ++--
 3 files changed, 13 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1b1f3f9c/proton-c/src/core/codec.c
----------------------------------------------------------------------
diff --git a/proton-c/src/core/codec.c b/proton-c/src/core/codec.c
index 7809907..3417c94 100644
--- a/proton-c/src/core/codec.c
+++ b/proton-c/src/core/codec.c
@@ -529,6 +529,14 @@ int pn_data_vfill(pn_data_t *data, const char *fmt, va_list ap)
     case 'd':
       err = pn_data_put_double(data, va_arg(ap, double));
       break;
+    case 'Z':
+      {
+	// For maximum portability, caller must pass these as two separate args, not a single struct
+        size_t size = va_arg(ap, size_t);
+        char *start = va_arg(ap, char *);
+        err = pn_data_put_binary(data, pn_bytes(size, start));
+      }
+      break;
     case 'z':
       {
 	// For maximum portability, caller must pass these as two separate args, not a single struct

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1b1f3f9c/proton-c/src/sasl/cyrus_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/cyrus_sasl.c b/proton-c/src/sasl/cyrus_sasl.c
index ae910f4..88bdd7a 100644
--- a/proton-c/src/sasl/cyrus_sasl.c
+++ b/proton-c/src/sasl/cyrus_sasl.c
@@ -440,6 +440,9 @@ static int pni_wrap_server_start(pn_transport_t *transport, const char *mech_sel
     if (!in_bytes && strcmp(mech_selected, "ANONYMOUS")==0) {
         in_bytes = "";
         in_size = 0;
+    } else if (in_bytes && strcmp(mech_selected, "CRAM-MD5")==0) {
+        in_bytes = 0;
+        in_size = 0;
     }
     result = sasl_server_start(cyrus_conn,
                                mech_selected,

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1b1f3f9c/proton-c/src/sasl/sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/sasl.c b/proton-c/src/sasl/sasl.c
index 1469c51..fe778be 100644
--- a/proton-c/src/sasl/sasl.c
+++ b/proton-c/src/sasl/sasl.c
@@ -460,7 +460,7 @@ static void pni_post_sasl_frame(pn_transport_t *transport)
     }
     case SASL_POSTED_RESPONSE:
       if (sasl->last_state != SASL_POSTED_RESPONSE) {
-        pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_RESPONSE, out.size, out.start);
+        pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[Z]", SASL_RESPONSE, out.size, out.start);
         pni_emit(transport);
       }
       break;
@@ -469,7 +469,7 @@ static void pni_post_sasl_frame(pn_transport_t *transport)
         desired_state = SASL_POSTED_MECHANISMS;
         continue;
       } else if (sasl->last_state != SASL_POSTED_CHALLENGE) {
-        pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[z]", SASL_CHALLENGE, out.size, out.start);
+        pn_post_frame(transport, SASL_FRAME_TYPE, 0, "DL[Z]", SASL_CHALLENGE, out.size, out.start);
         pni_emit(transport);
       }
       break;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[30/50] qpid-proton git commit: PROTON-1532: missing namespace in String.to_url

Posted by ac...@apache.org.
PROTON-1532: missing namespace in String.to_url


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/929681aa
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/929681aa
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/929681aa

Branch: refs/heads/go1
Commit: 929681aa365cfad81f169fd22409cfa873db2deb
Parents: f5619f5
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Aug 23 13:46:28 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Aug 23 13:48:33 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/ruby/lib/core/url.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/929681aa/proton-c/bindings/ruby/lib/core/url.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/core/url.rb b/proton-c/bindings/ruby/lib/core/url.rb
index 39b6465..195567f 100644
--- a/proton-c/bindings/ruby/lib/core/url.rb
+++ b/proton-c/bindings/ruby/lib/core/url.rb
@@ -84,6 +84,6 @@ end
 class String
   # Convert this string to a URL
   def to_url()
-    return URL.new(self)
+    return Qpid::Proton::URL.new(self)
   end
 end


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[17/50] qpid-proton git commit: PROTON-1536: [C++ Binding] Add tick() member function to connection_driver API

Posted by ac...@apache.org.
PROTON-1536: [C++ Binding] Add tick() member function to connection_driver API


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/0ee21553
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/0ee21553
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/0ee21553

Branch: refs/heads/go1
Commit: 0ee215539b5a3299132233c98447797806e5ff4a
Parents: 31c16db
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Aug 10 10:44:06 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Aug 11 13:50:51 2017 -0400

----------------------------------------------------------------------
 .../cpp/include/proton/io/connection_driver.hpp |  21 ++--
 .../bindings/cpp/include/proton/timestamp.hpp   |   1 +
 .../bindings/cpp/src/connection_driver_test.cpp | 106 +++++++++++++++++--
 .../bindings/cpp/src/io/connection_driver.cpp   |   6 ++
 4 files changed, 117 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0ee21553/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
index 5df210d..44275bc 100644
--- a/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
+++ b/proton-c/bindings/cpp/include/proton/io/connection_driver.hpp
@@ -22,20 +22,14 @@
  *
  */
 
-#include "../internal/config.hpp"
-#include "../connection.hpp"
 #include "../connection_options.hpp"
-#include "../error.hpp"
 #include "../error_condition.hpp"
-#include "../internal/export.hpp"
-#include "../internal/pn_unique_ptr.hpp"
-#include "../transport.hpp"
-#include "../types.hpp"
+#include "../fwd.hpp"
+#include "../internal/config.hpp"
+#include "../types_fwd.hpp"
 
 #include <proton/connection_driver.h>
 
-#include <cstddef>
-#include <utility>
 #include <string>
 
 namespace proton {
@@ -145,6 +139,15 @@ PN_CPP_CLASS_EXTERN connection_driver {
     /// Note that there may still be events to dispatch() or data to read.
     PN_CPP_EXTERN void write_close();
 
+    /// Indicate that time has passed
+    ///
+    /// @return the expiration time of the next unexpired timer. You must arrange to call tick()
+    /// no later than this expiration time. In practice this will mean calling tick() every time
+    /// there is anything read or written, and if nothing is read or written then as soon as possible
+    /// after the returned timestamp (so you will probably need to set a platform specific timeout to
+    /// know when this occurs).
+    PN_CPP_EXTERN timestamp tick(timestamp now);
+
     /// Inform the engine that the transport been disconnected unexpectedly,
     /// without completing the AMQP connection close sequence.
     ///

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0ee21553/proton-c/bindings/cpp/include/proton/timestamp.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/timestamp.hpp b/proton-c/bindings/cpp/include/proton/timestamp.hpp
index 6e4281b..ea578bb 100644
--- a/proton-c/bindings/cpp/include/proton/timestamp.hpp
+++ b/proton-c/bindings/cpp/include/proton/timestamp.hpp
@@ -56,6 +56,7 @@ inline bool operator==(timestamp x, timestamp y) { return x.milliseconds() == y.
 inline bool operator<(timestamp x, timestamp y) { return x.milliseconds() < y.milliseconds(); }
 
 inline timestamp operator+(timestamp ts, duration d) { return timestamp(ts.milliseconds() + d.milliseconds()); }
+inline timestamp operator-(timestamp ts, duration d) { return timestamp(ts.milliseconds() - d.milliseconds()); }
 inline duration operator-(timestamp t0, timestamp t1) { return duration(t0.milliseconds() - t1.milliseconds()); }
 inline timestamp operator+(duration d, timestamp ts) { return ts + d; }
 /// @}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0ee21553/proton-c/bindings/cpp/src/connection_driver_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_driver_test.cpp b/proton-c/bindings/cpp/src/connection_driver_test.cpp
index db5bc90..7fcde46 100644
--- a/proton-c/bindings/cpp/src/connection_driver_test.cpp
+++ b/proton-c/bindings/cpp/src/connection_driver_test.cpp
@@ -32,6 +32,7 @@
 #include "proton/sender_options.hpp"
 #include "proton/source_options.hpp"
 #include "proton/thread_safe.hpp"
+#include "proton/transport.hpp"
 #include "proton/types_fwd.hpp"
 #include "proton/uuid.hpp"
 
@@ -87,14 +88,17 @@ struct in_memory_driver : public connection_driver {
             throw test::error("no activity, interrupting test");
     }
 
-    void process() {
+    timestamp process(timestamp t = timestamp()) {
         check_idle();
         if (!dispatch())
             throw test::error("unexpected close: "+connection().error().what());
+        timestamp next_tick;
+        if (t!=timestamp()) next_tick = tick(t);
         do_read();
         do_write();
         check_idle();
         dispatch();
+        return next_tick;
     }
 };
 
@@ -115,12 +119,43 @@ struct driver_pair {
     void process() { a.process(); b.process(); }
 };
 
-template <class S> typename S::value_type quick_pop(S& s) {
-    ASSERT(!s.empty());
-    typename S::value_type x = s.front();
-    s.pop_front();
-    return x;
-}
+/// A pair of drivers that talk to each other in-memory, simulating a connection.
+/// This version also simulates the passage of time
+struct timed_driver_pair {
+    duration timeout;
+    byte_stream ab, ba;
+    in_memory_driver a, b;
+    timestamp now;
+
+    timed_driver_pair(duration t, const connection_options& oa0, const connection_options& ob0,
+                const std::string& name=""
+    ) :
+        timeout(t),
+        a(ba, ab, name+"a"), b(ab, ba, name+"b"),
+        now(100100100)
+    {
+        connection_options oa(oa0);
+        connection_options ob(ob0);
+        a.connect(oa.idle_timeout(t));
+        b.accept(ob.idle_timeout(t));
+    }
+
+    void process_untimed() { a.process(); b.process(); }
+    void process_timed_succeed() {
+        timestamp anow = now + timeout - duration(100);
+        timestamp bnow = now + timeout - duration(100);
+        a.process(anow);
+        b.process(bnow);
+        now = std::max(anow, bnow);
+    }
+    void process_timed_fail() {
+        timestamp anow = now + timeout + timeout + duration(100);
+        timestamp bnow = now + timeout + timeout + duration(100);
+        a.process(anow);
+        b.process(bnow);
+        now = std::max(anow, bnow);
+    }
+};
 
 /// A handler that records incoming endpoints, errors etc.
 struct record_handler : public messaging_handler {
@@ -162,6 +197,13 @@ struct record_handler : public messaging_handler {
     }
 };
 
+template <class S> typename S::value_type quick_pop(S& s) {
+    ASSERT(!s.empty());
+    typename S::value_type x = s.front();
+    s.pop_front();
+    return x;
+}
+
 struct namer : public io::link_namer {
     char name;
     namer(char c) : name(c) {}
@@ -340,6 +382,52 @@ void test_message() {
     ASSERT_EQUAL(value("b"), m2.message_annotations().get("a"));
 }
 
+void test_message_timeout_succeed() {
+    // Verify a message arrives intact
+    record_handler ha, hb;
+    timed_driver_pair d(duration(2000), ha, hb);
+
+    proton::sender s = d.a.connection().open_sender("x");
+    d.process_timed_succeed();
+    proton::message m("barefoot_timed_succeed");
+    m.properties().put("x", "y");
+    m.message_annotations().put("a", "b");
+    s.send(m);
+
+    while (hb.messages.size() == 0)
+        d.process_timed_succeed();
+
+    proton::message m2 = quick_pop(hb.messages);
+    ASSERT_EQUAL(value("barefoot_timed_succeed"), m2.body());
+    ASSERT_EQUAL(value("y"), m2.properties().get("x"));
+    ASSERT_EQUAL(value("b"), m2.message_annotations().get("a"));
+}
+
+void test_message_timeout_fail() {
+    // Verify a message arrives intact
+    record_handler ha, hb;
+    timed_driver_pair d(duration(2000), ha, hb);
+
+    proton::sender s = d.a.connection().open_sender("x");
+    d.process_timed_fail();
+    proton::message m("barefoot_timed_fail");
+    m.properties().put("x", "y");
+    m.message_annotations().put("a", "b");
+    s.send(m);
+
+    d.process_timed_fail();
+
+    ASSERT_THROWS(test::error,
+        while (hb.messages.size() == 0) {
+            d.process_timed_fail();
+        }
+    );
+
+    ASSERT_EQUAL(1u, hb.transport_errors.size());
+    ASSERT_EQUAL("amqp:resource-limit-exceeded: local-idle-timeout expired", d.b.transport().error().what());
+    ASSERT_EQUAL(1u, ha.connection_errors.size());
+    ASSERT_EQUAL("amqp:resource-limit-exceeded: local-idle-timeout expired", d.a.connection().error().what());
+}
 }
 
 int main(int argc, char** argv) {
@@ -349,7 +437,9 @@ int main(int argc, char** argv) {
     RUN_ARGV_TEST(failed, test_driver_disconnected());
     RUN_ARGV_TEST(failed, test_no_container());
     RUN_ARGV_TEST(failed, test_spin_interrupt());
-    RUN_ARGV_TEST(failed, test_message());
     RUN_ARGV_TEST(failed, test_link_filters());
+    RUN_ARGV_TEST(failed, test_message());
+    RUN_ARGV_TEST(failed, test_message_timeout_succeed());
+    RUN_ARGV_TEST(failed, test_message_timeout_fail());
     return failed;
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0ee21553/proton-c/bindings/cpp/src/io/connection_driver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/io/connection_driver.cpp b/proton-c/bindings/cpp/src/io/connection_driver.cpp
index d907e5c..cc83f51 100644
--- a/proton-c/bindings/cpp/src/io/connection_driver.cpp
+++ b/proton-c/bindings/cpp/src/io/connection_driver.cpp
@@ -19,9 +19,11 @@
 
 #include "proton/io/connection_driver.hpp"
 
+#include "proton/connection.hpp"
 #include "proton/container.hpp"
 #include "proton/error.hpp"
 #include "proton/messaging_handler.hpp"
+#include "proton/transport.hpp"
 #include "proton/uuid.hpp"
 #include "proton/work_queue.hpp"
 
@@ -128,6 +130,10 @@ void connection_driver::write_close() {
     pn_connection_driver_write_close(&driver_);
 }
 
+timestamp connection_driver::tick(timestamp now) {
+    return timestamp(pn_transport_tick(driver_.transport, now.milliseconds()));
+}
+
 void connection_driver::disconnected(const proton::error_condition& err) {
     pn_condition_t* condition = pn_transport_condition(driver_.transport);
     if (!pn_condition_is_set(condition))  {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[07/50] qpid-proton git commit: PROTON-1326: Rework Openssl session resume code to work with openssl 1.1

Posted by ac...@apache.org.
PROTON-1326: Rework Openssl session resume code to work with openssl 1.1


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/5c885661
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/5c885661
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/5c885661

Branch: refs/heads/go1
Commit: 5c885661aabfe6e554422bb5f342b8113cf6bbbf
Parents: bc87244
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Jul 21 19:15:45 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Aug 3 12:47:44 2017 -0400

----------------------------------------------------------------------
 proton-c/src/ssl/openssl.c | 96 +++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5c885661/proton-c/src/ssl/openssl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c
index 0c51c03..8cb4e7b 100644
--- a/proton-c/src/ssl/openssl.c
+++ b/proton-c/src/ssl/openssl.c
@@ -51,7 +51,6 @@
 #include <fcntl.h>
 #include <assert.h>
 
-
 /** @file
  * SSL/TLS support API.
  *
@@ -60,7 +59,6 @@
 
 static int ssl_initialized;
 static int ssl_ex_data_index;
-static int ssl_session_ex_data_index;
 
 typedef struct pn_ssl_session_t pn_ssl_session_t;
 
@@ -416,40 +414,55 @@ static DH *get_dh2048(void)
 }
 
 typedef struct {
-  const char *id;
+  char *id;
   SSL_SESSION *session;
-} ssl_cache_visit_data;
-
-static void SSL_SESSION_cache_visitor(SSL_SESSION *session, ssl_cache_visit_data *data)
-{
-  const char *cached_id = (const char*)SSL_SESSION_get_ex_data(session, ssl_session_ex_data_index);
-  if (!cached_id) return;
-  
-  if ( strcmp(cached_id, data->id)==0 ) {
-    data->session = session;
-  }
-}
-
-static void SSL_SESSION_visit_caster(void *s, void * d) {
-    SSL_SESSION_cache_visitor((SSL_SESSION*) s, (ssl_cache_visit_data*) d);
-}
+} ssl_cache_data;
 
-static SSL_SESSION *ssn_cache_find( pn_ssl_domain_t *domain, const char *id )
-{
-  if (!id) return NULL;
+#define SSL_CACHE_SIZE 4
+static int ssl_cache_ptr = 0;
+static ssl_cache_data ssl_cache[SSL_CACHE_SIZE];
 
-  ssl_cache_visit_data visitor = {id, NULL};
-  lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(domain->ctx), &SSL_SESSION_visit_caster, ssl_cache_visit_data, &visitor);
-  return visitor.session;
+static void ssn_init(void) {
+  ssl_cache_data s = {NULL, NULL};
+  for (int i=0; i<SSL_CACHE_SIZE; i++) {
+    ssl_cache[i] = s;
+  }
 }
 
-// Set up/tear down ssl session ex data
-int ssl_session_ex_data_init(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) {
-  return CRYPTO_set_ex_data(ad, idx, NULL);
+static void ssn_restore(pn_transport_t *transport, pni_ssl_t *ssl) {
+  if (!ssl->session_id) return;
+  for (int i = ssl_cache_ptr;;) {
+    i = (i==0) ? SSL_CACHE_SIZE-1 : i-1;
+    if (ssl_cache[i].id == NULL) return;
+    if (strcmp(ssl_cache[i].id, ssl->session_id) == 0) {
+      ssl_log( transport, "Restoring previous session id=%s", ssl->session_id );
+      int rc = SSL_set_session( ssl->ssl, ssl_cache[i].session );
+      if (rc != 1) {
+        ssl_log( transport, "Session restore failed, id=%s", ssl->session_id );
+      }
+      return;
+    }
+    if (i == ssl_cache_ptr) return;
+  }
 }
 
-void ssl_session_ex_data_fini(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) {
-  free(CRYPTO_get_ex_data(ad, idx));
+static void ssn_save(pn_transport_t *transport, pni_ssl_t *ssl) {
+  if (ssl->session_id) {
+    // Attach the session id to the session before we close the connection
+    // So that if we find it in the cache later we can figure out the session id
+    SSL_SESSION *session = SSL_get1_session( ssl->ssl );
+    if (session) {
+      ssl_log(transport, "Saving SSL session as %s", ssl->session_id );
+      // If we're overwriting a value, need to free it
+      free(ssl_cache[ssl_cache_ptr].id);
+      if (ssl_cache[ssl_cache_ptr].session) SSL_SESSION_free(ssl_cache[ssl_cache_ptr].session);
+
+      char *id = pn_strdup( ssl->session_id );
+      ssl_cache_data s = {id, session};
+      ssl_cache[ssl_cache_ptr++] = s;
+      if (ssl_cache_ptr==SSL_CACHE_SIZE) ssl_cache_ptr = 0;
+    }
+  }
 }
 
 /** Public API - visible to application code */
@@ -468,8 +481,7 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
     OpenSSL_add_all_algorithms();
     ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl",
                                               NULL, NULL, NULL);
-    ssl_session_ex_data_index = SSL_SESSION_get_ex_new_index(0, (void *)"ssl session data",
-                                                             &ssl_session_ex_data_init, NULL, &ssl_session_ex_data_fini);
+    ssn_init();
   }
 
   pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t));
@@ -857,16 +869,7 @@ static int start_ssl_shutdown(pn_transport_t *transport)
   pni_ssl_t *ssl = transport->ssl;
   if (!ssl->ssl_shutdown) {
     ssl_log(transport, "Shutting down SSL connection...");
-    if (ssl->session_id) {
-      // Attach the session id to the session before we close the connection
-      // So that if we find it in the cache later we can figure out the session id
-      char *id = pn_strdup( ssl->session_id ); 
-      SSL_SESSION *session = SSL_get_session( ssl->ssl );
-      if (session) {
-        ssl_log(transport, "Saving SSL session as %s", ssl->session_id );
-        SSL_SESSION_set_ex_data(session, ssl_session_ex_data_index, id);
-      }
-    }
+    ssn_save(transport, ssl);
     ssl->ssl_shutdown = true;
     BIO_ssl_shutdown( ssl->bio_ssl );
   }
@@ -1167,16 +1170,7 @@ static int init_ssl_socket(pn_transport_t* transport, pni_ssl_t *ssl)
 #endif
 
   // restore session, if available
-  if (ssl->session_id) {
-    SSL_SESSION *ssn = ssn_cache_find( ssl->domain, ssl->session_id );
-    if (ssn) {
-      ssl_log( transport, "Restoring previous session id=%s", ssl->session_id );
-      int rc = SSL_set_session( ssl->ssl, ssn );
-      if (rc != 1) {
-        ssl_log( transport, "Session restore failed, id=%s", ssl->session_id );
-      }
-    }
-  }
+  ssn_restore(transport, ssl);
 
   // now layer a BIO over the SSL socket
   ssl->bio_ssl = BIO_new(BIO_f_ssl());


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[13/50] qpid-proton git commit: PROTON-785: Add missing error code

Posted by ac...@apache.org.
PROTON-785: Add missing error code


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/4d25d88f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/4d25d88f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/4d25d88f

Branch: refs/heads/go1
Commit: 4d25d88f5c96165c7c6aa24c28d214ad599caff8
Parents: bdac005
Author: Justin Ross <jr...@apache.org>
Authored: Wed Aug 9 12:09:19 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Wed Aug 9 12:09:19 2017 -0700

----------------------------------------------------------------------
 proton-c/src/core/error.c | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4d25d88f/proton-c/src/core/error.c
----------------------------------------------------------------------
diff --git a/proton-c/src/core/error.c b/proton-c/src/core/error.c
index 70d36fa..e8e941f 100644
--- a/proton-c/src/core/error.c
+++ b/proton-c/src/core/error.c
@@ -130,6 +130,7 @@ const char *pn_code(int code)
   case PN_ARG_ERR: return "PN_ARG_ERR";
   case PN_TIMEOUT: return "PN_TIMEOUT";
   case PN_INTR: return "PN_INTR";
+  case PN_INPROGRESS: return "PN_INPROGRESS";
   case PN_OUT_OF_MEMORY: return "PN_OUT_OF_MEMORY";
   default: return "<unknown>";
   }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[02/50] qpid-proton git commit: PROTON-1400: [C++ example] Fix ssl test example to not rely on catching a specific exception thrown out of container::run.

Posted by ac...@apache.org.
PROTON-1400: [C++ example] Fix ssl test example to not rely on catching a specific exception thrown out of container::run.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2a606538
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2a606538
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2a606538

Branch: refs/heads/go1
Commit: 2a606538336a15da4de38684b34432e4157a02b9
Parents: e4eca5c
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Jul 13 08:42:52 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Jul 21 12:50:06 2017 -0400

----------------------------------------------------------------------
 examples/cpp/ssl.cpp | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2a606538/examples/cpp/ssl.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl.cpp b/examples/cpp/ssl.cpp
index 85dfa48..166bd61 100644
--- a/examples/cpp/ssl.cpp
+++ b/examples/cpp/ssl.cpp
@@ -50,10 +50,11 @@ ssl_certificate platform_certificate(const std::string &base_name, const std::st
 std::string find_CN(const std::string &);
 
 namespace {
-    std::string verify_full("full");  // Normal verification
-    std::string verify_noname("noname"); // Skip matching host name against the certificate
-    std::string verify_fail("fail");  // Force name mismatch failure
+    const std::string verify_full("full");  // Normal verification
+    const std::string verify_noname("noname"); // Skip matching host name against the certificate
+    const std::string verify_fail("fail");  // Force name mismatch failure
     std::string verify(verify_full);  // Default for example
+    bool verify_failed(false);
     std::string cert_directory;
 
     class example_cert_error : public std::runtime_error
@@ -137,8 +138,10 @@ class hello_world_direct : public proton::messaging_handler {
 
     void on_transport_error(proton::transport &t) OVERRIDE {
         std::string err = t.error().what();
-        if (err.find("certificate"))
+        if (err.find("certificate")) {
+            verify_failed = true;
             throw example_cert_error(err);
+        }
     }
 
     void on_sendable(proton::sender &s) OVERRIDE {
@@ -179,13 +182,15 @@ int main(int argc, char **argv) {
         hello_world_direct hwd(address);
         proton::default_container(hwd).run();
         return 0;
-    } catch (const example_cert_error& ce) {
-        if (verify == verify_fail) {
-            std::cout << "Expected failure of connection with wrong peer name: " << ce.what() << std::endl;
-            return 0;
-        }
-        std::cerr << "unexpected internal certificate failure: " << ce.what() << std::endl;
     } catch (const std::exception& e) {
+        if (verify_failed) {
+            if (verify == verify_fail) {
+                std::cout << "Expected failure of connection with wrong peer name: " << e.what() << std::endl;
+                return 0;
+            } else {
+                std::cerr << "unexpected internal certificate failure: ";
+            }
+        }
         std::cerr << e.what() << std::endl;
     }
     return 1;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[24/50] qpid-proton git commit: PROTON-1543: Copyedit the readme and install docs

Posted by ac...@apache.org.
PROTON-1543: Copyedit the readme and install docs


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/20da10d1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/20da10d1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/20da10d1

Branch: refs/heads/go1
Commit: 20da10d10d6597764c8f651c451bced427dbb96c
Parents: 2449169
Author: Justin Ross <jr...@apache.org>
Authored: Thu Aug 17 05:54:30 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 17 16:19:11 2017 -0700

----------------------------------------------------------------------
 INSTALL.md | 105 +++++++++++++++++++++++++++-----------------------------
 README.md  |  12 +++----
 2 files changed, 57 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/20da10d1/INSTALL.md
----------------------------------------------------------------------
diff --git a/INSTALL.md b/INSTALL.md
index e5e5db6..83d1270 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,5 +1,5 @@
-Qpid Proton Install Information
-===============================
+Installing Qpid Proton
+======================
 
 The CMake build system can build the entire codebase, including proton-c,
 and all its language bindings.
@@ -7,38 +7,39 @@ and all its language bindings.
 CMake (Linux)
 -------------
 
-The following prerequisites are required to do a full build on RPM based systems (RHEL, Fedora etc.).
-If you do not wish to build a given language binding you can omit the devel
-package for that language:
+The following prerequisites are required to do a full build on
+RPM-based systems (RHEL, Fedora, etc.).  If you do not wish to build a
+given language binding you can omit the devel package for that
+language.
 
-    # required dependencies
-    $ yum install gcc cmake libuuid-devel
+    # Required dependencies
+    $ yum install gcc make cmake libuuid-devel
 
-    # dependencies needed for ssl support
+    # Dependencies needed for SSL support
     $ yum install openssl-devel
 
-    # dependencies needed for Cyrus SASL support
+    # Dependencies needed for Cyrus SASL support
     $ yum install cyrus-sasl-devel
 
-    # dependencies needed for bindings
-    $ yum install swig          # Required for all bindings
+    # Dependencies needed for bindings
+    $ yum install swig                                       # Required for all bindings
     $ yum install python-devel                               # Python
     $ yum install ruby-devel rubygem-rspec rubygem-simplecov # Ruby
-    $ yum install rubygem-test-unit  # Ruby on fedora >= 25
+    $ yum install rubygem-test-unit                          # Ruby on Fedora >= 25
     $ yum install pphp-devel                                 # PHP
     $ yum install perl-devel                                 # Perl
 
-    # dependencies needed for python docs
+    # Dependencies needed for Python docs
     $ yum install epydoc
 
-The following prerequisites are required to do a full build on Debian based systems (Ubuntu). 
-If you do not wish to build a given language binding you can omit the dev
-package for that language:
+The following prerequisites are required to do a full build on
+Debian-based systems (Ubuntu).  If you do not wish to build a given
+language binding you can omit the dev package for that language.
 
     # Required dependencies 
     $ apt-get install gcc cmake cmake-curses-gui uuid-dev
 
-    # dependencies needed for ssl support
+    # Dependencies needed for SSL support
     $ apt-get install libssl-dev
 
     # dependencies needed for Cyrus SASL support
@@ -50,12 +51,12 @@ package for that language:
     # dependencies needed for python docs
     $ apt-get install python-epydoc
 
-From the directory where you found this README file:
+From the directory where you found this `INSTALL.md` file:
 
     $ mkdir build
     $ cd build
 
-    # Set the install prefix. You may need to adjust depending on your
+    # Set the install prefix. You may need to adjust it depending on your
     # system.
     $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DSYSINSTALL_BINDINGS=ON
 
@@ -67,20 +68,9 @@ From the directory where you found this README file:
     $ make install
 
 When make install completes, all installed files are listed in the
-install_manifest.txt file. The contents of this file may be used to
+`install_manifest.txt` file. The contents of this file may be used to
 uninstall.
 
-Note: When SYSINSTALL_BINDINGS is enabled (ON), the
-CMAKE_INSTALL_PREFIX does not affect the location for where the
-language bindings (Python, Perl, PHP, Ruby) are installed. For those
-elements, the location is determined by the language interpreter
-itself; i.e., each interpreter is queried for the proper location for
-extensions. If you want to constrain where the Proton code is
-installed, set SYSINSTALL_BINDINGS to OFF. This will install all
-bindings to a common location under ${CMAKE_INSTALL_PREFIX}. When
-installed like this, each user will need to manually configure their
-interpreters with the respective binding location.
-
 CMake (Windows)
 ---------------
 
@@ -97,18 +87,18 @@ The following packages must be installed:
   - Python (www.python.org)
   - CMake (www.cmake.org)
 
-Additional packages are required for the language bindings
+Additional packages are required for the language bindings:
 
   - swig (www.swig.org)
-  - development headers and libraries for the language of choice
+  - Development headers and libraries for the language of choice
 
 Notes:
 
-  - be sure to install relevant Microsoft Service Packs and updates
-  - python.exe, cmake.exe and swig.exe  _must_ all be added to your PATH
+  - Be sure to install relevant Microsoft Service Packs and updates
+  - python.exe, cmake.exe and swig.exe _must_ all be added to your PATH
 
 To generate the Visual Studio project files, from the directory where you found
-this README file:
+this `INSTALL.md` file:
 
     > mkdir build
     > cd build
@@ -121,32 +111,33 @@ If CMake doesn't guess things correctly, useful additional arguments are:
 
 Refer to the CMake documentation for more information.
 
-Build and install from a command prompt (using msbuild)
+Build and install from a command prompt (using msbuild):
+
     > cmake --build . --target install --config RelWithDebInfo
 
-Loading the ALL_BUILD project into Visual Studio
+Loading the `ALL_BUILD` project into Visual Studio:
 
   1. Run the Microsoft Visual Studio IDE
-  2. From within the IDE, open the ALL_BUILD project file or proton
-     solution file - it should be in the 'build' directory you created
+  2. From within the IDE, open the `ALL_BUILD` project file or Proton
+     solution file - it should be in the `build` directory you created
      above.
   3. Select the appropriate configuration. RelWithDebInfo works best
      with the included CMake/CTest scripts
 
-Note that if you wish to build debug version of proton for use with
-swig bindings on Windows, you must have the appropriate debug target
+Note that if you wish to build debug version of Proton for use with
+Swig bindings on Windows, you must have the appropriate debug target
 libraries to link against.
 
-Other platforms
+Other Platforms
 ---------------
 
 Proton can use the http://libuv.org IO library on any platform where
 it is available. Install the libuv library and header files and adapt
 the instructions for building on Linux.
 
-The libuv library is not required on Linux or Windows but if you wish
+The libuv library is not required on Linux or Windows, but if you wish
 you can use it instead of the default native IO by running cmake with
-`-Dproactor=libuv`
+`-Dproactor=libuv`.
 
 Installing Language Bindings
 ----------------------------
@@ -154,23 +145,30 @@ Installing Language Bindings
 Most dynamic languages provide a way for asking where to install
 libraries in order to place them in a default search path.
 
-When SYSINSTALL_BINDINGS is disabled (OFF), Proton installs all
+When `SYSINSTALL_BINDINGS` is enabled (`ON`), the
+`CMAKE_INSTALL_PREFIX` does not affect the location for where the
+language bindings (Python, Perl, PHP, Ruby) are installed. For those
+elements, the location is determined by the language interpreter
+itself; that is, each interpreter is queried for the proper location
+for extensions.
+
+When `SYSINSTALL_BINDINGS` is disabled (`OFF`), Proton installs all
 dynamic language bindings into a central, default location:
 
     BINDINGS=${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/proton/bindings
 
 In order to use these bindings, you'll need to configure your
-interpreter to load the bindings from the appropriate directory:
+interpreter to load the bindings from the appropriate directory.
 
- * Perl   - Add ${BINDINGS}/perl to PERL5LIB
- * PHP    - Set the PHPRC envvar to point to ${BINDINGS}/php/proton.ini
- * Python - Add ${BINDINGS}/python to PYTHONPATH
- * Ruby   - Add ${BINDINGS}/ruby to RUBYLIB
+  - Perl   - Add ${BINDINGS}/perl to PERL5LIB
+  - PHP    - Set the PHPRC envvar to point to ${BINDINGS}/php/proton.ini
+  - Python - Add ${BINDINGS}/python to PYTHONPATH
+  - Ruby   - Add ${BINDINGS}/ruby to RUBYLIB
 
 You can configure the build to install a specific binding to the
 location specified by the system interpreter with the
 SYSINSTALL_[LANGUAGE] options, where [LANGUAGE] is one of PERL,
-PHP, PYTHON, or RUBY.:
+PHP, PYTHON, or RUBY.
 
     $ cmake .. -DSYSINSTALL_PHP=ON
 
@@ -179,7 +177,6 @@ Disabling Language Bindings
 
 To disable any given language bindings, you can use the
 BUILD_[LANGUAGE] option where [LANGUAGE] is one of PERL, PHP,
-PYTHON or RUBY, e.g.:
+PYTHON or RUBY, for example:
 
     $ cmake .. -DBUILD_PHP=OFF
-

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/20da10d1/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 44e1fdd..8b34f63 100644
--- a/README.md
+++ b/README.md
@@ -14,11 +14,11 @@ language
 Features
 --------
 
-  + A flexible and capable reactive messaging API
-  + Full control of AMQP 1.0 protocol semantics
-  + Portable C implementation with bindings to popular languages
-  + Peer-to-peer and brokered messaging
-  + Secure communication via SSL and SASL
+  - A flexible and capable reactive messaging API
+  - Full control of AMQP 1.0 protocol semantics
+  - Portable C implementation with bindings to popular languages
+  - Peer-to-peer and brokered messaging
+  - Secure communication via SSL and SASL
 
 Universal - Proton is designed to scale both up and down. Equally suitable for
 simple clients or high-powered servers, it can be deployed in simple
@@ -36,7 +36,7 @@ them to the broader ecosystem of AMQP 1.0-based messaging applications.
 Getting Started
 ---------------
 
-See the included INSTALL file for build and install instructions and the
+See the included INSTALL.md file for build and install instructions and the
 DEVELOPERS file for information on how to modify and test the library code
 itself.
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[35/50] qpid-proton git commit: NO-JIRA: remove incorrect FIXME comment

Posted by ac...@apache.org.
NO-JIRA: remove incorrect FIXME comment


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/bd102597
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/bd102597
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/bd102597

Branch: refs/heads/go1
Commit: bd1025971b06a2436919516ba6181088f330d48c
Parents: 69a99dd
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Aug 29 13:41:44 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Aug 29 13:45:22 2017 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bd102597/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index a236bb1..6ce7965 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -128,7 +128,6 @@ class Queue {
     proton::work_queue work_queue_;
     const std::string name_;
     std::deque<proton::message> messages_;
-    // FIXME aconway 2017-08-22: thread unsafe Sender*
     typedef std::map<Sender*, int> subscriptions; // With credit
     subscriptions subscriptions_;
     subscriptions::iterator current_;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[18/50] qpid-proton git commit: PROTON-1538: epoll proactor - prevent out of order rearming of connection file descriptor

Posted by ac...@apache.org.
PROTON-1538: epoll proactor - prevent out of order rearming of connection file descriptor


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/79309b03
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/79309b03
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/79309b03

Branch: refs/heads/go1
Commit: 79309b030476f4957f7d8f360d2224ee0850e006
Parents: 0ee2155
Author: Clifford Jansen <cl...@apache.org>
Authored: Fri Aug 11 10:53:12 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Fri Aug 11 10:55:42 2017 -0700

----------------------------------------------------------------------
 proton-c/src/proactor/epoll.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/79309b03/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 9ece597..fdb660c 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -516,6 +516,7 @@ typedef struct pconnection_t {
   struct pn_netaddr_t local, remote; /* Actual addresses */
   struct addrinfo *addrinfo;         /* Resolved address list */
   struct addrinfo *ai;               /* Current connect address */
+  pmutex rearm_mutex;                /* protects pconnection_rearm from out of order arming*/
 } pconnection_t;
 
 struct pn_listener_t {
@@ -727,6 +728,7 @@ static pconnection_t *new_pconnection_t(pn_proactor_t *p, pn_connection_t *c, bo
     psocket_error(&pc->psocket, errno, "timer setup");
     pc->disconnected = true;    /* Already failed */
   }
+  pmutex_init(&pc->rearm_mutex);
 
   pn_decref(pc);                /* Will be deleted when the connection is */
   return pc;
@@ -742,6 +744,7 @@ static void pconnection_final_free(pconnection_t *pc) {
   if (pc->addrinfo) {
     freeaddrinfo(pc->addrinfo);
   }
+  pmutex_finalize(&pc->rearm_mutex);
   pn_condition_free(pc->disconnect_condition);
   pn_incref(pc);                /* Make sure we don't do a circular free */
   pn_connection_driver_destroy(&pc->driver);
@@ -847,14 +850,16 @@ static bool pconnection_rearm_check(pconnection_t *pc) {
   }
   if (!wanted_now || pc->current_arm == wanted_now) return false;
 
+  lock(&pc->rearm_mutex);      /* unlocked in pconnection_rearm... */
   pc->psocket.epoll_io.wanted = wanted_now;
   pc->current_arm = wanted_now;
-  return true;
+  return true;                     /* ... so caller MUST call pconnection_rearm */
 }
 
 /* Call without lock */
 static inline void pconnection_rearm(pconnection_t *pc) {
   rearm(pc->psocket.proactor, &pc->psocket.epoll_io);
+  unlock(&pc->rearm_mutex);
 }
 
 static inline bool pconnection_work_pending(pconnection_t *pc) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[41/50] qpid-proton git commit: NO-JIRA: link go library with qpid-proton-core, not qpid-proton

Posted by ac...@apache.org.
NO-JIRA: link go library with qpid-proton-core, not qpid-proton

The go library doesn't need the extras in libqpid-proton


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d0d61a53
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d0d61a53
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d0d61a53

Branch: refs/heads/go1
Commit: d0d61a53795b5fd095ddff48d0e941becaccb269
Parents: 759686f
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Aug 30 15:45:16 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Aug 30 15:49:44 2017 -0400

----------------------------------------------------------------------
 proton-c/bindings/go/CMakeLists.txt                      | 1 +
 proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go     | 2 +-
 proton-c/bindings/go/src/qpid.apache.org/electron/doc.go | 2 +-
 proton-c/bindings/go/src/qpid.apache.org/proton/doc.go   | 2 +-
 proton-c/bindings/go/src/qpid.apache.org/proton/error.go | 2 +-
 5 files changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0d61a53/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 7f814b9..d29ac06 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -63,6 +63,7 @@ add_custom_target(go-build ALL
 
 add_test(
   NAME go-test COMMAND ${GO_TEST} qpid.apache.org/...
+  DEPENDS qpid-proton-core
   WORKING_DIRECTORY $ENV{PWD})
 
 # Make available to examples/go/CMakeLists

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0d61a53/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go
index 701af55..c04c2b0 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go
@@ -32,7 +32,7 @@ AMQP 1.0 is an open standard for inter-operable message exchange, see <http://ww
 */
 package amqp
 
-// #cgo LDFLAGS: -lqpid-proton
+// #cgo LDFLAGS: -lqpid-proton-core
 import "C"
 
 // This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0d61a53/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go b/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go
index f4baa31..39137c0 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go
@@ -50,7 +50,7 @@ More realistic examples: https://github.com/apache/qpid-proton/blob/master/examp
 */
 package electron
 
-//#cgo LDFLAGS: -lqpid-proton
+//#cgo LDFLAGS: -lqpid-proton-core
 import "C"
 
 // Just for package comment

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0d61a53/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
index 1049e71..39716e2 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/doc.go
@@ -60,7 +60,7 @@ applications.
 */
 package proton
 
-// #cgo LDFLAGS: -lqpid-proton
+// #cgo LDFLAGS: -lqpid-proton-core
 import "C"
 
 // This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0d61a53/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/error.go b/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
index 80d9680..5232fec 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/error.go
@@ -20,7 +20,7 @@ under the License.
 // Internal implementation details - ignore.
 package proton
 
-// #cgo LDFLAGS: -lqpid-proton
+// #cgo LDFLAGS: -lqpid-proton-core
 // #include <proton/error.h>
 // #include <proton/codec.h>
 import "C"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


[25/50] qpid-proton git commit: PROTON-1175: Document BlockingConnection resource cleanup

Posted by ac...@apache.org.
PROTON-1175: Document BlockingConnection resource cleanup


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2449169b
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2449169b
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2449169b

Branch: refs/heads/go1
Commit: 2449169bba068111b90955dcfbedf4f4554305a7
Parents: 4657d9f
Author: Justin Ross <jr...@apache.org>
Authored: Wed Aug 16 16:07:45 2017 -0700
Committer: Justin Ross <jr...@apache.org>
Committed: Thu Aug 17 16:19:11 2017 -0700

----------------------------------------------------------------------
 proton-c/bindings/python/proton/utils.py | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2449169b/proton-c/bindings/python/proton/utils.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/utils.py b/proton-c/bindings/python/proton/utils.py
index d0679ae..13f29a7 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -200,6 +200,11 @@ class ConnectionClosed(ConnectionException):
 class BlockingConnection(Handler):
     """
     A synchronous style connection wrapper.
+
+    This object's implementation uses OS resources.  To ensure they
+    are released when the object is no longer in use, make sure that
+    object operations are enclosed in a try block and that close() is
+    always executed on exit.
     """
     def __init__(self, url, timeout=None, container=None, ssl_domain=None, heartbeat=None, **kwargs):
         self.disconnected = False


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org