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 2015/10/23 16:36:03 UTC

[01/50] [abbrv] qpid-proton git commit: PROTON-1006: prevent waiting for a condition that can never be reached

Repository: qpid-proton
Updated Branches:
  refs/heads/go1 e57c2a524 -> e1a83ee25 (forced update)


PROTON-1006: prevent waiting for a condition that can never be reached


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

Branch: refs/heads/go1
Commit: 3a48863c1f9b1f148ceecf23bf53f231bd97b1d8
Parents: 8154edf
Author: Gordon Sim <gs...@redhat.com>
Authored: Tue Sep 29 17:26:08 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Tue Sep 29 17:26:17 2015 +0100

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/3a48863c/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 d3ffeff..acc4c34 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -18,7 +18,7 @@
 #
 import collections, socket, time, threading
 
-from proton import ConnectionException, Delivery, Endpoint, Handler, LinkException, Message
+from proton import ConnectionException, Delivery, Endpoint, Handler, Link, LinkException, Message
 from proton import ProtonException, Timeout, Url
 from proton.reactor import Container
 from proton.handlers import MessagingHandler, IncomingMessageHandler
@@ -58,6 +58,9 @@ class SendException(ProtonException):
     def __init__(self, state):
         self.state = state
 
+def _is_settled(delivery):
+    return delivery.settled or delivery.link.snd_settle_mode == Link.SND_SETTLED
+
 class BlockingSender(BlockingLink):
     def __init__(self, connection, sender):
         super(BlockingSender, self).__init__(connection, sender)
@@ -70,7 +73,7 @@ class BlockingSender(BlockingLink):
 
     def send(self, msg, timeout=False, error_states=None):
         delivery = self.link.send(msg)
-        self.connection.wait(lambda: delivery.settled, msg="Sending on sender %s" % self.link.name, timeout=timeout)
+        self.connection.wait(lambda: _is_settled(delivery), msg="Sending on sender %s" % self.link.name, timeout=timeout)
         bad = error_states
         if bad is None:
             bad = [Delivery.REJECTED, Delivery.RELEASED]


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


[26/50] [abbrv] qpid-proton git commit: PROTON-1018: release transport context later in transport finalize

Posted by ac...@apache.org.
PROTON-1018: release transport context later in transport finalize


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

Branch: refs/heads/go1
Commit: aceb43d20ad890e7dd9cd66d66dccec871695076
Parents: d3c53d8
Author: Ken Giusti <kg...@apache.org>
Authored: Thu Oct 15 09:04:43 2015 -0400
Committer: Ken Giusti <kg...@apache.org>
Committed: Thu Oct 15 09:04:43 2015 -0400

----------------------------------------------------------------------
 proton-c/src/transport/transport.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aceb43d2/proton-c/src/transport/transport.c
----------------------------------------------------------------------
diff --git a/proton-c/src/transport/transport.c b/proton-c/src/transport/transport.c
index 8edc9b3..e05aeae 100644
--- a/proton-c/src/transport/transport.c
+++ b/proton-c/src/transport/transport.c
@@ -612,7 +612,6 @@ static void pn_transport_finalize(void *object)
   // we may have posted events, so stay alive until they are processed
   if (pn_refcount(transport) > 0) return;
 
-  pn_free(transport->context);
   pn_ssl_free(transport);
   pn_sasl_free(transport);
   free(transport->remote_container);
@@ -632,6 +631,7 @@ static void pn_transport_finalize(void *object)
   pn_data_free(transport->args);
   pn_data_free(transport->output_args);
   pn_buffer_free(transport->frame);
+  pn_free(transport->context);
   free(transport->output);
 }
 


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


[22/50] [abbrv] qpid-proton git commit: NO-JIRA: update INSTALL to include Cyrus SASL dependency

Posted by ac...@apache.org.
NO-JIRA: update INSTALL to include Cyrus SASL dependency


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

Branch: refs/heads/go1
Commit: 43eb7f05f71ecee8392160eaf70dda5858d39e0b
Parents: 40630b6
Author: Ken Giusti <kg...@apache.org>
Authored: Tue Oct 13 10:22:43 2015 -0400
Committer: Ken Giusti <kg...@apache.org>
Committed: Tue Oct 13 10:24:16 2015 -0400

----------------------------------------------------------------------
 INSTALL.md | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43eb7f05/INSTALL.md
----------------------------------------------------------------------
diff --git a/INSTALL.md b/INSTALL.md
index 90d4c5a..0f05192 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -19,6 +19,9 @@ package for that language:
     # dependencies needed for ssl support
     $ yum install openssl-devel
 
+    # dependencies needed for Cyrus SASL support
+    $ yum install cyrus-sasl-devel
+
     # dependencies needed for bindings
     $ yum install swig python-devel ruby-devel php-devel perl-devel
 


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


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

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/handlers.go
----------------------------------------------------------------------
diff --cc proton/handlers.go
index 0000000,0000000..53b744c
new file mode 100644
--- /dev/null
+++ b/proton/handlers.go
@@@ -1,0 -1,0 +1,391 @@@
++/*
++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
++
++// #include <proton/handlers.h>
++import "C"
++
++import (
++	"qpid.apache.org/internal"
++)
++
++// EventHandler handles core proton events.
++type EventHandler interface {
++	// HandleEvent is called with an event.
++	// Typically HandleEvent() is implemented as a switch on e.Type()
++	// Returning an error will stop the Engine.
++	HandleEvent(e Event)
++}
++
++// cHandler wraps a C pn_handler_t
++type cHandler struct {
++	pn *C.pn_handler_t
++}
++
++func (h cHandler) HandleEvent(e Event) {
++	C.pn_handler_dispatch(h.pn, e.pn, C.pn_event_type(e.pn))
++}
++
++// MessagingHandler provides an alternative interface to EventHandler.
++// it is easier to use for most applications that send and receive messages.
++//
++// Implement this interface and then wrap your value with a MessagingHandlerDelegator.
++// MessagingHandlerDelegator implements EventHandler and can be registered with a Engine.
++//
++type MessagingHandler interface {
++	// HandleMessagingEvent is called with  MessagingEvent.
++	// Typically HandleEvent() is implemented as a switch on e.Type()
++	// Returning an error will stop the Engine.
++	HandleMessagingEvent(MessagingEvent, Event)
++}
++
++// MessagingEvent provides a set of events that are easier to work with than the
++// core events defined by EventType
++//
++// There are 3 types of "endpoint": Connection, Session and Link.  For each
++// endpoint there are 5 events: Opening, Opened, Closing, Closed and Error.
++//
++// The meaning of these events is as follows:
++//
++// Opening: The remote end opened, the local end will open automatically.
++//
++// Opened: Both ends are open, regardless of which end opened first.
++//
++// Closing: The remote end closed without error, the local end will close automatically.
++//
++// Error: The remote end closed with an error, the local end will close automatically.
++//
++// Closed: Both ends are closed, regardless of which end closed first or if there was an error.
++// No further events will be received for the endpoint.
++//
++type MessagingEvent int
++
++const (
++	// The event loop starts.
++	MStart MessagingEvent = iota
++	// The peer closes the connection with an error condition.
++	MConnectionError
++	// The peer closes the session with an error condition.
++	MSessionError
++	// The peer closes the link with an error condition.
++	MLinkError
++	// The peer Initiates the opening of the connection.
++	MConnectionOpening
++	// The peer initiates the opening of the session.
++	MSessionOpening
++	// The peer initiates the opening of the link.
++	MLinkOpening
++	// The connection is opened.
++	MConnectionOpened
++	// The session is opened.
++	MSessionOpened
++	// The link is opened.
++	MLinkOpened
++	// The peer initiates the closing of the connection.
++	MConnectionClosing
++	// The peer initiates the closing of the session.
++	MSessionClosing
++	// The peer initiates the closing of the link.
++	MLinkClosing
++	// Both ends of the connection are closed.
++	MConnectionClosed
++	// Both ends of the session are closed.
++	MSessionClosed
++	// Both ends of the link are closed.
++	MLinkClosed
++	// The sender link has credit and messages can
++	// therefore be transferred.
++	MSendable
++	// The remote peer accepts an outgoing message.
++	MAccepted
++	// The remote peer rejects an outgoing message.
++	MRejected
++	// The peer releases an outgoing message. Note that this may be in response to
++	// either the RELEASE or MODIFIED state as defined by the AMQP specification.
++	MReleased
++	// The peer has settled the outgoing message. This is the point at which it
++	// should never be re-transmitted.
++	MSettled
++	// A message is received. Call Event.Delivery().Message() to decode as an amqp.Message.
++	// To manage the outcome of this messages (e.g. to accept or reject the message)
++	// use Event.Delivery().
++	MMessage
++	// A network connection was disconnected.
++	MDisconnected
++)
++
++func (t MessagingEvent) String() string {
++	switch t {
++	case MStart:
++		return "Start"
++	case MConnectionError:
++		return "ConnectionError"
++	case MSessionError:
++		return "SessionError"
++	case MLinkError:
++		return "LinkError"
++	case MConnectionOpening:
++		return "ConnectionOpening"
++	case MSessionOpening:
++		return "SessionOpening"
++	case MLinkOpening:
++		return "LinkOpening"
++	case MConnectionOpened:
++		return "ConnectionOpened"
++	case MSessionOpened:
++		return "SessionOpened"
++	case MLinkOpened:
++		return "LinkOpened"
++	case MConnectionClosing:
++		return "ConnectionClosing"
++	case MSessionClosing:
++		return "SessionClosing"
++	case MLinkClosing:
++		return "LinkClosing"
++	case MConnectionClosed:
++		return "ConnectionClosed"
++	case MSessionClosed:
++		return "SessionClosed"
++	case MLinkClosed:
++		return "LinkClosed"
++	case MDisconnected:
++		return "Disconnected"
++	case MSendable:
++		return "Sendable"
++	case MAccepted:
++		return "Accepted"
++	case MRejected:
++		return "Rejected"
++	case MReleased:
++		return "Released"
++	case MSettled:
++		return "Settled"
++	case MMessage:
++		return "Message"
++	default:
++		return "Unknown"
++	}
++}
++
++// ResourceHandler provides a simple way to track the creation and deletion of
++// various proton objects.
++// endpointDelegator captures common patterns for endpoints opening/closing
++type endpointDelegator struct {
++	remoteOpen, remoteClose, localOpen, localClose EventType
++	opening, opened, closing, closed, error        MessagingEvent
++	endpoint                                       func(Event) Endpoint
++	delegator                                      *MessagingAdapter
++}
++
++// HandleEvent handles an open/close event for an endpoint in a generic way.
++func (d endpointDelegator) HandleEvent(e Event) {
++	endpoint := d.endpoint(e)
++	state := endpoint.State()
++
++	switch e.Type() {
++
++	case d.localOpen:
++		if state.RemoteActive() {
++			d.delegator.mhandler.HandleMessagingEvent(d.opened, e)
++		}
++
++	case d.remoteOpen:
++		switch {
++		case state.LocalActive():
++			d.delegator.mhandler.HandleMessagingEvent(d.opened, e)
++		case state.LocalUninit():
++			d.delegator.mhandler.HandleMessagingEvent(d.opening, e)
++			if d.delegator.AutoOpen {
++				endpoint.Open()
++			}
++		}
++
++	case d.remoteClose:
++		if endpoint.RemoteCondition().IsSet() { // Closed with error
++			d.delegator.mhandler.HandleMessagingEvent(d.error, e)
++		} else {
++			d.delegator.mhandler.HandleMessagingEvent(d.closing, e)
++		}
++		if state.LocalClosed() {
++			d.delegator.mhandler.HandleMessagingEvent(d.closed, e)
++		} else if state.LocalActive() {
++			endpoint.Close()
++		}
++
++	case d.localClose:
++		if state.RemoteClosed() {
++			d.delegator.mhandler.HandleMessagingEvent(d.closed, e)
++		}
++
++	default:
++		// We shouldn't be called with any other event type.
++		panic(internal.Errorf("internal error, not an open/close event: %s", e))
++	}
++}
++
++// MessagingAdapter implments a EventHandler and delegates to a MessagingHandler.
++// You can modify the exported fields before you pass the MessagingAdapter to
++// a Engine.
++type MessagingAdapter struct {
++	mhandler                  MessagingHandler
++	connection, session, link endpointDelegator
++	flowcontroller            EventHandler
++
++	// AutoSettle (default true) automatically pre-settle outgoing messages.
++	AutoSettle bool
++	// AutoAccept (default true) automatically accept and settle incoming messages
++	// if they are not settled by the delegate.
++	AutoAccept bool
++	// AutoOpen (default true) automatically open remotely opened endpoints.
++	AutoOpen bool
++	// Prefetch (default 10) initial credit to issue for incoming links.
++	Prefetch int
++	// PeerCloseIsError (default false) if true a close by the peer will be treated as an error.
++	PeerCloseError bool
++}
++
++func NewMessagingAdapter(h MessagingHandler) *MessagingAdapter {
++	return &MessagingAdapter{
++		mhandler:       h,
++		flowcontroller: nil,
++		AutoSettle:     true,
++		AutoAccept:     true,
++		AutoOpen:       true,
++		Prefetch:       10,
++		PeerCloseError: false,
++	}
++}
++
++func handleIf(h EventHandler, e Event) {
++	if h != nil {
++		h.HandleEvent(e)
++	}
++}
++
++// Handle a proton event by passing the corresponding MessagingEvent(s) to
++// the MessagingHandler.
++func (d *MessagingAdapter) HandleEvent(e Event) {
++	handleIf(d.flowcontroller, e)
++
++	switch e.Type() {
++
++	case EConnectionInit:
++		d.connection = endpointDelegator{
++			EConnectionRemoteOpen, EConnectionRemoteClose, EConnectionLocalOpen, EConnectionLocalClose,
++			MConnectionOpening, MConnectionOpened, MConnectionClosing, MConnectionClosed,
++			MConnectionError,
++			func(e Event) Endpoint { return e.Connection() },
++			d,
++		}
++		d.session = endpointDelegator{
++			ESessionRemoteOpen, ESessionRemoteClose, ESessionLocalOpen, ESessionLocalClose,
++			MSessionOpening, MSessionOpened, MSessionClosing, MSessionClosed,
++			MSessionError,
++			func(e Event) Endpoint { return e.Session() },
++			d,
++		}
++		d.link = endpointDelegator{
++			ELinkRemoteOpen, ELinkRemoteClose, ELinkLocalOpen, ELinkLocalClose,
++			MLinkOpening, MLinkOpened, MLinkClosing, MLinkClosed,
++			MLinkError,
++			func(e Event) Endpoint { return e.Link() },
++			d,
++		}
++		if d.Prefetch > 0 {
++			d.flowcontroller = cHandler{C.pn_flowcontroller(C.int(d.Prefetch))}
++		}
++		d.mhandler.HandleMessagingEvent(MStart, e)
++
++	case EConnectionRemoteOpen:
++
++		d.connection.HandleEvent(e)
++
++	case EConnectionRemoteClose:
++		d.connection.HandleEvent(e)
++		e.Connection().Transport().CloseTail()
++
++	case EConnectionLocalOpen, EConnectionLocalClose:
++		d.connection.HandleEvent(e)
++
++	case ESessionRemoteOpen, ESessionRemoteClose, ESessionLocalOpen, ESessionLocalClose:
++		d.session.HandleEvent(e)
++
++	case ELinkRemoteOpen:
++		e.Link().Source().Copy(e.Link().RemoteSource())
++		e.Link().Target().Copy(e.Link().RemoteTarget())
++		d.link.HandleEvent(e)
++
++	case ELinkRemoteClose, ELinkLocalOpen, ELinkLocalClose:
++		d.link.HandleEvent(e)
++
++	case ELinkFlow:
++		if e.Link().IsSender() && e.Link().Credit() > 0 {
++			d.mhandler.HandleMessagingEvent(MSendable, e)
++		}
++
++	case EDelivery:
++		if e.Delivery().Link().IsReceiver() {
++			d.incoming(e)
++		} else {
++			d.outgoing(e)
++		}
++
++	case ETransportClosed:
++		d.mhandler.HandleMessagingEvent(MDisconnected, e)
++	}
++}
++
++func (d *MessagingAdapter) incoming(e Event) (err error) {
++	delivery := e.Delivery()
++	if delivery.HasMessage() {
++		d.mhandler.HandleMessagingEvent(MMessage, e)
++		if d.AutoAccept && !delivery.Settled() {
++			delivery.Accept()
++		}
++		if delivery.Current() {
++			e.Link().Advance()
++		}
++	} else if delivery.Updated() && delivery.Settled() {
++		d.mhandler.HandleMessagingEvent(MSettled, e)
++	}
++	return
++}
++
++func (d *MessagingAdapter) outgoing(e Event) (err error) {
++	delivery := e.Delivery()
++	if delivery.Updated() {
++		switch delivery.Remote().Type() {
++		case Accepted:
++			d.mhandler.HandleMessagingEvent(MAccepted, e)
++		case Rejected:
++			d.mhandler.HandleMessagingEvent(MRejected, e)
++		case Released, Modified:
++			d.mhandler.HandleMessagingEvent(MReleased, e)
++		}
++		if err == nil && delivery.Settled() {
++			// The delivery was settled remotely, inform the local end.
++			d.mhandler.HandleMessagingEvent(MSettled, e)
++		}
++		if err == nil && d.AutoSettle {
++			delivery.Settle() // Local settle, don't mhandler MSettled till the remote end settles.
++		}
++	}
++	return
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/message.go
----------------------------------------------------------------------
diff --cc proton/message.go
index 0000000,0000000..c545b7e
new file mode 100644
--- /dev/null
+++ b/proton/message.go
@@@ -1,0 -1,0 +1,86 @@@
++/*
++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
++
++// #include <proton/types.h>
++// #include <proton/message.h>
++// #include <proton/codec.h>
++import "C"
++
++import (
++	"qpid.apache.org/internal"
++	"qpid.apache.org/amqp"
++)
++
++// HasMessage is true if all message data is available.
++// Equivalent to !d.isNil && d.Readable() && !d.Partial()
++func (d Delivery) HasMessage() bool { return !d.IsNil() && d.Readable() && !d.Partial() }
++
++// Message decodes the message containined in a delivery.
++//
++// Must be called in the correct link context with this delivery as the current message,
++// handling an MMessage event is always a safe context to call this function.
++//
++// Will return an error if message is incomplete or not current.
++func (delivery Delivery) Message() (m amqp.Message, err error) {
++	if !delivery.Readable() {
++		return nil, internal.Errorf("delivery is not readable")
++	}
++	if delivery.Partial() {
++		return nil, internal.Errorf("delivery has partial message")
++	}
++	data := make([]byte, delivery.Pending())
++	result := delivery.Link().Recv(data)
++	if result != len(data) {
++		return nil, internal.Errorf("cannot receive message: %s", internal.PnErrorCode(result))
++	}
++	m = amqp.NewMessage()
++	err = m.Decode(data)
++	return
++}
++
++// TODO aconway 2015-04-08: proper handling of delivery tags. Tag counter per link.
++var tags internal.IdCounter
++
++// Send sends a amqp.Message over a Link.
++// Returns a Delivery that can be use to determine the outcome of the message.
++func (link Link) Send(m amqp.Message) (Delivery, error) {
++	if !link.IsSender() {
++		return Delivery{}, internal.Errorf("attempt to send message on receiving link")
++	}
++	delivery := link.Delivery(tags.Next())
++	bytes, err := m.Encode(nil)
++	if err != nil {
++		return Delivery{}, internal.Errorf("cannot send mesage %s", err)
++	}
++	result := link.SendBytes(bytes)
++	link.Advance()
++	if result != len(bytes) {
++		if result < 0 {
++			return delivery, internal.Errorf("send failed %v", internal.PnErrorCode(result))
++		} else {
++			return delivery, internal.Errorf("send incomplete %v of %v", result, len(bytes))
++		}
++	}
++	if link.RemoteSndSettleMode() == SndSettled {
++		delivery.Settle()
++	}
++	return delivery, nil
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/proton_test.go
----------------------------------------------------------------------
diff --cc proton/proton_test.go
index 0000000,0000000..bb3f21c
new file mode 100644
--- /dev/null
+++ b/proton/proton_test.go
@@@ -1,0 -1,0 +1,27 @@@
++/*
++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
++
++import (
++	"testing"
++)
++
++// TODO aconway 2015-10-14: placeholder, add unit tests.
++func Test(*testing.T) {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/wrappers.go
----------------------------------------------------------------------
diff --cc proton/wrappers.go
index 0000000,0000000..45a6722
new file mode 100644
--- /dev/null
+++ b/proton/wrappers.go
@@@ -1,0 -1,0 +1,384 @@@
++/*
++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.
++*/
++
++// This file contains special-case wrapper functions or wrappers that don't follow
++// the pattern of genwrap.go.
++
++package proton
++
++//#include <proton/codec.h>
++//#include <proton/connection.h>
++//#include <proton/delivery.h>
++//#include <proton/event.h>
++//#include <proton/link.h>
++//#include <proton/link.h>
++//#include <proton/object.h>
++//#include <proton/session.h>
++//#include <proton/transport.h>
++//#include <stdlib.h>
++import "C"
++
++import (
++	"fmt"
++	"qpid.apache.org/amqp"
++	"qpid.apache.org/internal"
++	"reflect"
++	"time"
++	"unsafe"
++)
++
++// TODO aconway 2015-05-05: Documentation for generated types.
++
++// CHandle holds an unsafe.Pointer to a proton C struct, the C type depends on the
++// Go type implementing this interface. For low level, at-your-own-risk use only.
++type CHandle interface {
++	// CPtr returns the unsafe C pointer, equivalent to a C void*.
++	CPtr() unsafe.Pointer
++}
++
++// Incref increases the refcount of a proton value, which prevents the
++// underlying C struct being freed until you call Decref().
++//
++// It can be useful to "pin" a proton value in memory while it is in use by
++// goroutines other than the event loop goroutine. For example if you Incref() a
++// Link, the underlying object is not freed when the link is closed, so means
++// other goroutines can continue to safely use it as an index in a map or inject
++// it into the event loop goroutine. There will of course be an error if you try
++// to use a link after it is closed, but not a segmentation fault.
++func Incref(c CHandle) {
++	if p := c.CPtr(); p != nil {
++		C.pn_incref(p)
++	}
++}
++
++// Decref decreases the refcount of a proton value, freeing the underlying C
++// struct if this is the last reference.  Only call this if you previously
++// called Incref() for this value.
++func Decref(c CHandle) {
++	if p := c.CPtr(); p != nil {
++		C.pn_decref(p)
++	}
++}
++
++// Event is an AMQP protocol event.
++type Event struct {
++	pn         *C.pn_event_t
++	eventType  EventType
++	connection Connection
++	transport  Transport
++	session    Session
++	link       Link
++	delivery   Delivery
++	injecter   Injecter
++}
++
++func makeEvent(pn *C.pn_event_t, injecter Injecter) Event {
++	return Event{
++		pn:         pn,
++		eventType:  EventType(C.pn_event_type(pn)),
++		connection: Connection{C.pn_event_connection(pn)},
++		transport:  Transport{C.pn_event_transport(pn)},
++		session:    Session{C.pn_event_session(pn)},
++		link:       Link{C.pn_event_link(pn)},
++		delivery:   Delivery{C.pn_event_delivery(pn)},
++		injecter:   injecter,
++	}
++}
++func (e Event) IsNil() bool            { return e.eventType == EventType(0) }
++func (e Event) Type() EventType        { return e.eventType }
++func (e Event) Connection() Connection { return e.connection }
++func (e Event) Transport() Transport   { return e.transport }
++func (e Event) Session() Session       { return e.session }
++func (e Event) Link() Link             { return e.link }
++func (e Event) Delivery() Delivery     { return e.delivery }
++func (e Event) String() string         { return e.Type().String() }
++
++// Injecter should not be used in a handler function, but it can be passed to
++// other goroutines (via a channel or to a goroutine started by handler
++// functions) to let them inject functions back into the handlers goroutine.
++func (e Event) Injecter() Injecter { return e.injecter }
++
++// Data holds a pointer to decoded AMQP data.
++// Use amqp.marshal/unmarshal to access it as Go data types.
++//
++type Data struct{ pn *C.pn_data_t }
++
++func NewData(p unsafe.Pointer) Data { return Data{(*C.pn_data_t)(p)} }
++
++func (d Data) Free()                   { C.pn_data_free(d.pn) }
++func (d Data) Pointer() unsafe.Pointer { return unsafe.Pointer(d.pn) }
++func (d Data) Clear()                  { C.pn_data_clear(d.pn) }
++func (d Data) Rewind()                 { C.pn_data_rewind(d.pn) }
++func (d Data) Error() error {
++	return internal.PnError(unsafe.Pointer(C.pn_data_error(d.pn)))
++}
++
++// State holds the state flags for an AMQP endpoint.
++type State byte
++
++const (
++	SLocalUninit  State = C.PN_LOCAL_UNINIT
++	SLocalActive        = C.PN_LOCAL_ACTIVE
++	SLocalClosed        = C.PN_LOCAL_CLOSED
++	SRemoteUninit       = C.PN_REMOTE_UNINIT
++	SRemoteActive       = C.PN_REMOTE_ACTIVE
++	SRemoteClosed       = C.PN_REMOTE_CLOSED
++)
++
++// Has is True if bits & state is non 0.
++func (s State) Has(bits State) bool { return s&bits != 0 }
++
++func (s State) LocalUninit() bool  { return s.Has(SLocalUninit) }
++func (s State) LocalActive() bool  { return s.Has(SLocalActive) }
++func (s State) LocalClosed() bool  { return s.Has(SLocalClosed) }
++func (s State) RemoteUninit() bool { return s.Has(SRemoteUninit) }
++func (s State) RemoteActive() bool { return s.Has(SRemoteActive) }
++func (s State) RemoteClosed() bool { return s.Has(SRemoteClosed) }
++
++// Return a State containig just the local flags
++func (s State) Local() State { return State(s & C.PN_LOCAL_MASK) }
++
++// Return a State containig just the remote flags
++func (s State) Remote() State { return State(s & C.PN_REMOTE_MASK) }
++
++// Endpoint is the common interface for Connection, Link and Session.
++type Endpoint interface {
++	// State is the open/closed state.
++	State() State
++	// Open an endpoint.
++	Open()
++	// Close an endpoint.
++	Close()
++	// Condition holds a local error condition.
++	Condition() Condition
++	// RemoteCondition holds a remote error condition.
++	RemoteCondition() Condition
++	// Human readable name
++	String() string
++}
++
++// CloseError sets an error condition on an endpoint and closes the endpoint (if not already closed)
++func CloseError(e Endpoint, err error) {
++	if err != nil {
++		e.Condition().SetError(err)
++	}
++	if e.State().RemoteActive() {
++		e.Close()
++	}
++}
++
++// EndpointError returns the remote error if there is one, the local error if not
++// nil if there is no error.
++func EndpointError(e Endpoint) error {
++	err := e.RemoteCondition().Error()
++	if err == nil {
++		err = e.Condition().Error()
++	}
++	return err
++}
++
++const (
++	Received uint64 = C.PN_RECEIVED
++	Accepted        = C.PN_ACCEPTED
++	Rejected        = C.PN_REJECTED
++	Released        = C.PN_RELEASED
++	Modified        = C.PN_MODIFIED
++)
++
++// SettleAs is equivalent to d.Update(disposition); d.Settle()
++func (d Delivery) SettleAs(disposition uint64) {
++	d.Update(disposition)
++	d.Settle()
++}
++
++// Accept accepts and settles a delivery.
++func (d Delivery) Accept() { d.SettleAs(Accepted) }
++
++// Reject rejects and settles a delivery
++func (d Delivery) Reject() { d.SettleAs(Rejected) }
++
++// Release releases and settles a delivery
++// If delivered is true the delivery count for the message will be increased.
++func (d Delivery) Release(delivered bool) {
++	if delivered {
++		d.SettleAs(Modified)
++	} else {
++		d.SettleAs(Released)
++	}
++}
++
++type DeliveryTag struct{ pn C.pn_delivery_tag_t }
++
++func (t DeliveryTag) String() string { return C.GoStringN(t.pn.start, C.int(t.pn.size)) }
++
++func (l Link) Recv(buf []byte) int {
++	if len(buf) == 0 {
++		return 0
++	}
++	return int(C.pn_link_recv(l.pn, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))))
++}
++
++func (l Link) SendBytes(bytes []byte) int {
++	return int(C.pn_link_send(l.pn, cPtr(bytes), cLen(bytes)))
++}
++
++func pnTag(tag string) C.pn_delivery_tag_t {
++	bytes := []byte(tag)
++	return C.pn_dtag(cPtr(bytes), cLen(bytes))
++}
++
++func (l Link) Delivery(tag string) Delivery {
++	return Delivery{C.pn_delivery(l.pn, pnTag(tag))}
++}
++
++func (l Link) Connection() Connection { return l.Session().Connection() }
++
++// Human-readable link description including name, source, target and direction.
++func (l Link) String() string {
++	switch {
++	case l.IsNil():
++		return fmt.Sprintf("<nil-link>")
++	case l.IsSender():
++		return fmt.Sprintf("%s(%s->%s)", l.Name(), l.Source().Address(), l.Target().Address())
++	default:
++		return fmt.Sprintf("%s(%s<-%s)", l.Name(), l.Target().Address(), l.Source().Address())
++	}
++}
++
++func cPtr(b []byte) *C.char {
++	if len(b) == 0 {
++		return nil
++	}
++	return (*C.char)(unsafe.Pointer(&b[0]))
++}
++
++func cLen(b []byte) C.size_t {
++	return C.size_t(len(b))
++}
++
++func (s Session) Sender(name string) Link {
++	cname := C.CString(name)
++	defer C.free(unsafe.Pointer(cname))
++	return Link{C.pn_sender(s.pn, cname)}
++}
++
++func (s Session) Receiver(name string) Link {
++	cname := C.CString(name)
++	defer C.free(unsafe.Pointer(cname))
++	return Link{C.pn_receiver(s.pn, cname)}
++}
++
++// Context information per connection.
++type connectionContext struct {
++	str string
++}
++
++var connectionContexts = internal.MakeSafeMap()
++
++// Unique (per process) string identifier for a connection, useful for debugging.
++func (c Connection) String() string {
++	if cc, ok := connectionContexts.Get(c).(connectionContext); ok {
++		return cc.str
++	}
++	return fmt.Sprintf("%x", c.pn)
++}
++
++// Head functions don't follow the normal naming conventions so missed by the generator.
++
++func (c Connection) LinkHead(s State) Link {
++	return Link{C.pn_link_head(c.pn, C.pn_state_t(s))}
++}
++
++func (c Connection) SessionHead(s State) Session {
++	return Session{C.pn_session_head(c.pn, C.pn_state_t(s))}
++}
++
++func (c Connection) Links(state State) (links []Link) {
++	for l := c.LinkHead(state); !l.IsNil(); l = l.Next(state) {
++		links = append(links, l)
++	}
++	return
++}
++
++func (c Connection) Sessions(state State) (sessions []Session) {
++	for s := c.SessionHead(state); !s.IsNil(); s = s.Next(state) {
++		sessions = append(sessions, s)
++	}
++	return
++}
++
++func (s Session) String() string {
++	return fmt.Sprintf("%s/%p", s.Connection(), s.pn)
++}
++
++// Error returns an instance of amqp.Error or nil.
++func (c Condition) Error() error {
++	if c.IsNil() || !c.IsSet() {
++		return nil
++	}
++	return amqp.Error{c.Name(), c.Description()}
++}
++
++// Set a Go error into a condition.
++// If it is not an amqp.Condition use the error type as name, error string as description.
++func (c Condition) SetError(err error) {
++	if err != nil {
++		if cond, ok := err.(amqp.Error); ok {
++			c.SetName(cond.Name)
++			c.SetDescription(cond.Description)
++		} else {
++			c.SetName(reflect.TypeOf(err).Name())
++			c.SetDescription(err.Error())
++		}
++	}
++}
++
++func (c Connection) Session() (Session, error) {
++	s := Session{C.pn_session(c.pn)}
++	if s.IsNil() {
++		return s, Connection(c).Error()
++	}
++	return s, nil
++}
++
++// pnTime converts Go time.Time to Proton millisecond Unix time.
++func pnTime(t time.Time) C.pn_timestamp_t {
++	secs := t.Unix()
++	// Note: sub-second accuracy is not guaraunteed if the Unix time in
++	// nanoseconds cannot be represented by an int64 (sometime around year 2260)
++	msecs := (t.UnixNano() % int64(time.Second)) / int64(time.Millisecond)
++	return C.pn_timestamp_t(secs*1000 + msecs)
++}
++
++// goTime converts a pn_timestamp_t to a Go time.Time.
++func goTime(t C.pn_timestamp_t) time.Time {
++	secs := int64(t) / 1000
++	nsecs := (int64(t) % 1000) * int64(time.Millisecond)
++	return time.Unix(secs, nsecs)
++}
++
++// Special treatment for Transport.Head, return value is unsafe.Pointer not string
++func (t Transport) Head() unsafe.Pointer {
++	return unsafe.Pointer(C.pn_transport_head(t.pn))
++}
++
++// Special treatment for Transport.Push, takes []byte instead of char*, size
++func (t Transport) Push(bytes []byte) int {
++	return int(C.pn_transport_push(t.pn, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes))))
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/wrappers_gen.go
----------------------------------------------------------------------
diff --cc proton/wrappers_gen.go
index 0000000,0000000..074495d
new file mode 100644
--- /dev/null
+++ b/proton/wrappers_gen.go
@@@ -1,0 -1,0 +1,874 @@@
++/*
++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.
++*/
++
++//
++// NOTE: DO NOT EDIT. This file was generated by genwrap.go from the proton header files.
++// Update the generator and re-run if you need to modify this code.
++//
++
++package proton
++
++import (
++	"qpid.apache.org/internal"
++	"time"
++	"unsafe"
++)
++
++// #include <proton/types.h>
++// #include <proton/event.h>
++// #include <stdlib.h>
++// #include <proton/session.h>
++// #include <proton/link.h>
++// #include <proton/delivery.h>
++// #include <proton/disposition.h>
++// #include <proton/condition.h>
++// #include <proton/terminus.h>
++// #include <proton/connection.h>
++// #include <proton/transport.h>
++import "C"
++
++type EventType int
++
++const (
++	EConnectionInit         EventType = C.PN_CONNECTION_INIT
++	EConnectionBound        EventType = C.PN_CONNECTION_BOUND
++	EConnectionUnbound      EventType = C.PN_CONNECTION_UNBOUND
++	EConnectionLocalOpen    EventType = C.PN_CONNECTION_LOCAL_OPEN
++	EConnectionRemoteOpen   EventType = C.PN_CONNECTION_REMOTE_OPEN
++	EConnectionLocalClose   EventType = C.PN_CONNECTION_LOCAL_CLOSE
++	EConnectionRemoteClose  EventType = C.PN_CONNECTION_REMOTE_CLOSE
++	EConnectionFinal        EventType = C.PN_CONNECTION_FINAL
++	ESessionInit            EventType = C.PN_SESSION_INIT
++	ESessionLocalOpen       EventType = C.PN_SESSION_LOCAL_OPEN
++	ESessionRemoteOpen      EventType = C.PN_SESSION_REMOTE_OPEN
++	ESessionLocalClose      EventType = C.PN_SESSION_LOCAL_CLOSE
++	ESessionRemoteClose     EventType = C.PN_SESSION_REMOTE_CLOSE
++	ESessionFinal           EventType = C.PN_SESSION_FINAL
++	ELinkInit               EventType = C.PN_LINK_INIT
++	ELinkLocalOpen          EventType = C.PN_LINK_LOCAL_OPEN
++	ELinkRemoteOpen         EventType = C.PN_LINK_REMOTE_OPEN
++	ELinkLocalClose         EventType = C.PN_LINK_LOCAL_CLOSE
++	ELinkRemoteClose        EventType = C.PN_LINK_REMOTE_CLOSE
++	ELinkLocalDetach        EventType = C.PN_LINK_LOCAL_DETACH
++	ELinkRemoteDetach       EventType = C.PN_LINK_REMOTE_DETACH
++	ELinkFlow               EventType = C.PN_LINK_FLOW
++	ELinkFinal              EventType = C.PN_LINK_FINAL
++	EDelivery               EventType = C.PN_DELIVERY
++	ETransport              EventType = C.PN_TRANSPORT
++	ETransportAuthenticated EventType = C.PN_TRANSPORT_AUTHENTICATED
++	ETransportError         EventType = C.PN_TRANSPORT_ERROR
++	ETransportHeadClosed    EventType = C.PN_TRANSPORT_HEAD_CLOSED
++	ETransportTailClosed    EventType = C.PN_TRANSPORT_TAIL_CLOSED
++	ETransportClosed        EventType = C.PN_TRANSPORT_CLOSED
++)
++
++func (e EventType) String() string {
++	switch e {
++
++	case C.PN_CONNECTION_INIT:
++		return "ConnectionInit"
++	case C.PN_CONNECTION_BOUND:
++		return "ConnectionBound"
++	case C.PN_CONNECTION_UNBOUND:
++		return "ConnectionUnbound"
++	case C.PN_CONNECTION_LOCAL_OPEN:
++		return "ConnectionLocalOpen"
++	case C.PN_CONNECTION_REMOTE_OPEN:
++		return "ConnectionRemoteOpen"
++	case C.PN_CONNECTION_LOCAL_CLOSE:
++		return "ConnectionLocalClose"
++	case C.PN_CONNECTION_REMOTE_CLOSE:
++		return "ConnectionRemoteClose"
++	case C.PN_CONNECTION_FINAL:
++		return "ConnectionFinal"
++	case C.PN_SESSION_INIT:
++		return "SessionInit"
++	case C.PN_SESSION_LOCAL_OPEN:
++		return "SessionLocalOpen"
++	case C.PN_SESSION_REMOTE_OPEN:
++		return "SessionRemoteOpen"
++	case C.PN_SESSION_LOCAL_CLOSE:
++		return "SessionLocalClose"
++	case C.PN_SESSION_REMOTE_CLOSE:
++		return "SessionRemoteClose"
++	case C.PN_SESSION_FINAL:
++		return "SessionFinal"
++	case C.PN_LINK_INIT:
++		return "LinkInit"
++	case C.PN_LINK_LOCAL_OPEN:
++		return "LinkLocalOpen"
++	case C.PN_LINK_REMOTE_OPEN:
++		return "LinkRemoteOpen"
++	case C.PN_LINK_LOCAL_CLOSE:
++		return "LinkLocalClose"
++	case C.PN_LINK_REMOTE_CLOSE:
++		return "LinkRemoteClose"
++	case C.PN_LINK_LOCAL_DETACH:
++		return "LinkLocalDetach"
++	case C.PN_LINK_REMOTE_DETACH:
++		return "LinkRemoteDetach"
++	case C.PN_LINK_FLOW:
++		return "LinkFlow"
++	case C.PN_LINK_FINAL:
++		return "LinkFinal"
++	case C.PN_DELIVERY:
++		return "Delivery"
++	case C.PN_TRANSPORT:
++		return "Transport"
++	case C.PN_TRANSPORT_AUTHENTICATED:
++		return "TransportAuthenticated"
++	case C.PN_TRANSPORT_ERROR:
++		return "TransportError"
++	case C.PN_TRANSPORT_HEAD_CLOSED:
++		return "TransportHeadClosed"
++	case C.PN_TRANSPORT_TAIL_CLOSED:
++		return "TransportTailClosed"
++	case C.PN_TRANSPORT_CLOSED:
++		return "TransportClosed"
++	}
++	return "Unknown"
++}
++
++// Wrappers for declarations in session.h
++
++type Session struct{ pn *C.pn_session_t }
++
++func (s Session) IsNil() bool          { return s.pn == nil }
++func (s Session) CPtr() unsafe.Pointer { return unsafe.Pointer(s.pn) }
++func (s Session) Free() {
++	C.pn_session_free(s.pn)
++}
++func (s Session) State() State {
++	return State(C.pn_session_state(s.pn))
++}
++func (s Session) Error() error {
++	return internal.PnError(unsafe.Pointer(C.pn_session_error(s.pn)))
++}
++func (s Session) Condition() Condition {
++	return Condition{C.pn_session_condition(s.pn)}
++}
++func (s Session) RemoteCondition() Condition {
++	return Condition{C.pn_session_remote_condition(s.pn)}
++}
++func (s Session) Connection() Connection {
++	return Connection{C.pn_session_connection(s.pn)}
++}
++func (s Session) Open() {
++	C.pn_session_open(s.pn)
++}
++func (s Session) Close() {
++	C.pn_session_close(s.pn)
++}
++func (s Session) IncomingCapacity() uint {
++	return uint(C.pn_session_get_incoming_capacity(s.pn))
++}
++func (s Session) SetIncomingCapacity(capacity uint) {
++	C.pn_session_set_incoming_capacity(s.pn, C.size_t(capacity))
++}
++func (s Session) OutgoingWindow() uint {
++	return uint(C.pn_session_get_outgoing_window(s.pn))
++}
++func (s Session) SetOutgoingWindow(window uint) {
++	C.pn_session_set_outgoing_window(s.pn, C.size_t(window))
++}
++func (s Session) OutgoingBytes() uint {
++	return uint(C.pn_session_outgoing_bytes(s.pn))
++}
++func (s Session) IncomingBytes() uint {
++	return uint(C.pn_session_incoming_bytes(s.pn))
++}
++func (s Session) Next(state State) Session {
++	return Session{C.pn_session_next(s.pn, C.pn_state_t(state))}
++}
++
++// Wrappers for declarations in link.h
++
++type SndSettleMode C.pn_snd_settle_mode_t
++
++const (
++	SndUnsettled SndSettleMode = C.PN_SND_UNSETTLED
++	SndSettled   SndSettleMode = C.PN_SND_SETTLED
++	SndMixed     SndSettleMode = C.PN_SND_MIXED
++)
++
++func (e SndSettleMode) String() string {
++	switch e {
++
++	case C.PN_SND_UNSETTLED:
++		return "SndUnsettled"
++	case C.PN_SND_SETTLED:
++		return "SndSettled"
++	case C.PN_SND_MIXED:
++		return "SndMixed"
++	}
++	return "unknown"
++}
++
++type RcvSettleMode C.pn_rcv_settle_mode_t
++
++const (
++	RcvFirst  RcvSettleMode = C.PN_RCV_FIRST
++	RcvSecond RcvSettleMode = C.PN_RCV_SECOND
++)
++
++func (e RcvSettleMode) String() string {
++	switch e {
++
++	case C.PN_RCV_FIRST:
++		return "RcvFirst"
++	case C.PN_RCV_SECOND:
++		return "RcvSecond"
++	}
++	return "unknown"
++}
++
++type Link struct{ pn *C.pn_link_t }
++
++func (l Link) IsNil() bool          { return l.pn == nil }
++func (l Link) CPtr() unsafe.Pointer { return unsafe.Pointer(l.pn) }
++func (l Link) Free() {
++	C.pn_link_free(l.pn)
++}
++func (l Link) Name() string {
++	return C.GoString(C.pn_link_name(l.pn))
++}
++func (l Link) IsSender() bool {
++	return bool(C.pn_link_is_sender(l.pn))
++}
++func (l Link) IsReceiver() bool {
++	return bool(C.pn_link_is_receiver(l.pn))
++}
++func (l Link) State() State {
++	return State(C.pn_link_state(l.pn))
++}
++func (l Link) Error() error {
++	return internal.PnError(unsafe.Pointer(C.pn_link_error(l.pn)))
++}
++func (l Link) Condition() Condition {
++	return Condition{C.pn_link_condition(l.pn)}
++}
++func (l Link) RemoteCondition() Condition {
++	return Condition{C.pn_link_remote_condition(l.pn)}
++}
++func (l Link) Session() Session {
++	return Session{C.pn_link_session(l.pn)}
++}
++func (l Link) Next(state State) Link {
++	return Link{C.pn_link_next(l.pn, C.pn_state_t(state))}
++}
++func (l Link) Open() {
++	C.pn_link_open(l.pn)
++}
++func (l Link) Close() {
++	C.pn_link_close(l.pn)
++}
++func (l Link) Detach() {
++	C.pn_link_detach(l.pn)
++}
++func (l Link) Source() Terminus {
++	return Terminus{C.pn_link_source(l.pn)}
++}
++func (l Link) Target() Terminus {
++	return Terminus{C.pn_link_target(l.pn)}
++}
++func (l Link) RemoteSource() Terminus {
++	return Terminus{C.pn_link_remote_source(l.pn)}
++}
++func (l Link) RemoteTarget() Terminus {
++	return Terminus{C.pn_link_remote_target(l.pn)}
++}
++func (l Link) Current() Delivery {
++	return Delivery{C.pn_link_current(l.pn)}
++}
++func (l Link) Advance() bool {
++	return bool(C.pn_link_advance(l.pn))
++}
++func (l Link) Credit() int {
++	return int(C.pn_link_credit(l.pn))
++}
++func (l Link) Queued() int {
++	return int(C.pn_link_queued(l.pn))
++}
++func (l Link) RemoteCredit() int {
++	return int(C.pn_link_remote_credit(l.pn))
++}
++func (l Link) IsDrain() bool {
++	return bool(C.pn_link_get_drain(l.pn))
++}
++func (l Link) Drained() int {
++	return int(C.pn_link_drained(l.pn))
++}
++func (l Link) Available() int {
++	return int(C.pn_link_available(l.pn))
++}
++func (l Link) SndSettleMode() SndSettleMode {
++	return SndSettleMode(C.pn_link_snd_settle_mode(l.pn))
++}
++func (l Link) RcvSettleMode() RcvSettleMode {
++	return RcvSettleMode(C.pn_link_rcv_settle_mode(l.pn))
++}
++func (l Link) SetSndSettleMode(mode SndSettleMode) {
++	C.pn_link_set_snd_settle_mode(l.pn, C.pn_snd_settle_mode_t(mode))
++}
++func (l Link) SetRcvSettleMode(mode RcvSettleMode) {
++	C.pn_link_set_rcv_settle_mode(l.pn, C.pn_rcv_settle_mode_t(mode))
++}
++func (l Link) RemoteSndSettleMode() SndSettleMode {
++	return SndSettleMode(C.pn_link_remote_snd_settle_mode(l.pn))
++}
++func (l Link) RemoteRcvSettleMode() RcvSettleMode {
++	return RcvSettleMode(C.pn_link_remote_rcv_settle_mode(l.pn))
++}
++func (l Link) Unsettled() int {
++	return int(C.pn_link_unsettled(l.pn))
++}
++func (l Link) Offered(credit int) {
++	C.pn_link_offered(l.pn, C.int(credit))
++}
++func (l Link) Flow(credit int) {
++	C.pn_link_flow(l.pn, C.int(credit))
++}
++func (l Link) Drain(credit int) {
++	C.pn_link_drain(l.pn, C.int(credit))
++}
++func (l Link) SetDrain(drain bool) {
++	C.pn_link_set_drain(l.pn, C.bool(drain))
++}
++func (l Link) Draining() bool {
++	return bool(C.pn_link_draining(l.pn))
++}
++
++// Wrappers for declarations in delivery.h
++
++type Delivery struct{ pn *C.pn_delivery_t }
++
++func (d Delivery) IsNil() bool          { return d.pn == nil }
++func (d Delivery) CPtr() unsafe.Pointer { return unsafe.Pointer(d.pn) }
++func (d Delivery) Tag() DeliveryTag {
++	return DeliveryTag{C.pn_delivery_tag(d.pn)}
++}
++func (d Delivery) Link() Link {
++	return Link{C.pn_delivery_link(d.pn)}
++}
++func (d Delivery) Local() Disposition {
++	return Disposition{C.pn_delivery_local(d.pn)}
++}
++func (d Delivery) LocalState() uint64 {
++	return uint64(C.pn_delivery_local_state(d.pn))
++}
++func (d Delivery) Remote() Disposition {
++	return Disposition{C.pn_delivery_remote(d.pn)}
++}
++func (d Delivery) RemoteState() uint64 {
++	return uint64(C.pn_delivery_remote_state(d.pn))
++}
++func (d Delivery) Settled() bool {
++	return bool(C.pn_delivery_settled(d.pn))
++}
++func (d Delivery) Pending() uint {
++	return uint(C.pn_delivery_pending(d.pn))
++}
++func (d Delivery) Partial() bool {
++	return bool(C.pn_delivery_partial(d.pn))
++}
++func (d Delivery) Writable() bool {
++	return bool(C.pn_delivery_writable(d.pn))
++}
++func (d Delivery) Readable() bool {
++	return bool(C.pn_delivery_readable(d.pn))
++}
++func (d Delivery) Updated() bool {
++	return bool(C.pn_delivery_updated(d.pn))
++}
++func (d Delivery) Update(state uint64) {
++	C.pn_delivery_update(d.pn, C.uint64_t(state))
++}
++func (d Delivery) Clear() {
++	C.pn_delivery_clear(d.pn)
++}
++func (d Delivery) Current() bool {
++	return bool(C.pn_delivery_current(d.pn))
++}
++func (d Delivery) Settle() {
++	C.pn_delivery_settle(d.pn)
++}
++func (d Delivery) Dump() {
++	C.pn_delivery_dump(d.pn)
++}
++func (d Delivery) Buffered() bool {
++	return bool(C.pn_delivery_buffered(d.pn))
++}
++
++// Wrappers for declarations in disposition.h
++
++type Disposition struct{ pn *C.pn_disposition_t }
++
++func (d Disposition) IsNil() bool          { return d.pn == nil }
++func (d Disposition) CPtr() unsafe.Pointer { return unsafe.Pointer(d.pn) }
++func (d Disposition) Type() uint64 {
++	return uint64(C.pn_disposition_type(d.pn))
++}
++func (d Disposition) Condition() Condition {
++	return Condition{C.pn_disposition_condition(d.pn)}
++}
++func (d Disposition) Data() Data {
++	return Data{C.pn_disposition_data(d.pn)}
++}
++func (d Disposition) SectionNumber() uint16 {
++	return uint16(C.pn_disposition_get_section_number(d.pn))
++}
++func (d Disposition) SetSectionNumber(section_number uint16) {
++	C.pn_disposition_set_section_number(d.pn, C.uint32_t(section_number))
++}
++func (d Disposition) SectionOffset() uint64 {
++	return uint64(C.pn_disposition_get_section_offset(d.pn))
++}
++func (d Disposition) SetSectionOffset(section_offset uint64) {
++	C.pn_disposition_set_section_offset(d.pn, C.uint64_t(section_offset))
++}
++func (d Disposition) IsFailed() bool {
++	return bool(C.pn_disposition_is_failed(d.pn))
++}
++func (d Disposition) SetFailed(failed bool) {
++	C.pn_disposition_set_failed(d.pn, C.bool(failed))
++}
++func (d Disposition) IsUndeliverable() bool {
++	return bool(C.pn_disposition_is_undeliverable(d.pn))
++}
++func (d Disposition) SetUndeliverable(undeliverable bool) {
++	C.pn_disposition_set_undeliverable(d.pn, C.bool(undeliverable))
++}
++func (d Disposition) Annotations() Data {
++	return Data{C.pn_disposition_annotations(d.pn)}
++}
++
++// Wrappers for declarations in condition.h
++
++type Condition struct{ pn *C.pn_condition_t }
++
++func (c Condition) IsNil() bool          { return c.pn == nil }
++func (c Condition) CPtr() unsafe.Pointer { return unsafe.Pointer(c.pn) }
++func (c Condition) IsSet() bool {
++	return bool(C.pn_condition_is_set(c.pn))
++}
++func (c Condition) Clear() {
++	C.pn_condition_clear(c.pn)
++}
++func (c Condition) Name() string {
++	return C.GoString(C.pn_condition_get_name(c.pn))
++}
++func (c Condition) SetName(name string) int {
++	nameC := C.CString(name)
++	defer C.free(unsafe.Pointer(nameC))
++
++	return int(C.pn_condition_set_name(c.pn, nameC))
++}
++func (c Condition) Description() string {
++	return C.GoString(C.pn_condition_get_description(c.pn))
++}
++func (c Condition) SetDescription(description string) int {
++	descriptionC := C.CString(description)
++	defer C.free(unsafe.Pointer(descriptionC))
++
++	return int(C.pn_condition_set_description(c.pn, descriptionC))
++}
++func (c Condition) Info() Data {
++	return Data{C.pn_condition_info(c.pn)}
++}
++func (c Condition) IsRedirect() bool {
++	return bool(C.pn_condition_is_redirect(c.pn))
++}
++func (c Condition) RedirectHost() string {
++	return C.GoString(C.pn_condition_redirect_host(c.pn))
++}
++func (c Condition) RedirectPort() int {
++	return int(C.pn_condition_redirect_port(c.pn))
++}
++
++// Wrappers for declarations in terminus.h
++
++type TerminusType C.pn_terminus_type_t
++
++const (
++	Unspecified TerminusType = C.PN_UNSPECIFIED
++	Source      TerminusType = C.PN_SOURCE
++	Target      TerminusType = C.PN_TARGET
++	Coordinator TerminusType = C.PN_COORDINATOR
++)
++
++func (e TerminusType) String() string {
++	switch e {
++
++	case C.PN_UNSPECIFIED:
++		return "Unspecified"
++	case C.PN_SOURCE:
++		return "Source"
++	case C.PN_TARGET:
++		return "Target"
++	case C.PN_COORDINATOR:
++		return "Coordinator"
++	}
++	return "unknown"
++}
++
++type Durability C.pn_durability_t
++
++const (
++	Nondurable    Durability = C.PN_NONDURABLE
++	Configuration Durability = C.PN_CONFIGURATION
++	Deliveries    Durability = C.PN_DELIVERIES
++)
++
++func (e Durability) String() string {
++	switch e {
++
++	case C.PN_NONDURABLE:
++		return "Nondurable"
++	case C.PN_CONFIGURATION:
++		return "Configuration"
++	case C.PN_DELIVERIES:
++		return "Deliveries"
++	}
++	return "unknown"
++}
++
++type ExpiryPolicy C.pn_expiry_policy_t
++
++const (
++	ExpireWithLink       ExpiryPolicy = C.PN_EXPIRE_WITH_LINK
++	ExpireWithSession    ExpiryPolicy = C.PN_EXPIRE_WITH_SESSION
++	ExpireWithConnection ExpiryPolicy = C.PN_EXPIRE_WITH_CONNECTION
++	ExpireNever          ExpiryPolicy = C.PN_EXPIRE_NEVER
++)
++
++func (e ExpiryPolicy) String() string {
++	switch e {
++
++	case C.PN_EXPIRE_WITH_LINK:
++		return "ExpireWithLink"
++	case C.PN_EXPIRE_WITH_SESSION:
++		return "ExpireWithSession"
++	case C.PN_EXPIRE_WITH_CONNECTION:
++		return "ExpireWithConnection"
++	case C.PN_EXPIRE_NEVER:
++		return "ExpireNever"
++	}
++	return "unknown"
++}
++
++type DistributionMode C.pn_distribution_mode_t
++
++const (
++	DistModeUnspecified DistributionMode = C.PN_DIST_MODE_UNSPECIFIED
++	DistModeCopy        DistributionMode = C.PN_DIST_MODE_COPY
++	DistModeMove        DistributionMode = C.PN_DIST_MODE_MOVE
++)
++
++func (e DistributionMode) String() string {
++	switch e {
++
++	case C.PN_DIST_MODE_UNSPECIFIED:
++		return "DistModeUnspecified"
++	case C.PN_DIST_MODE_COPY:
++		return "DistModeCopy"
++	case C.PN_DIST_MODE_MOVE:
++		return "DistModeMove"
++	}
++	return "unknown"
++}
++
++type Terminus struct{ pn *C.pn_terminus_t }
++
++func (t Terminus) IsNil() bool          { return t.pn == nil }
++func (t Terminus) CPtr() unsafe.Pointer { return unsafe.Pointer(t.pn) }
++func (t Terminus) Type() TerminusType {
++	return TerminusType(C.pn_terminus_get_type(t.pn))
++}
++func (t Terminus) SetType(type_ TerminusType) int {
++	return int(C.pn_terminus_set_type(t.pn, C.pn_terminus_type_t(type_)))
++}
++func (t Terminus) Address() string {
++	return C.GoString(C.pn_terminus_get_address(t.pn))
++}
++func (t Terminus) SetAddress(address string) int {
++	addressC := C.CString(address)
++	defer C.free(unsafe.Pointer(addressC))
++
++	return int(C.pn_terminus_set_address(t.pn, addressC))
++}
++func (t Terminus) SetDistributionMode(mode DistributionMode) int {
++	return int(C.pn_terminus_set_distribution_mode(t.pn, C.pn_distribution_mode_t(mode)))
++}
++func (t Terminus) Durability() Durability {
++	return Durability(C.pn_terminus_get_durability(t.pn))
++}
++func (t Terminus) SetDurability(durability Durability) int {
++	return int(C.pn_terminus_set_durability(t.pn, C.pn_durability_t(durability)))
++}
++func (t Terminus) ExpiryPolicy() ExpiryPolicy {
++	return ExpiryPolicy(C.pn_terminus_get_expiry_policy(t.pn))
++}
++func (t Terminus) SetExpiryPolicy(policy ExpiryPolicy) int {
++	return int(C.pn_terminus_set_expiry_policy(t.pn, C.pn_expiry_policy_t(policy)))
++}
++func (t Terminus) Timeout() time.Duration {
++	return (time.Duration(C.pn_terminus_get_timeout(t.pn)) * time.Second)
++}
++func (t Terminus) SetTimeout(timeout time.Duration) int {
++	return int(C.pn_terminus_set_timeout(t.pn, C.pn_seconds_t(timeout)))
++}
++func (t Terminus) IsDynamic() bool {
++	return bool(C.pn_terminus_is_dynamic(t.pn))
++}
++func (t Terminus) SetDynamic(dynamic bool) int {
++	return int(C.pn_terminus_set_dynamic(t.pn, C.bool(dynamic)))
++}
++func (t Terminus) Properties() Data {
++	return Data{C.pn_terminus_properties(t.pn)}
++}
++func (t Terminus) Capabilities() Data {
++	return Data{C.pn_terminus_capabilities(t.pn)}
++}
++func (t Terminus) Outcomes() Data {
++	return Data{C.pn_terminus_outcomes(t.pn)}
++}
++func (t Terminus) Filter() Data {
++	return Data{C.pn_terminus_filter(t.pn)}
++}
++func (t Terminus) Copy(src Terminus) int {
++	return int(C.pn_terminus_copy(t.pn, src.pn))
++}
++
++// Wrappers for declarations in connection.h
++
++type Connection struct{ pn *C.pn_connection_t }
++
++func (c Connection) IsNil() bool          { return c.pn == nil }
++func (c Connection) CPtr() unsafe.Pointer { return unsafe.Pointer(c.pn) }
++func (c Connection) Free() {
++	C.pn_connection_free(c.pn)
++}
++func (c Connection) Release() {
++	C.pn_connection_release(c.pn)
++}
++func (c Connection) Error() error {
++	return internal.PnError(unsafe.Pointer(C.pn_connection_error(c.pn)))
++}
++func (c Connection) State() State {
++	return State(C.pn_connection_state(c.pn))
++}
++func (c Connection) Open() {
++	C.pn_connection_open(c.pn)
++}
++func (c Connection) Close() {
++	C.pn_connection_close(c.pn)
++}
++func (c Connection) Reset() {
++	C.pn_connection_reset(c.pn)
++}
++func (c Connection) Condition() Condition {
++	return Condition{C.pn_connection_condition(c.pn)}
++}
++func (c Connection) RemoteCondition() Condition {
++	return Condition{C.pn_connection_remote_condition(c.pn)}
++}
++func (c Connection) Container() string {
++	return C.GoString(C.pn_connection_get_container(c.pn))
++}
++func (c Connection) SetContainer(container string) {
++	containerC := C.CString(container)
++	defer C.free(unsafe.Pointer(containerC))
++
++	C.pn_connection_set_container(c.pn, containerC)
++}
++func (c Connection) SetUser(user string) {
++	userC := C.CString(user)
++	defer C.free(unsafe.Pointer(userC))
++
++	C.pn_connection_set_user(c.pn, userC)
++}
++func (c Connection) SetPassword(password string) {
++	passwordC := C.CString(password)
++	defer C.free(unsafe.Pointer(passwordC))
++
++	C.pn_connection_set_password(c.pn, passwordC)
++}
++func (c Connection) User() string {
++	return C.GoString(C.pn_connection_get_user(c.pn))
++}
++func (c Connection) Hostname() string {
++	return C.GoString(C.pn_connection_get_hostname(c.pn))
++}
++func (c Connection) SetHostname(hostname string) {
++	hostnameC := C.CString(hostname)
++	defer C.free(unsafe.Pointer(hostnameC))
++
++	C.pn_connection_set_hostname(c.pn, hostnameC)
++}
++func (c Connection) RemoteContainer() string {
++	return C.GoString(C.pn_connection_remote_container(c.pn))
++}
++func (c Connection) RemoteHostname() string {
++	return C.GoString(C.pn_connection_remote_hostname(c.pn))
++}
++func (c Connection) OfferedCapabilities() Data {
++	return Data{C.pn_connection_offered_capabilities(c.pn)}
++}
++func (c Connection) DesiredCapabilities() Data {
++	return Data{C.pn_connection_desired_capabilities(c.pn)}
++}
++func (c Connection) Properties() Data {
++	return Data{C.pn_connection_properties(c.pn)}
++}
++func (c Connection) RemoteOfferedCapabilities() Data {
++	return Data{C.pn_connection_remote_offered_capabilities(c.pn)}
++}
++func (c Connection) RemoteDesiredCapabilities() Data {
++	return Data{C.pn_connection_remote_desired_capabilities(c.pn)}
++}
++func (c Connection) RemoteProperties() Data {
++	return Data{C.pn_connection_remote_properties(c.pn)}
++}
++func (c Connection) Transport() Transport {
++	return Transport{C.pn_connection_transport(c.pn)}
++}
++
++// Wrappers for declarations in transport.h
++
++type Transport struct{ pn *C.pn_transport_t }
++
++func (t Transport) IsNil() bool          { return t.pn == nil }
++func (t Transport) CPtr() unsafe.Pointer { return unsafe.Pointer(t.pn) }
++func (t Transport) SetServer() {
++	C.pn_transport_set_server(t.pn)
++}
++func (t Transport) Free() {
++	C.pn_transport_free(t.pn)
++}
++func (t Transport) User() string {
++	return C.GoString(C.pn_transport_get_user(t.pn))
++}
++func (t Transport) RequireAuth(required bool) {
++	C.pn_transport_require_auth(t.pn, C.bool(required))
++}
++func (t Transport) IsAuthenticated() bool {
++	return bool(C.pn_transport_is_authenticated(t.pn))
++}
++func (t Transport) RequireEncryption(required bool) {
++	C.pn_transport_require_encryption(t.pn, C.bool(required))
++}
++func (t Transport) IsEncrypted() bool {
++	return bool(C.pn_transport_is_encrypted(t.pn))
++}
++func (t Transport) Condition() Condition {
++	return Condition{C.pn_transport_condition(t.pn)}
++}
++func (t Transport) Error() error {
++	return internal.PnError(unsafe.Pointer(C.pn_transport_error(t.pn)))
++}
++func (t Transport) Bind(connection Connection) int {
++	return int(C.pn_transport_bind(t.pn, connection.pn))
++}
++func (t Transport) Unbind() int {
++	return int(C.pn_transport_unbind(t.pn))
++}
++func (t Transport) Log(message string) {
++	messageC := C.CString(message)
++	defer C.free(unsafe.Pointer(messageC))
++
++	C.pn_transport_log(t.pn, messageC)
++}
++func (t Transport) ChannelMax() uint32 {
++	return uint32(C.pn_transport_get_channel_max(t.pn))
++}
++func (t Transport) SetChannelMax(channel_max uint32) int {
++	return int(C.pn_transport_set_channel_max(t.pn, C.uint16_t(channel_max)))
++}
++func (t Transport) RemoteChannelMax() uint32 {
++	return uint32(C.pn_transport_remote_channel_max(t.pn))
++}
++func (t Transport) MaxFrame() uint16 {
++	return uint16(C.pn_transport_get_max_frame(t.pn))
++}
++func (t Transport) SetMaxFrame(size uint16) {
++	C.pn_transport_set_max_frame(t.pn, C.uint32_t(size))
++}
++func (t Transport) RemoteMaxFrame() uint16 {
++	return uint16(C.pn_transport_get_remote_max_frame(t.pn))
++}
++func (t Transport) IdleTimeout() time.Duration {
++	return (time.Duration(C.pn_transport_get_idle_timeout(t.pn)) * time.Millisecond)
++}
++func (t Transport) SetIdleTimeout(timeout time.Duration) {
++	C.pn_transport_set_idle_timeout(t.pn, C.pn_millis_t(timeout))
++}
++func (t Transport) RemoteIdleTimeout() time.Duration {
++	return (time.Duration(C.pn_transport_get_remote_idle_timeout(t.pn)) * time.Millisecond)
++}
++func (t Transport) Input(bytes string, available uint) int {
++	bytesC := C.CString(bytes)
++	defer C.free(unsafe.Pointer(bytesC))
++
++	return int(C.pn_transport_input(t.pn, bytesC, C.size_t(available)))
++}
++func (t Transport) Output(bytes string, size uint) int {
++	bytesC := C.CString(bytes)
++	defer C.free(unsafe.Pointer(bytesC))
++
++	return int(C.pn_transport_output(t.pn, bytesC, C.size_t(size)))
++}
++func (t Transport) Capacity() int {
++	return int(C.pn_transport_capacity(t.pn))
++}
++func (t Transport) Tail() string {
++	return C.GoString(C.pn_transport_tail(t.pn))
++}
++func (t Transport) Process(size uint) int {
++	return int(C.pn_transport_process(t.pn, C.size_t(size)))
++}
++func (t Transport) CloseTail() int {
++	return int(C.pn_transport_close_tail(t.pn))
++}
++func (t Transport) Pending() int {
++	return int(C.pn_transport_pending(t.pn))
++}
++func (t Transport) Peek(dst string, size uint) int {
++	dstC := C.CString(dst)
++	defer C.free(unsafe.Pointer(dstC))
++
++	return int(C.pn_transport_peek(t.pn, dstC, C.size_t(size)))
++}
++func (t Transport) Pop(size uint) {
++	C.pn_transport_pop(t.pn, C.size_t(size))
++}
++func (t Transport) CloseHead() int {
++	return int(C.pn_transport_close_head(t.pn))
++}
++func (t Transport) Quiesced() bool {
++	return bool(C.pn_transport_quiesced(t.pn))
++}
++func (t Transport) Closed() bool {
++	return bool(C.pn_transport_closed(t.pn))
++}
++func (t Transport) Tick(now time.Time) time.Time {
++	return goTime(C.pn_transport_tick(t.pn, pnTime(now)))
++}
++func (t Transport) Connection() Connection {
++	return Connection{C.pn_transport_connection(t.pn)}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/readme-branch.md
----------------------------------------------------------------------
diff --cc readme-branch.md
index 0000000,0000000..b488eea
new file mode 100644
--- /dev/null
+++ b/readme-branch.md
@@@ -1,0 -1,0 +1,7 @@@
++`go1` is a special branch for the `go get` command, it contains just the Go subtree of proton.
++
++Created with: `git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b go1`
++Update with:  `git checkout go1; git merge -s subtree master`
++
++To see the branch description: `git config branch.go1.description`
++


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


[06/50] [abbrv] qpid-proton git commit: PROTON-1011: Go example of event driven broker. Package renaming and some new features.

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
index 63dc452..5dc8727 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
@@ -34,7 +34,7 @@ import (
 	"fmt"
 	"io"
 	"net"
-	"qpid.apache.org/proton/internal"
+	"qpid.apache.org/internal"
 	"sync"
 	"unsafe"
 )
@@ -107,7 +107,7 @@ func (b *bufferChan) buffer() []byte {
 //
 type Engine struct {
 	// Error is set on exit from Run() if there was an error.
-	err    internal.FirstError
+	err    internal.ErrorHolder
 	inject chan func()
 
 	conn       net.Conn
@@ -127,14 +127,14 @@ const bufferSize = 4096
 var engines = internal.MakeSafeMap()
 
 // NewEngine initializes a engine with a connection and handlers. To start it running:
-//    p := NewEngine(...)
-//    go run p.Run()
+//    eng := NewEngine(...)
+//    go run eng.Run()
 // The goroutine will exit when the engine is closed or disconnected.
 // You can check for errors on Engine.Error.
 //
 func NewEngine(conn net.Conn, handlers ...EventHandler) (*Engine, error) {
 	// Save the connection ID for Connection.String()
-	p := &Engine{
+	eng := &Engine{
 		inject:     make(chan func()),
 		conn:       conn,
 		transport:  Transport{C.pn_transport()},
@@ -145,7 +145,7 @@ func NewEngine(conn net.Conn, handlers ...EventHandler) (*Engine, error) {
 		write:      newBufferChan(bufferSize),
 		running:    make(chan struct{}),
 	}
-	if p.transport.IsNil() || p.connection.IsNil() || p.collector == nil {
+	if eng.transport.IsNil() || eng.connection.IsNil() || eng.collector == nil {
 		return nil, internal.Errorf("failed to allocate engine")
 	}
 
@@ -154,27 +154,27 @@ func NewEngine(conn net.Conn, handlers ...EventHandler) (*Engine, error) {
 	// to run connection.
 
 	// Unique container-id by default.
-	p.connection.SetContainer(internal.UUID4().String())
-	pnErr := p.transport.Bind(p.connection)
+	eng.connection.SetContainer(internal.UUID4().String())
+	pnErr := eng.transport.Bind(eng.connection)
 	if pnErr != 0 {
 		return nil, internal.Errorf("cannot setup engine: %s", internal.PnErrorCode(pnErr))
 	}
-	C.pn_connection_collect(p.connection.pn, p.collector)
-	p.connection.Open()
-	connectionContexts.Put(p.connection, connectionContext{p, p.String()})
-	return p, nil
+	C.pn_connection_collect(eng.connection.pn, eng.collector)
+	eng.connection.Open()
+	connectionContexts.Put(eng.connection, connectionContext{eng, eng.String()})
+	return eng, nil
 }
 
-func (p *Engine) String() string {
-	return fmt.Sprintf("%s-%s", p.conn.LocalAddr(), p.conn.RemoteAddr())
+func (eng *Engine) String() string {
+	return fmt.Sprintf("%s-%s", eng.conn.LocalAddr(), eng.conn.RemoteAddr())
 }
 
-func (p *Engine) Id() string {
-	return fmt.Sprintf("%p", &p)
+func (eng *Engine) Id() string {
+	return fmt.Sprintf("%eng", &eng)
 }
 
-func (p *Engine) Error() error {
-	return p.err.Get()
+func (eng *Engine) Error() error {
+	return eng.err.Get()
 }
 
 // Inject a function into the Engine's event loop.
@@ -189,27 +189,27 @@ func (p *Engine) Error() error {
 //
 // Returns a non-nil error if the engine is closed before the function could be
 // injected.
-func (p *Engine) Inject(f func()) error {
+func (eng *Engine) Inject(f func()) error {
 	select {
-	case p.inject <- f:
+	case eng.inject <- f:
 		return nil
-	case <-p.running:
-		return p.Error()
+	case <-eng.running:
+		return eng.Error()
 	}
 }
 
 // InjectWait is like Inject but does not return till f() has completed or the
 // engine is closed, and returns an error value from f()
-func (p *Engine) InjectWait(f func() error) error {
+func (eng *Engine) InjectWait(f func() error) error {
 	done := make(chan error)
 	defer close(done)
-	err := p.Inject(func() { done <- f() })
+	err := eng.Inject(func() { done <- f() })
 	if err != nil {
 		return err
 	}
 	select {
-	case <-p.running:
-		return p.Error()
+	case <-eng.running:
+		return eng.Error()
 	case err := <-done:
 		return err
 	}
@@ -219,119 +219,131 @@ func (p *Engine) InjectWait(f func() error) error {
 // the incoming connnection such as use of SASL and SSL.
 // Must be called before Run()
 //
-func (p *Engine) Server() { p.transport.SetServer() }
+func (eng *Engine) Server() { eng.transport.SetServer() }
 
 // Close the engine's connection, returns when the engine has exited.
-func (p *Engine) Close(err error) {
-	p.Inject(func() {
-		if err != nil {
-			p.connection.Condition().SetError(err)
-		}
-		p.connection.Close()
+func (eng *Engine) Close(err error) {
+	eng.Inject(func() {
+		CloseError(eng.connection, err)
 	})
-	<-p.running
+	<-eng.running
 }
 
 // Disconnect the engine's connection without and AMQP close, returns when the engine has exited.
-func (p *Engine) Disconnect(err error) {
+func (eng *Engine) Disconnect(err error) {
 	if err != nil {
-		p.err.Set(err)
+		eng.err.Set(err)
 	}
-	p.conn.Close()
-	<-p.running
+	eng.conn.Close()
+	<-eng.running
 }
 
-// Run the engine. Normally called in a goroutine as: go engine.Run()
-// Engine.Run() will exit when the engine is closed or disconnected.
-// You can check for errors after exit with Engine.Error().
+// Run the engine. Engine.Run() will exit when the engine is closed or
+// disconnected.  You can check for errors after exit with Engine.Error().
 //
-func (p *Engine) Run() {
-	// Signal errors from the read/write goroutines. Don't block if we don't
-	// read all the errors, we only care about the first.
-	error := make(chan error, 2)
+func (eng *Engine) Run() error {
 	wait := sync.WaitGroup{}
-	wait.Add(2)
+	wait.Add(2) // Read and write goroutines
 
-	go func() { // Read goroutine
+	readErr := make(chan error, 1) // Don't block
+	go func() {                    // Read goroutine
 		defer wait.Done()
 		for {
-			rbuf := p.read.buffer()
-			n, err := p.conn.Read(rbuf)
+			rbuf := eng.read.buffer()
+			n, err := eng.conn.Read(rbuf)
 			if n > 0 {
-				p.read.buffers <- rbuf[:n]
-			} else if err != nil {
-				close(p.read.buffers)
-				error <- err
+				eng.read.buffers <- rbuf[:n]
+			}
+			if err != nil {
+				readErr <- err
+				close(readErr)
+				close(eng.read.buffers)
 				return
 			}
 		}
 	}()
 
-	go func() { // Write goroutine
+	writeErr := make(chan error, 1) // Don't block
+	go func() {                     // Write goroutine
 		defer wait.Done()
 		for {
-			wbuf, ok := <-p.write.buffers
+			wbuf, ok := <-eng.write.buffers
 			if !ok {
 				return
 			}
-			_, err := p.conn.Write(wbuf)
+			_, err := eng.conn.Write(wbuf)
 			if err != nil {
-				error <- err
+				writeErr <- err
+				close(writeErr)
 				return
 			}
 		}
 	}()
 
-	wbuf := p.write.buffer()[:0]
+	wbuf := eng.write.buffer()[:0]
 loop:
 	for {
 		if len(wbuf) == 0 {
-			p.pop(&wbuf)
+			eng.pop(&wbuf)
 		}
 		// Don't set wchan unless there is something to write.
 		var wchan chan []byte
 		if len(wbuf) > 0 {
-			wchan = p.write.buffers
+			wchan = eng.write.buffers
 		}
 
 		select {
-		case buf := <-p.read.buffers: // Read a buffer
-			p.push(buf)
+		case buf, ok := <-eng.read.buffers: // Read a buffer
+			if ok {
+				eng.push(buf)
+			}
 		case wchan <- wbuf: // Write a buffer
-			wbuf = p.write.buffer()[:0]
-		case f := <-p.inject: // Function injected from another goroutine
-			f()
-		case err := <-error: // Network read or write error
-			p.conn.Close() // Make sure both sides are closed
-			p.err.Set(err)
-			p.transport.CloseHead()
-			p.transport.CloseTail()
+			wbuf = eng.write.buffer()[:0]
+		case f, ok := <-eng.inject: // Function injected from another goroutine
+			if ok {
+				f()
+			}
+		case err := <-readErr:
+			eng.netError(err)
+		case err := <-writeErr:
+			eng.netError(err)
 		}
-		p.process()
-		if p.err.Get() != nil {
+		eng.process()
+		if eng.err.Get() != nil {
 			break loop
 		}
 	}
-	close(p.write.buffers)
-	p.conn.Close()
+	close(eng.write.buffers)
+	eng.conn.Close() // Make sure connection is closed
 	wait.Wait()
-	connectionContexts.Delete(p.connection)
-	if !p.connection.IsNil() {
-		p.connection.Free()
+	connectionContexts.Delete(eng.connection)
+	if !eng.connection.IsNil() {
+		eng.connection.Free()
 	}
-	if !p.transport.IsNil() {
-		p.transport.Free()
+	if !eng.transport.IsNil() {
+		eng.transport.Free()
 	}
-	if p.collector != nil {
-		C.pn_collector_free(p.collector)
+	if eng.collector != nil {
+		C.pn_collector_free(eng.collector)
 	}
-	for _, h := range p.handlers {
+	for _, h := range eng.handlers {
 		switch h := h.(type) {
 		case cHandler:
 			C.pn_handler_free(h.pn)
 		}
 	}
-	close(p.running) // Signal goroutines have exited and Error is set.
+	close(eng.running) // Signal goroutines have exited and Error is set.
+	return eng.err.Get()
+}
+
+func (eng *Engine) netError(err error) {
+	if err == nil {
+		err = internal.Errorf("unknown network error")
+	}
+	eng.conn.Close() // Make sure both sides are closed
+	eng.err.Set(err)
+	eng.transport.CloseHead()
+	eng.transport.CloseTail()
 }
 
 func minInt(a, b int) int {
@@ -342,8 +354,8 @@ func minInt(a, b int) int {
 	}
 }
 
-func (p *Engine) pop(buf *[]byte) {
-	pending := int(p.transport.Pending())
+func (eng *Engine) pop(buf *[]byte) {
+	pending := int(eng.transport.Pending())
 	switch {
 	case pending == int(C.PN_EOS):
 		*buf = (*buf)[:]
@@ -356,15 +368,15 @@ func (p *Engine) pop(buf *[]byte) {
 	if size == 0 {
 		return
 	}
-	C.memcpy(unsafe.Pointer(&(*buf)[0]), p.transport.Head(), C.size_t(size))
+	C.memcpy(unsafe.Pointer(&(*buf)[0]), eng.transport.Head(), C.size_t(size))
 	internal.Assert(size > 0)
-	p.transport.Pop(uint(size))
+	eng.transport.Pop(uint(size))
 }
 
-func (p *Engine) push(buf []byte) {
+func (eng *Engine) push(buf []byte) {
 	buf2 := buf
 	for len(buf2) > 0 {
-		n := p.transport.Push(buf2)
+		n := eng.transport.Push(buf2)
 		if n <= 0 {
 			panic(internal.Errorf("error in transport: %s", internal.PnErrorCode(n)))
 		}
@@ -372,30 +384,24 @@ func (p *Engine) push(buf []byte) {
 	}
 }
 
-func (p *Engine) handle(e Event) (more bool) {
-	for _, h := range p.handlers {
+func (eng *Engine) handle(e Event) {
+	for _, h := range eng.handlers {
 		h.HandleEvent(e)
 	}
 	if e.Type() == ETransportClosed {
-		p.err.Set(e.Connection().RemoteCondition().Error())
-		p.err.Set(e.Connection().Transport().Condition().Error())
-		if p.err.Get() == nil {
-			p.err.Set(io.EOF)
+		eng.err.Set(e.Connection().RemoteCondition().Error())
+		eng.err.Set(e.Connection().Transport().Condition().Error())
+		if eng.err.Get() == nil {
+			eng.err.Set(io.EOF)
 		}
-		return false
 	}
-	return true
 }
 
-func (p *Engine) process() (more bool) {
-	for ce := C.pn_collector_peek(p.collector); ce != nil; ce = C.pn_collector_peek(p.collector) {
-		e := makeEvent(ce)
-		if !p.handle(e) {
-			return false
-		}
-		C.pn_collector_pop(p.collector)
+func (eng *Engine) process() {
+	for ce := C.pn_collector_peek(eng.collector); ce != nil; ce = C.pn_collector_peek(eng.collector) {
+		eng.handle(makeEvent(ce))
+		C.pn_collector_pop(eng.collector)
 	}
-	return true
 }
 
-func (p *Engine) Connection() Connection { return p.connection }
+func (eng *Engine) Connection() Connection { return eng.connection }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go b/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
index aa4d76b..8a5cbf8 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
@@ -23,7 +23,7 @@ package proton
 import "C"
 
 import (
-	"qpid.apache.org/proton/internal"
+	"qpid.apache.org/internal"
 )
 
 // EventHandler handles core proton events.
@@ -166,7 +166,7 @@ func (t MessagingEvent) String() string {
 	case MLinkClosed:
 		return "LinkClosed"
 	case MDisconnected:
-		return "MDisconnected"
+		return "Disconnected"
 	case MSendable:
 		return "Sendable"
 	case MAccepted:
@@ -355,20 +355,12 @@ func (d *MessagingDelegator) HandleEvent(e Event) {
 func (d *MessagingDelegator) incoming(e Event) (err error) {
 	delivery := e.Delivery()
 	if delivery.HasMessage() {
-		if e.Link().State().LocalClosed() {
+		d.mhandler.HandleMessagingEvent(MMessage, e)
+		if d.AutoAccept && !delivery.Settled() {
+			delivery.Accept()
+		}
+		if delivery.Current() {
 			e.Link().Advance()
-			if d.AutoAccept {
-				delivery.Release(false)
-			}
-		} else {
-			d.mhandler.HandleMessagingEvent(MMessage, e)
-			if d.AutoAccept && !delivery.Settled() {
-				if err == nil {
-					delivery.Accept()
-				} else {
-					delivery.Reject()
-				}
-			}
 		}
 	} else if delivery.Updated() && delivery.Settled() {
 		d.mhandler.HandleMessagingEvent(MSettled, e)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/internal/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/error.go b/proton-c/bindings/go/src/qpid.apache.org/proton/internal/error.go
deleted file mode 100644
index 9f65e04..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/error.go
+++ /dev/null
@@ -1,121 +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.
-*/
-
-// Internal implementation details - ignore.
-package internal
-
-// #cgo LDFLAGS: -lqpid-proton
-// #include <proton/error.h>
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"fmt"
-	"sync"
-	"unsafe"
-)
-
-// Error type for proton runtime errors returned as error values.
-type Error string
-
-// Error prefixes error message with proton:
-func (e Error) Error() string {
-	return "proton: " + string(e)
-}
-
-// Errorf creates an Error with a formatted message
-func Errorf(format string, a ...interface{}) Error {
-	return Error(fmt.Sprintf(format, a...))
-}
-
-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(p unsafe.Pointer) error {
-	e := (*C.pn_error_t)(p)
-	if e == nil || C.pn_error_code(e) == 0 {
-		return nil
-	}
-	return Errorf("%s: %s", PnErrorCode(C.pn_error_code(e)), C.GoString(C.pn_error_text(e)))
-}
-
-// panicIf panics if condition is true, the panic value is Errorf(fmt, args...)
-func panicIf(condition bool, fmt string, args ...interface{}) {
-	if condition {
-		panic(Errorf(fmt, args...))
-	}
-}
-
-// FirstError is a goroutine-safe error holder that keeps the first error that is set.
-type FirstError struct {
-	err  error
-	lock sync.Mutex
-}
-
-// Set the error if not already set, return the error.
-func (e *FirstError) Set(err error) error {
-	e.lock.Lock()
-	defer e.lock.Unlock()
-	if e.err == nil {
-		e.err = err
-	}
-	return e.err
-}
-
-// Get the error.
-func (e *FirstError) Get() error {
-	e.lock.Lock()
-	defer e.lock.Unlock()
-	return e.err
-}
-
-// Assert panics if condition is false with optional formatted message
-func Assert(condition bool, format ...interface{}) {
-	if !condition {
-		if len(format) > 0 {
-			panic(Errorf(format[0].(string), format[1:]...))
-		} else {
-			panic(Errorf("assertion failed"))
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel.go b/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel.go
deleted file mode 100644
index 77b524c..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel.go
+++ /dev/null
@@ -1,82 +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.
-*/
-
-package internal
-
-// FlexChannel acts like a channel with an automatically sized buffer, see NewFlexChannel().
-type FlexChannel struct {
-	// In channel to send to. close(In) will close the FlexChannel once buffer has drained.
-	In chan<- interface{}
-	// Out channel to receive from. Out closes when In has closed and the buffer is empty.
-	Out <-chan interface{}
-
-	in, out chan interface{}
-	buffer  []interface{}
-	limit   int
-}
-
-// NewFlexChannel creates a FlexChannel, a channel with an automatically-sized buffer.
-//
-// Initially the buffer size is 0, the buffer grows as needed up to limit. limit < 0 means
-// there is no limit.
-//
-func NewFlexChannel(limit int) *FlexChannel {
-	fc := &FlexChannel{
-		in:     make(chan interface{}),
-		out:    make(chan interface{}),
-		buffer: make([]interface{}, 0),
-		limit:  limit,
-	}
-	fc.In = fc.in
-	fc.Out = fc.out
-	go fc.run()
-	return fc
-}
-
-func (fc *FlexChannel) run() {
-	defer func() { // Flush the channel on exit
-		for _, data := range fc.buffer {
-			fc.out <- data
-		}
-		close(fc.out)
-	}()
-
-	for {
-		var usein, useout chan interface{}
-		var outvalue interface{}
-		if len(fc.buffer) > 0 {
-			useout = fc.out
-			outvalue = fc.buffer[0]
-		}
-		if len(fc.buffer) < fc.limit || fc.limit < 0 {
-			usein = fc.in
-		}
-		Assert(usein != nil || useout != nil)
-		select {
-		case useout <- outvalue:
-			fc.buffer = fc.buffer[1:]
-		case data, ok := <-usein:
-			if ok {
-				fc.buffer = append(fc.buffer, data)
-			} else {
-				return
-			}
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel_test.go
deleted file mode 100644
index d0e1a44..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/flexchannel_test.go
+++ /dev/null
@@ -1,89 +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.
-*/
-
-package internal
-
-import (
-	"testing"
-)
-
-func recvall(ch <-chan interface{}) (result []interface{}) {
-	for {
-		select {
-		case x := <-ch:
-			result = append(result, x)
-		default:
-			return
-		}
-	}
-}
-
-func sendall(data []interface{}, ch chan<- interface{}) {
-}
-
-func TestFlex(t *testing.T) {
-	fc := NewFlexChannel(5)
-
-	// Test send/receve
-	go func() {
-		for i := 0; i < 4; i++ {
-			fc.In <- i
-		}
-	}()
-
-	for i := 0; i < 4; i++ {
-		j := <-fc.Out
-		if i != j {
-			t.Error("%v != %v", i, j)
-		}
-	}
-	select {
-	case x, ok := <-fc.Out:
-		t.Error("receive empty channel got", x, ok)
-	default:
-	}
-
-	// Test buffer limit
-	for i := 10; i < 15; i++ {
-		fc.In <- i
-	}
-	select {
-	case fc.In <- 0:
-		t.Error("send to full channel did not block")
-	default:
-	}
-	i := <-fc.Out
-	if i != 10 {
-		t.Error("%v != %v", i, 10)
-	}
-	fc.In <- 15
-	close(fc.In)
-
-	for i := 11; i < 16; i++ {
-		j := <-fc.Out
-		if i != j {
-			t.Error("%v != %v", i, j)
-		}
-	}
-
-	x, ok := <-fc.Out
-	if ok {
-		t.Error("Unexpected value on Out", x)
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/internal/safemap.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/safemap.go b/proton-c/bindings/go/src/qpid.apache.org/proton/internal/safemap.go
deleted file mode 100644
index 3a1fe2b..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/safemap.go
+++ /dev/null
@@ -1,57 +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.
-*/
-
-package internal
-
-import (
-	"sync"
-)
-
-// SafeMap is a goroutine-safe map of interface{} to interface{}.
-type SafeMap struct {
-	m    map[interface{}]interface{}
-	lock sync.Mutex
-}
-
-func MakeSafeMap() SafeMap { return SafeMap{m: make(map[interface{}]interface{})} }
-
-func (m *SafeMap) Get(key interface{}) interface{} {
-	m.lock.Lock()
-	defer m.lock.Unlock()
-	return m.m[key]
-}
-
-func (m *SafeMap) GetOk(key interface{}) (interface{}, bool) {
-	m.lock.Lock()
-	defer m.lock.Unlock()
-	v, ok := m.m[key]
-	return v, ok
-}
-
-func (m *SafeMap) Put(key, value interface{}) {
-	m.lock.Lock()
-	defer m.lock.Unlock()
-	m.m[key] = value
-}
-
-func (m *SafeMap) Delete(key interface{}) {
-	m.lock.Lock()
-	defer m.lock.Unlock()
-	delete(m.m, key)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/internal/uuid.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/uuid.go b/proton-c/bindings/go/src/qpid.apache.org/proton/internal/uuid.go
deleted file mode 100644
index ef941a1..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/internal/uuid.go
+++ /dev/null
@@ -1,70 +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.
-*/
-
-package internal
-
-import (
-	"fmt"
-	"math/rand"
-	"strconv"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-type UUID [16]byte
-
-func (u UUID) String() string {
-	return fmt.Sprintf("%X-%X-%X-%X-%X", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
-}
-
-// Don't mess with the default random source.
-var randomSource = rand.NewSource(time.Now().UnixNano())
-var randomLock sync.Mutex
-
-func random() byte {
-	randomLock.Lock()
-	defer randomLock.Unlock()
-	return byte(randomSource.Int63())
-}
-
-func UUID4() UUID {
-	var u UUID
-	for i := 0; i < len(u); i++ {
-		u[i] = random()
-	}
-	// See /https://tools.ietf.org/html/rfc4122#section-4.4
-	u[6] = (u[6] & 0x0F) | 0x40 // Version bits to 4
-	u[8] = (u[8] & 0x3F) | 0x80 // Reserved bits (top two) set to 01
-	return u
-}
-
-// A simple atomic counter to generate unique 64 bit IDs.
-type IdCounter struct{ count uint64 }
-
-// NextInt gets the next uint64 value from the atomic counter.
-func (uc *IdCounter) NextInt() uint64 {
-	return atomic.AddUint64(&uc.count, 1)
-}
-
-// Next gets the next integer value encoded as a base32 string, safe for NUL
-// terminated C strings.
-func (uc *IdCounter) Next() string {
-	return strconv.FormatUint(uc.NextInt(), 32)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/message.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/message.go b/proton-c/bindings/go/src/qpid.apache.org/proton/message.go
index a4370ff..c545b7e 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/message.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/message.go
@@ -25,8 +25,8 @@ package proton
 import "C"
 
 import (
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/internal"
+	"qpid.apache.org/internal"
+	"qpid.apache.org/amqp"
 )
 
 // HasMessage is true if all message data is available.
@@ -34,10 +34,17 @@ import (
 func (d Delivery) HasMessage() bool { return !d.IsNil() && d.Readable() && !d.Partial() }
 
 // Message decodes the message containined in a delivery.
-// Will return an error if delivery.HasMessage() is false.
+//
+// Must be called in the correct link context with this delivery as the current message,
+// handling an MMessage event is always a safe context to call this function.
+//
+// Will return an error if message is incomplete or not current.
 func (delivery Delivery) Message() (m amqp.Message, err error) {
-	if !delivery.Readable() || delivery.Partial() {
-		return nil, internal.Errorf("attempting to get incomplete message")
+	if !delivery.Readable() {
+		return nil, internal.Errorf("delivery is not readable")
+	}
+	if delivery.Partial() {
+		return nil, internal.Errorf("delivery has partial message")
 	}
 	data := make([]byte, delivery.Pending())
 	result := delivery.Link().Recv(data)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
index 4e208f7..7d40890 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
@@ -36,8 +36,8 @@ import "C"
 
 import (
 	"fmt"
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/internal"
+	"qpid.apache.org/internal"
+	"qpid.apache.org/amqp"
 	"reflect"
 	"time"
 	"unsafe"
@@ -134,10 +134,22 @@ type Endpoint interface {
 
 // CloseError sets an error condition on an endpoint and closes the endpoint.
 func CloseError(e Endpoint, err error) {
-	e.Condition().SetError(err)
+	if err != nil {
+		e.Condition().SetError(err)
+	}
 	e.Close()
 }
 
+// EndpointError returns the remote error if there is one, the local error if not
+// nil if there is no error.
+func EndpointError(e Endpoint) error {
+	err := e.RemoteCondition().Error()
+	if err == nil {
+		err = e.Condition().Error()
+	}
+	return err
+}
+
 const (
 	Received uint64 = C.PN_RECEIVED
 	Accepted        = C.PN_ACCEPTED
@@ -271,9 +283,12 @@ func (l Link) Connection() Connection { return l.Session().Connection() }
 
 // Human-readable link description including name, source, target and direction.
 func (l Link) String() string {
-	if l.IsSender() {
+	switch {
+	case l.IsNil():
+		return fmt.Sprintf("<nil-link>")
+	case l.IsSender():
 		return fmt.Sprintf("%s(%s->%s)", l.Name(), l.Source().Address(), l.Target().Address())
-	} else {
+	default:
 		return fmt.Sprintf("%s(%s<-%s)", l.Name(), l.Target().Address(), l.Source().Address())
 	}
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers_gen.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers_gen.go b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers_gen.go
index 82de2cf..074495d 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers_gen.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers_gen.go
@@ -25,7 +25,7 @@ under the License.
 package proton
 
 import (
-	"qpid.apache.org/proton/internal"
+	"qpid.apache.org/internal"
 	"time"
 	"unsafe"
 )


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


[14/50] [abbrv] qpid-proton git commit: PROTON-1016: Support for encoding of java.math.BigInteger

Posted by ac...@apache.org.
PROTON-1016: Support for encoding of java.math.BigInteger


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

Branch: refs/heads/go1
Commit: 6091e9e2c57d2dd94cfb5b87d61ca354ce84362e
Parents: 1ae893e
Author: Bozo Dragojevic <bo...@digiverse.si>
Authored: Thu Oct 8 17:18:38 2015 +0200
Committer: Bozo Dragojevic <bo...@digiverse.si>
Committed: Thu Oct 8 17:54:24 2015 +0200

----------------------------------------------------------------------
 .../qpid/proton/codec/BigIntegerType.java       | 196 +++++++++++++++++++
 .../apache/qpid/proton/codec/EncoderImpl.java   |   2 +
 2 files changed, 198 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6091e9e2/proton-j/src/main/java/org/apache/qpid/proton/codec/BigIntegerType.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/codec/BigIntegerType.java b/proton-j/src/main/java/org/apache/qpid/proton/codec/BigIntegerType.java
new file mode 100644
index 0000000..f74e80b
--- /dev/null
+++ b/proton-j/src/main/java/org/apache/qpid/proton/codec/BigIntegerType.java
@@ -0,0 +1,196 @@
+/*
+ *
+ * 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 org.apache.qpid.proton.codec;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+
+public class BigIntegerType extends AbstractPrimitiveType<BigInteger> {
+
+    public static interface BigIntegerEncoding extends PrimitiveTypeEncoding<BigInteger>
+    {
+        void write(BigInteger l);
+        void writeValue(BigInteger l);
+        public BigInteger readPrimitiveValue();
+    }
+
+    private static final BigInteger BIG_BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE);
+    private static final BigInteger BIG_BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE);
+    private static final BigInteger BIG_LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);;
+    private static final BigInteger BIG_LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);;
+
+    private BigIntegerEncoding _BigIntegerEncoding;
+    private BigIntegerEncoding _smallBigIntegerEncoding;
+
+    BigIntegerType(final EncoderImpl encoder, final DecoderImpl decoder)
+    {
+        _BigIntegerEncoding = new AllBigIntegerEncoding(encoder, decoder);
+        _smallBigIntegerEncoding = new SmallBigIntegerEncoding(encoder, decoder);
+        encoder.register(BigInteger.class, this);
+    }
+
+    public Class<BigInteger> getTypeClass()
+    {
+        return BigInteger.class;
+    }
+
+    public BigIntegerEncoding getEncoding(final BigInteger l)
+    {
+        return (l.compareTo(BIG_BYTE_MIN) >= 0 && l.compareTo(BIG_BYTE_MAX) <= 0) ? _smallBigIntegerEncoding : _BigIntegerEncoding;
+    }
+
+
+    public BigIntegerEncoding getCanonicalEncoding()
+    {
+        return _BigIntegerEncoding;
+    }
+
+    public Collection<BigIntegerEncoding> getAllEncodings()
+    {
+        return Arrays.asList(_smallBigIntegerEncoding, _BigIntegerEncoding);
+    }
+
+    private long longValueExact(final BigInteger val) {
+        if (val.compareTo(BIG_LONG_MIN) < 0 || val.compareTo(BIG_LONG_MAX) > 0) {
+            throw new ArithmeticException("cannot encode BigInteger not representable as long");
+        }
+        return val.longValue();
+    }
+
+    private class AllBigIntegerEncoding extends FixedSizePrimitiveTypeEncoding<BigInteger> implements BigIntegerEncoding
+    {
+
+        public AllBigIntegerEncoding(final EncoderImpl encoder, final DecoderImpl decoder)
+        {
+            super(encoder, decoder);
+        }
+
+        @Override
+        protected int getFixedSize()
+        {
+            return 8;
+        }
+
+        @Override
+        public byte getEncodingCode()
+        {
+            return EncodingCodes.LONG;
+        }
+
+        public BigIntegerType getType()
+        {
+            return BigIntegerType.this;
+        }
+
+        public void writeValue(final BigInteger val)
+        {
+            getEncoder().writeRaw(longValueExact(val));
+        }
+        
+        public void write(final BigInteger l)
+        {
+            writeConstructor();
+            getEncoder().writeRaw(longValueExact(l));
+            
+        }
+
+        public boolean encodesSuperset(final TypeEncoding<BigInteger> encoding)
+        {
+            return (getType() == encoding.getType());
+        }
+
+        public BigInteger readValue()
+        {
+            return readPrimitiveValue();
+        }
+
+        public BigInteger readPrimitiveValue()
+        {
+            return BigInteger.valueOf(getDecoder().readLong());
+        }
+
+
+        @Override
+        public boolean encodesJavaPrimitive()
+        {
+            return true;
+        }
+    }
+
+    private class SmallBigIntegerEncoding  extends FixedSizePrimitiveTypeEncoding<BigInteger> implements BigIntegerEncoding
+    {
+        public SmallBigIntegerEncoding(final EncoderImpl encoder, final DecoderImpl decoder)
+        {
+            super(encoder, decoder);
+        }
+
+        @Override
+        public byte getEncodingCode()
+        {
+            return EncodingCodes.SMALLLONG;
+        }
+
+        @Override
+        protected int getFixedSize()
+        {
+            return 1;
+        }
+
+        public void write(final BigInteger l)
+        {
+            writeConstructor();
+            getEncoder().writeRaw(l.byteValue());
+        }
+
+        public BigInteger readPrimitiveValue()
+        {
+            return BigInteger.valueOf(getDecoder().readRawByte());
+        }
+
+        public BigIntegerType getType()
+        {
+            return BigIntegerType.this;
+        }
+
+        public void writeValue(final BigInteger val)
+        {
+            getEncoder().writeRaw(val.byteValue());
+        }
+
+        public boolean encodesSuperset(final TypeEncoding<BigInteger> encoder)
+        {
+            return encoder == this;
+        }
+
+        public BigInteger readValue()
+        {
+            return readPrimitiveValue();
+        }
+
+
+        @Override
+        public boolean encodesJavaPrimitive()
+        {
+            return true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6091e9e2/proton-j/src/main/java/org/apache/qpid/proton/codec/EncoderImpl.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/codec/EncoderImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/codec/EncoderImpl.java
index fd0be07..97e1005 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/codec/EncoderImpl.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/codec/EncoderImpl.java
@@ -59,6 +59,7 @@ public final class EncoderImpl implements ByteBufferEncoder
     private final UnsignedIntegerType   _unsignedIntegerType;
     private final LongType              _longType;
     private final UnsignedLongType      _unsignedLongType;
+    private final BigIntegerType        _bigIntegerType;
 
     private final CharacterType         _characterType;
     private final FloatType             _floatType;
@@ -98,6 +99,7 @@ public final class EncoderImpl implements ByteBufferEncoder
         _unsignedIntegerType    = new UnsignedIntegerType(this, decoder);
         _longType               = new LongType(this, decoder);
         _unsignedLongType       = new UnsignedLongType(this, decoder);
+        _bigIntegerType         = new BigIntegerType(this, decoder);
 
         _characterType          = new CharacterType(this, decoder);
         _floatType              = new FloatType(this, decoder);


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


[12/50] [abbrv] qpid-proton git commit: NO-JIRA: Added go-get repo update script

Posted by ac...@apache.org.
NO-JIRA: Added go-get repo update script


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

Branch: refs/heads/go1
Commit: 1ae893efe4e3facc2d9917ec8fe9d465176a1eab
Parents: 2e8995f
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Oct 8 10:56:35 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Oct 8 10:56:45 2015 -0400

----------------------------------------------------------------------
 .../go/src/qpid.apache.org/go-get-repo.sh       | 26 ++++++++++++++++++++
 1 file changed, 26 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1ae893ef/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh b/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
new file mode 100755
index 0000000..3a84191
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# This script is used to create a repository to support the "go get" command.
+#
+# WARNING: DO NOT run in the main proton repository.
+#
+# This script will REPLACE the master branch of the current repository with just
+# the Go subset of the proton repository.
+#
+# Currently the go-get repository is: https://github.com/alanconway/proton-go.git
+#
+
+set -e -x
+# Safety check: the repo for `go get` should have a branch called proton_go_get_master
+git checkout proton_go_get_master
+git checkout master
+git fetch -f https://git-wip-us.apache.org/repos/asf/qpid-proton.git master:proton_go_get_master
+git checkout proton_go_get_master
+git branch -f -D master  # Will replace master with the go subtree of proton
+git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b master
+git checkout master
+
+set +x
+echo
+echo TO FINISH:
+echo git push -f -u origin master


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


[33/50] [abbrv] qpid-proton git commit: NO-JIRA: Add missing CMake dependencies for Go examples, was causing build failures.

Posted by ac...@apache.org.
NO-JIRA: Add missing CMake dependencies for Go examples, was causing build failures.


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

Branch: refs/heads/go1
Commit: 9106cb0aeed37fc5e59775e3e9efe4eec24e44ea
Parents: dc5cbac
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 19 15:40:37 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 19 15:40:37 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt          |  1 +
 proton-c/bindings/go/CMakeLists.txt | 11 +++++++----
 2 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9106cb0a/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 2a36ec8..bcfff1a 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -25,6 +25,7 @@ if(BUILD_GO)
   foreach(example ${examples})
     set(source ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go)
     set(target ${CMAKE_CURRENT_BINARY_DIR}/${example})
+    message("FIXME ${source} ${GO_TARGETS}")
     add_custom_command(
       OUTPUT ${target}
       COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${target} ${source}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9106cb0a/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index e791555..51c2d86 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -49,7 +49,8 @@ set(GO_INSTALL ${GO} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
 set(GO_TEST ${GO} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
 
 # Go build depends on the C headers
-file(GLOB headers ${CMAKE_SOURCE_DIR}/proton_c/include/proton/*.h)
+file(GLOB cheaders ${CMAKE_SOURCE_DIR}/proton_c/include/proton/*.h)
+set(cdepends ${headers} qpid-proton)
 
 # Go tools insist on standard Go layout which puts compiled code in the source tree :(
 # Build output is all under git-ignored pkg or bin subdirectories, they are removed by make clean.
@@ -74,7 +75,7 @@ foreach (pkg amqp proton electron)
   set(sources "${GoFiles}${CgoFiles}")
 
   # Build the package library
-  add_custom_command(OUTPUT ${lib} COMMAND ${GO_INSTALL} ${package} DEPENDS ${sources} ${headers})
+  add_custom_command(OUTPUT ${lib} COMMAND ${GO_INSTALL} ${package} DEPENDS ${sources} ${cdepends})
   set(target go-package-${pkg})
   add_custom_target(${target} ALL DEPENDS ${lib})
 
@@ -86,10 +87,12 @@ foreach (pkg amqp proton electron)
   add_custom_target(go-package-test-${pkg} ALL DEPENDS ${test_exe})
   add_test(NAME go_test_${pkg} COMMAND ${test_exe} WORKING_DIRECTORY ${dir})
 
-  list(APPEND GO_TARGETS ${target})
-
+  list(APPEND targets ${target})
 endforeach()
 
+# Make available to examples/go/CMakeLists
+set(GO_TARGETS ${targets} CACHE INTERNAL "Go package library targets")
+
 # Clean up go output directories.
 list(APPEND ADDITIONAL_MAKE_CLEAN_FILES
   ${CMAKE_CURRENT_SOURCE_DIR}/pkg


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


[20/50] [abbrv] qpid-proton git commit: NO-JIRA: Travis config: don't run build if cmake fails, don't run tests if build fails.

Posted by ac...@apache.org.
NO-JIRA: Travis config: don't run build if cmake fails, don't run tests if build fails.


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

Branch: refs/heads/go1
Commit: 6859fa30722cd5e1c602cda0415c689781f3c903
Parents: bd698ee
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 12 11:42:37 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 12 12:38:48 2015 -0400

----------------------------------------------------------------------
 .travis.yml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6859fa30/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 8bbeb2b..3708db0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,9 +27,8 @@ install:
 - gem install minitest --version 4.7.0
 before_script:
 - export PATH=${HOME}/.local/bin:${PATH}
-script:
 - mkdir Build
 - cd Build
 - cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/install
-- cmake --build . --target install
-- ctest -V
+script:
+- cmake --build . --target install && ctest -V


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


[45/50] [abbrv] qpid-proton git commit: NO-JIRA: go: Bug fixes and improved examples.

Posted by ac...@apache.org.
NO-JIRA: go: Bug fixes and improved examples.

package proton:
- Injecter() provided by event rather than connection. Allow different event-loop strategies.
- Add access to proton refcounts, may be useful for some apps.

package electron:
- simplified sender logic using credit flag.
- consistent link, session and connection options.

examples: simplified & improved

proton/broker: concurrent broker using handler per connection.
electron/broker: cleaned up for comparison to proton/broker.

examples/README.md discussion of brokers.


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

Branch: refs/heads/go1
Commit: bc0a242e4cc335f2aa496b98bf06d033904ca23d
Parents: 6a30616
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 13 10:31:01 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Oct 22 18:14:17 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt                      |   9 +-
 examples/go/README.md                           |  31 ++
 examples/go/electron/broker.go                  |  67 ++--
 examples/go/electron/receive.go                 |   5 +-
 examples/go/electron/send.go                    |   2 -
 examples/go/example_test.go                     |  57 ++-
 examples/go/proton/broker.go                    | 389 ++++++++++---------
 examples/go/util/util.go                        |   2 +-
 proton-c/bindings/go/CMakeLists.txt             |   7 +-
 .../src/qpid.apache.org/electron/connection.go  | 151 ++++---
 .../src/qpid.apache.org/electron/container.go   |   6 +-
 .../go/src/qpid.apache.org/electron/handler.go  | 102 +++--
 .../go/src/qpid.apache.org/electron/link.go     |  67 ++--
 .../go/src/qpid.apache.org/electron/receiver.go |  60 +--
 .../go/src/qpid.apache.org/electron/sender.go   | 120 +++---
 .../go/src/qpid.apache.org/electron/session.go  |  49 ++-
 .../go/src/qpid.apache.org/electron/time.go     |  19 +-
 .../go/src/qpid.apache.org/proton/doc.go        |  29 +-
 .../go/src/qpid.apache.org/proton/engine.go     |  71 ++--
 .../go/src/qpid.apache.org/proton/handlers.go   |  18 +-
 .../go/src/qpid.apache.org/proton/wrappers.go   |  98 +++--
 .../qpid/proton/amqp/messaging/Terminus.java    |   2 +-
 22 files changed, 736 insertions(+), 625 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index c345523..32be548 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -20,6 +20,7 @@
 if(BUILD_GO)
 
   set(examples electron/broker electron/receive electron/send proton/broker)
+  file(GLOB_RECURSE example_source ${CMAKE_CURRENT_SOURCE_DIR}/*.go)
 
   # Build example exes
   foreach(example ${examples})
@@ -28,7 +29,8 @@ if(BUILD_GO)
     add_custom_command(
       OUTPUT ${target}
       COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${target} ${source}
-      DEPENDS  ${source} ${GO_TARGETS})
+      DEPENDS  ${example_source} ${GO_TARGETS}
+      WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
     list(APPEND example_exes ${target})
   endforeach()
 
@@ -36,8 +38,9 @@ if(BUILD_GO)
   set(test_exe ${CMAKE_CURRENT_BINARY_DIR}/example_test)
   add_custom_command(
     OUTPUT ${test_exe}
-    DEPENDS ${example_exes}
-    COMMAND ${GO_TEST} -c -o ${test_exe} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go)
+    DEPENDS ${example_exes} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go
+    COMMAND ${GO_TEST} -c -o ${test_exe} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 
   add_custom_target(go-test-exe ALL DEPENDS ${test_exe})
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/README.md
----------------------------------------------------------------------
diff --git a/examples/go/README.md b/examples/go/README.md
index 0114d0e..ce9206b 100644
--- a/examples/go/README.md
+++ b/examples/go/README.md
@@ -87,3 +87,34 @@ Or use the Go broker and the python clients:
 
     python ../python/simple_send.py
     python ../python/simple_recv.py
+
+
+## A tale of two brokers.
+
+The `proton` and `electron` packages provide two alternate APIs for AMQP applications.
+See [the proton Go README](https://github.com/apache/qpid-proton/blob/master/proton-c/bindings/go/src/qpid.apache.org/README.md) for a discussion
+of why there are two APIs.
+
+The examples `proton/broker.go` and `electron/broker.go` both implement the same
+simple broker-like functionality using each of the two APIs. They both handle
+multiple connections concurrently and store messages on bounded queues
+implemented by Go channels.
+
+However the `electron/broker` is less than half as long as the `proton/broker`
+illustrating why it is better suited for most Go applications.
+
+`proton/broker` must explicitly handle proton events, which are processed in a
+single goroutine per connection since proton is not concurrent safe. Each
+connection uses channels to exchange messages between the event-handling
+goroutine and the shared queues that are accessible to all connections. Sending
+messages is particularly tricky since we must monitor the queue for available
+messages and the sending link for available credit in order to send messages.
+
+
+`electron/broker` takes advantage of the `electron` package, which hides all the
+event handling and passing of messages between goroutines beind behind
+straightforward interfaces for sending and receiving messages. The electron
+broker can implement links as simple goroutines that loop popping messages from
+a queue and sending them or receiving messages and pushing them to a queue.
+
+

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/electron/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/broker.go b/examples/go/electron/broker.go
index 1e4a931..f1dce17 100644
--- a/examples/go/electron/broker.go
+++ b/examples/go/electron/broker.go
@@ -52,21 +52,20 @@ var qsize = flag.Int("qsize", 1000, "Max queue size")
 func main() {
 	flag.Usage = usage
 	flag.Parse()
-	if err := newBroker().run(); err != nil {
+	b := &broker{util.MakeQueues(*qsize), electron.NewContainer("")}
+	if err := b.run(); err != nil {
 		log.Fatal(err)
 	}
 }
 
+// State for the broker
 type broker struct {
 	queues    util.Queues
 	container electron.Container
 }
 
-func newBroker() *broker {
-	return &broker{util.MakeQueues(*qsize), electron.NewContainer("")}
-}
-
-func (b *broker) run() (err error) {
+// Listens for connections and starts an electron.Connection for each one.
+func (b *broker) run() error {
 	listener, err := net.Listen("tcp", *addr)
 	if err != nil {
 		return err
@@ -76,46 +75,29 @@ func (b *broker) run() (err error) {
 	for {
 		conn, err := listener.Accept()
 		if err != nil {
-			util.Debugf("Accept error: %s", err)
+			util.Debugf("Accept error: %v", err)
 			continue
 		}
-		if err := b.connection(conn); err != nil {
-			if err != nil {
-				util.Debugf("Connection error: %s", err)
-				continue
-			}
+		c, err := b.container.Connection(conn, electron.Server(), electron.Accepter(b.accept))
+		if err != nil {
+			util.Debugf("Connection error: %v", err)
+			continue
 		}
+		util.Debugf("Accepted %v", c)
 	}
 }
 
-// connection creates a new AMQP connection for a net.Conn.
-func (b *broker) connection(conn net.Conn) error {
-	c, err := b.container.Connection(conn)
-	if err != nil {
-		return err
-	}
-	c.Server()         // Enable server-side protocol negotiation.
-	c.Listen(b.accept) // Call accept() for remotely-opened endpoints.
-	if err := c.Open(); err != nil {
-		return err
-	}
-	util.Debugf("Accepted %s", c)
-	return nil
-}
-
 // accept remotely-opened endpoints (Session, Sender and Receiver)
 // and start goroutines to service them.
-func (b *broker) accept(ep electron.Endpoint) error {
-	switch ep := ep.(type) {
-	case electron.Sender:
-		util.Debugf("%s opened", ep)
-		go b.sender(ep)
-	case electron.Receiver:
-		util.Debugf("%s opened", ep)
-		ep.SetCapacity(100, true) // Pre-fetch 100 messages
-		go b.receiver(ep)
+func (b *broker) accept(i electron.Incoming) {
+	switch i := i.(type) {
+	case *electron.IncomingSender:
+		go b.sender(i.AcceptSender())
+	case *electron.IncomingReceiver:
+		go b.receiver(i.AcceptReceiver(100, true)) // Pre-fetch 100 messages
+	default:
+		i.Accept()
 	}
-	return nil
 }
 
 // sender pops messages from a queue and sends them.
@@ -127,17 +109,16 @@ func (b *broker) sender(sender electron.Sender) {
 			return
 		}
 		if err := sender.SendForget(m); err == nil {
-			util.Debugf("send %s: %s", sender, util.FormatMessage(m))
+			util.Debugf("%s send: %s", sender, util.FormatMessage(m))
 		} else {
-			util.Debugf("send error %s: %s", sender, err)
+			util.Debugf("%s error: %s", sender, err)
 			q <- m // Put it back on the queue.
-			break
+			return
 		}
 	}
 }
 
-// receiver receives messages and pushes to the queue named by the receivers's
-// Target address
+// receiver receives messages and pushes to a queue.
 func (b *broker) receiver(receiver electron.Receiver) {
 	q := b.queues.Get(receiver.Target())
 	for {
@@ -146,7 +127,7 @@ func (b *broker) receiver(receiver electron.Receiver) {
 			q <- rm.Message
 			rm.Accept()
 		} else {
-			util.Debugf("%s: error %s", receiver, err)
+			util.Debugf("%s error: %s", receiver, err)
 			break
 		}
 	}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/electron/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/receive.go b/examples/go/electron/receive.go
index e450a75..f7d41fa 100644
--- a/examples/go/electron/receive.go
+++ b/examples/go/electron/receive.go
@@ -77,8 +77,6 @@ func main() {
 			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
 			util.ExitIf(err)
 			c, err := container.Connection(conn)
-			util.ExitIf(err)
-			util.ExitIf(c.Open())
 			connections <- c // Save connection so we can Close() when main() ends
 
 			// Create a Receiver using the path of the URL as the source address
@@ -106,9 +104,8 @@ func main() {
 
 	// print each message until the count is exceeded.
 	for i := uint64(0); i < *count; i++ {
-		util.Debugf("pre (%d/%d)\n", i, *count)
 		m := <-messages
-		util.Debugf("%s (%d/%d)\n", util.FormatMessage(m), i, *count)
+		util.Debugf("%s\n", util.FormatMessage(m))
 	}
 	fmt.Printf("Received %d messages\n", *count)
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/electron/send.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/send.go b/examples/go/electron/send.go
index 6b7aec1..c9bdbc9 100644
--- a/examples/go/electron/send.go
+++ b/examples/go/electron/send.go
@@ -80,8 +80,6 @@ func main() {
 			util.ExitIf(err)
 			c, err := container.Connection(conn)
 			util.ExitIf(err)
-			err = c.Open()
-			util.ExitIf(err)
 			connections <- c // Save connection so we can Close() when main() ends
 
 			// Create a Sender using the path of the URL as the AMQP address

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
index 1e497b9..006e17c 100644
--- a/examples/go/example_test.go
+++ b/examples/go/example_test.go
@@ -28,6 +28,7 @@ import (
 	"flag"
 	"fmt"
 	"io"
+	"log"
 	"math/rand"
 	"net"
 	"os"
@@ -35,7 +36,6 @@ import (
 	"path"
 	"path/filepath"
 	"reflect"
-	"strings"
 	"testing"
 	"time"
 )
@@ -108,27 +108,8 @@ func checkEqual(want interface{}, got interface{}) error {
 	return fmt.Errorf("%#v != %#v", want, got)
 }
 
-// 'go build' uses the installed copy of the proton Go libraries, which may be out of date.
-func checkStaleLibs(t *testing.T) {
-	var stale []string
-	pp := "qpid.apache.org"
-	for _, p := range []string{pp + "/proton", pp + "/amqp", pp + "/electron"} {
-		out, err := exec.Command("go", "list", "-f", "{{.Stale}}", p).CombinedOutput()
-		if err != nil {
-			t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))
-		}
-		if string(out) != "false\n" {
-			stale = append(stale, p)
-		}
-	}
-	if len(stale) > 0 {
-		t.Fatalf("Stale libraries, run 'go install %s'", strings.Trim(fmt.Sprint(stale), "[]"))
-	}
-}
-
 // exampleCommand returns an exec.Cmd to run an example.
 func exampleCommand(t *testing.T, prog string, arg ...string) (cmd *exec.Cmd) {
-	checkStaleLibs(t)
 	args := []string{}
 	if *debug {
 		args = append(args, "-debug=true")
@@ -230,6 +211,7 @@ func goReceiveWant(t *testing.T, errchan chan<- error, want string, arg ...strin
 		errchan <- ready
 		buf := bytes.Buffer{}
 		io.Copy(&buf, out) // Collect the rest of the output
+		cmd.Wait()
 		errchan <- checkEqual(want, buf.String())
 		close(errchan)
 	}()
@@ -242,26 +224,30 @@ func TestExampleReceiveSend(t *testing.T) {
 		t.Skip("Skip demo tests in short mode")
 	}
 	testBroker.start(t)
-	recvErr := make(chan error)
-	recvCmd := goReceiveWant(
-		t, recvErr,
-		fmt.Sprintf("Received %d messages\n", expected),
-		exampleArgs(fmt.Sprintf("-count=%d", expected))...)
-	defer func() {
-		recvCmd.Process.Kill()
-		recvCmd.Wait()
-	}()
-	if err := <-recvErr; err != ready { // Wait for receiver ready
+
+	// Start receiver, wait for "listening" message on stdout
+	recvCmd := exampleCommand(t, "receive", exampleArgs(fmt.Sprintf("-count=%d", expected))...)
+	pipe, err := recvCmd.StdoutPipe()
+	if err != nil {
 		t.Fatal(err)
 	}
-	err := runExampleWant(t,
+	recvCmd.Start()
+	out := bufio.NewReader(pipe)
+	line, err := out.ReadString('\n')
+	if err := checkEqual("Listening on 3 connections\n", line); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := runExampleWant(t,
 		fmt.Sprintf("Received all %d acknowledgements\n", expected),
 		"send",
-		exampleArgs("-count", fmt.Sprintf("%d", *count))...)
-	if err != nil {
+		exampleArgs("-count", fmt.Sprintf("%d", *count))...); err != nil {
 		t.Fatal(err)
 	}
-	if err := <-recvErr; err != nil {
+
+	buf := bytes.Buffer{}
+	io.Copy(&buf, out)
+	if err := checkEqual(fmt.Sprintf("Received %d messages\n", expected), buf.String()); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -276,6 +262,9 @@ var dir = flag.String("dir", "", "Directory containing example sources or binari
 var expected int
 
 func TestMain(m *testing.M) {
+	if out, err := exec.Command("go", "install", "qpid.apache.org/...").CombinedOutput(); err != nil {
+		log.Fatalf("go install failed: %s\n%s", err, out)
+	}
 	expected = (*count) * (*connections)
 	rand.Seed(time.Now().UTC().UnixNano())
 	testBroker = &broker{} // Broker is started on-demand by tests.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/proton/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/proton/broker.go b/examples/go/proton/broker.go
index 75f14f5..3eb5880 100644
--- a/examples/go/proton/broker.go
+++ b/examples/go/proton/broker.go
@@ -30,7 +30,7 @@ import (
 	"./util"
 	"flag"
 	"fmt"
-	"io"
+	"log"
 	"net"
 	"os"
 	"qpid.apache.org/amqp"
@@ -53,247 +53,276 @@ var qsize = flag.Int("qsize", 1000, "Max queue size")
 func main() {
 	flag.Usage = usage
 	flag.Parse()
+	b := &broker{util.MakeQueues(*qsize)}
+	if err := b.run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+// State for the broker
+type broker struct {
+	queues util.Queues
+}
 
-	b := newBroker()
+// Listens for connections and starts a proton.Engine for each one.
+func (b *broker) run() error {
 	listener, err := net.Listen("tcp", *addr)
-	util.ExitIf(err)
+	if err != nil {
+		return err
+	}
 	defer listener.Close()
 	fmt.Printf("Listening on %s\n", listener.Addr())
-
-	// Loop accepting new connections.
 	for {
 		conn, err := listener.Accept()
 		if err != nil {
-			util.Debugf("Accept error: %s", err)
+			util.Debugf("Accept error: %v", err)
 			continue
 		}
-		if err := b.connection(conn); err != nil {
-			if err != nil {
-				util.Debugf("Connection error: %s", err)
-				continue
-			}
+		adapter := proton.NewMessagingAdapter(newHandler(&b.queues))
+		// We want to accept messages when they are enqueued, not just when they
+		// are received, so we turn off auto-accept and prefetch by the adapter.
+		adapter.Prefetch = 0
+		adapter.AutoAccept = false
+		engine, err := proton.NewEngine(conn, adapter)
+		if err != nil {
+			util.Debugf("Connection error: %v", err)
+			continue
 		}
+		engine.Server() // Enable server-side protocol negotiation.
+		util.Debugf("Accepted connection %s", engine)
+		go func() { // Start goroutine to run the engine event loop
+			engine.Run()
+			util.Debugf("Closed %s", engine)
+		}()
 	}
 }
 
-type broker struct {
-	queues util.Queues
-}
-
-func newBroker() *broker {
-	return &broker{util.MakeQueues(*qsize)}
-}
-
-// connection creates a new AMQP connection for a net.Conn.
-func (b *broker) connection(conn net.Conn) error {
-	delegator := proton.NewMessagingDelegator(newHandler(&b.queues, *credit))
-	// We want to accept messages when they are enqueued, not just when they
-	// are received, so we turn off auto-accept and prefetch by the handler.
-	delegator.Prefetch = 0
-	delegator.AutoAccept = false
-	engine, err := proton.NewEngine(conn, delegator)
-	if err != nil {
-		return err
-	}
-	engine.Server() // Enable server-side protocol negotiation.
-	go func() {     // Start goroutine to run the engine event loop
-		engine.Run()
-		util.Debugf("Closed %s", engine)
-	}()
-	util.Debugf("Accepted %s", engine)
-	return nil
-}
-
-// receiver is a channel to buffer messages waiting to go on the queue.
-type receiver chan receivedMessage
-
-// receivedMessage is a message and the corresponding delivery for acknowledgement.
-type receivedMessage struct {
-	delivery proton.Delivery
-	message  amqp.Message
-}
-
-// sender is a signal channel, closed when we are done sending.
-type sender chan struct{}
-
 // handler handles AMQP events. There is one handler per connection.  The
-// handler does not need to be concurrent-safe as proton will serialize all
-// calls to a handler. We will use channels to communicate from the handler
-// to goroutines sending and receiving messages.
+// handler does not need to be concurrent-safe as proton.Engine will serialize
+// all calls to the handler. We use channels to communicate between the handler
+// goroutine and other goroutines sending and receiving messages.
 type handler struct {
 	queues    *util.Queues
-	credit    int // Credit window for receiver flow control.
-	receivers map[proton.Link]receiver
-	senders   map[proton.Link]sender
+	receivers map[proton.Link]*receiver
+	senders   map[proton.Link]*sender
+	injecter  proton.Injecter
 }
 
-func newHandler(queues *util.Queues, credit int) *handler {
+func newHandler(queues *util.Queues) *handler {
 	return &handler{
-		queues,
-		credit,
-		make(map[proton.Link]receiver),
-		make(map[proton.Link]sender),
+		queues:    queues,
+		receivers: make(map[proton.Link]*receiver),
+		senders:   make(map[proton.Link]*sender),
 	}
 }
 
-// Handle an AMQP event.
+// HandleMessagingEvent handles an event, called in the handler goroutine.
 func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
 	switch t {
 
+	case proton.MStart:
+		h.injecter = e.Injecter()
+
 	case proton.MLinkOpening:
-		l := e.Link()
-		var err error
-		if l.IsReceiver() {
-			err = h.receiver(l)
-		} else { // IsSender()
-			err = h.sender(l)
-		}
-		if err == nil {
-			util.Debugf("%s opened", l)
+		if e.Link().IsReceiver() {
+			h.startReceiver(e)
 		} else {
-			util.Debugf("%s open error: %s", l, err)
-			proton.CloseError(l, err)
+			h.startSender(e)
 		}
 
-	case proton.MLinkClosing:
-		l := e.Link()
-		if r, ok := h.receivers[l]; ok {
-			close(r)
-			delete(h.receivers, l)
-		} else if s, ok := h.senders[l]; ok {
-			close(s)
-			delete(h.senders, l)
-		}
-		util.Debugf("%s closed", l)
+	case proton.MLinkClosed:
+		h.linkClosed(e.Link(), e.Link().RemoteCondition().Error())
 
 	case proton.MSendable:
-		l := e.Link()
-		q := h.queues.Get(l.RemoteSource().Address())
-		if n, err := h.sendAll(e.Link(), q); err == nil && n > 0 {
-			// Still have credit, start a watcher.
-			go h.sendWatch(e.Link(), q)
+		if s, ok := h.senders[e.Link()]; ok {
+			s.sendable() // Signal the send goroutine that we have credit.
+		} else {
+			proton.CloseError(e.Link(), amqp.Errorf(amqp.NotFound, "link %s sender not found", e.Link()))
 		}
 
 	case proton.MMessage:
-		l := e.Link()
-		d := e.Delivery()
-		m, err := d.Message() // Must decode message immediately before link state changes.
+		m, err := e.Delivery().Message() // Message() must be called while handling the MMessage event.
 		if err != nil {
-			util.Debugf("%s error decoding message: %s", e.Link(), err)
-			proton.CloseError(l, err)
-		} else {
-			// This will not block, AMQP credit prevents us from overflowing the buffer.
-			h.receivers[l] <- receivedMessage{d, m}
-			util.Debugf("%s received %s", l, util.FormatMessage(m))
+			proton.CloseError(e.Link(), err)
+			break
 		}
+		r, ok := h.receivers[e.Link()]
+		if !ok {
+			proton.CloseError(e.Link(), amqp.Errorf(amqp.NotFound, "link %s receiver not found", e.Link()))
+			break
+		}
+		// This will not block as AMQP credit is set to the buffer capacity.
+		r.buffer <- receivedMessage{e.Delivery(), m}
+		util.Debugf("link %s received %s", e.Link(), util.FormatMessage(m))
 
-	case proton.MConnectionClosing, proton.MDisconnected:
-		for l, r := range h.receivers {
-			close(r)
-			delete(h.receivers, l)
+	case proton.MConnectionClosed, proton.MDisconnected:
+		for l, _ := range h.receivers {
+			h.linkClosed(l, nil)
 		}
-		for l, s := range h.senders {
-			close(s)
-			delete(h.senders, l)
+		for l, _ := range h.senders {
+			h.linkClosed(l, nil)
 		}
 	}
 }
 
-// receiver is called by the handler when a receiver link opens.
+// linkClosed is called when a link has been closed by both ends.
+// It removes the link from the handlers maps and stops its goroutine.
+func (h *handler) linkClosed(l proton.Link, err error) {
+	if s, ok := h.senders[l]; ok {
+		s.stop()
+		delete(h.senders, l)
+	} else if r, ok := h.receivers[l]; ok {
+		r.stop()
+		delete(h.receivers, l)
+	}
+}
+
+// link has some common data and methods that are used by the sender and receiver types.
 //
-// It sets up data structures in the handler and then starts a goroutine
-// to receive messages and put them on a queue.
-func (h *handler) receiver(l proton.Link) error {
-	q := h.queues.Get(l.RemoteTarget().Address())
-	buffer := make(receiver, h.credit)
-	h.receivers[l] = buffer
-	l.Flow(cap(buffer)) // credit==cap(buffer) so we won't overflow the buffer.
-	go h.runReceive(l, buffer, q)
-	return nil
+// An active link is represented by a sender or receiver value and a goroutine
+// running its run() method. The run() method communicates with the handler via
+// channels.
+type link struct {
+	l proton.Link
+	q util.Queue
+	h *handler
+}
+
+func makeLink(l proton.Link, q util.Queue, h *handler) link {
+	lnk := link{l: l, q: q, h: h}
+	return lnk
+}
+
+// receiver has a channel to buffer messages that have been received by the
+// handler and are waiting to go on the queue. AMQP credit ensures that the
+// handler does not overflow the buffer and block.
+type receiver struct {
+	link
+	buffer chan receivedMessage
 }
 
-// runReceive moves messages from buffer to queue
-func (h *handler) runReceive(l proton.Link, buffer receiver, q util.Queue) {
-	for rm := range buffer {
-		q <- rm.message
-		rm2 := rm // Save in temp var for injected closure
-		err := l.Connection().Injecter().Inject(func() {
-			rm2.delivery.Accept()
-			l.Flow(1)
+// receivedMessage holds a message and a Delivery so that the message can be
+// acknowledged when it is put on the queue.
+type receivedMessage struct {
+	delivery proton.Delivery
+	message  amqp.Message
+}
+
+// startReceiver creates a receiver and a goroutine for its run() method.
+func (h *handler) startReceiver(e proton.Event) {
+	q := h.queues.Get(e.Link().RemoteTarget().Address())
+	r := &receiver{
+		link:   makeLink(e.Link(), q, h),
+		buffer: make(chan receivedMessage, *credit),
+	}
+	h.receivers[r.l] = r
+	r.l.Flow(cap(r.buffer)) // Give credit to fill the buffer to capacity.
+	go r.run()
+}
+
+// run runs in a separate goroutine. It moves messages from the buffer to the
+// queue for a receiver link, and injects a handler function to acknowledge the
+// message and send a credit.
+func (r *receiver) run() {
+	for rm := range r.buffer {
+		r.q <- rm.message
+		d := rm.delivery
+		// We are not in the handler goroutine so we Inject the accept function as a closure.
+		r.h.injecter.Inject(func() {
+			// Check that the receiver is still open, it may have been closed by the remote end.
+			if r == r.h.receivers[r.l] {
+				d.Accept()  // Accept the delivery
+				r.l.Flow(1) // Add one credit
+			}
 		})
-		if err != nil {
-			util.Debugf("%s receive error: %s", l, err)
-			proton.CloseError(l, err)
-		}
 	}
 }
 
-// sender is called by the handler when a sender link opens.
-// It sets up a sender structures in the handler.
-func (h *handler) sender(l proton.Link) error {
-	h.senders[l] = make(sender)
-	return nil
+// stop closes the buffer channel and waits for the run() goroutine to stop.
+func (r *receiver) stop() {
+	close(r.buffer)
 }
 
-// send one message in handler context, assumes we have credit.
-func (h *handler) send(l proton.Link, m amqp.Message, q util.Queue) error {
-	delivery, err := l.Send(m)
-	if err != nil {
-		h.closeSender(l, err)
-		return err
+// sender has a channel that is used to signal when there is credit to send messages.
+type sender struct {
+	link
+	credit chan struct{} // Channel to signal availability of credit.
+}
+
+// startSender creates a sender and starts a goroutine for sender.run()
+func (h *handler) startSender(e proton.Event) {
+	q := h.queues.Get(e.Link().RemoteSource().Address())
+	s := &sender{
+		link:   makeLink(e.Link(), q, h),
+		credit: make(chan struct{}, 1), // Capacity of 1 for signalling.
 	}
-	delivery.Settle() // Pre-settled, unreliable.
-	util.Debugf("%s sent %s", l, util.FormatMessage(m))
-	return nil
+	h.senders[e.Link()] = s
+	go s.run()
 }
 
-// sendAll sends as many messages as possible without blocking, call in handler context.
-// Returns the number of credits left, >0 means we ran out of messages.
-func (h *handler) sendAll(l proton.Link, q util.Queue) (int, error) {
-	for l.Credit() > 0 {
-		select {
-		case m, ok := <-q:
-			if ok { // Got a message
-				if err := h.send(l, m, q); err != nil {
-					return 0, err
-				}
-			} else { // Queue is closed
-				l.Close()
-				return 0, io.EOF
-			}
-		default: // Queue empty
-			return l.Credit(), nil
-		}
+// stop closes the credit channel and waits for the run() goroutine to stop.
+func (s *sender) stop() {
+	close(s.credit)
+}
+
+// sendable signals that the sender has credit, it does not block.
+// sender.credit has capacity 1, if it is already full we carry on.
+func (s *sender) sendable() {
+	select { // Non-blocking
+	case s.credit <- struct{}{}:
+	default:
 	}
-	return l.Credit(), nil
 }
 
-// sendWatch watches the queue for more messages and re-runs sendAll.
-// Run in a separate goroutine, so must inject handler functions.
-func (h *handler) sendWatch(l proton.Link, q util.Queue) {
-	select {
-	case m, ok := <-q:
-		l.Connection().Injecter().Inject(func() {
-			if ok {
-				if h.send(l, m, q) != nil {
+// run runs in a separate goroutine. It monitors the queue for messages and injects
+// a function to send them when there is credit
+func (s *sender) run() {
+	var q chan amqp.Message // q is nil initially as we have no credit.
+	for {
+		select {
+		case _, ok := <-s.credit:
+			if !ok { // sender closed
+				return
+			}
+			q = s.q // We have credit, enable selecting on the queue.
+
+		case m, ok := <-q: // q is only enabled when we have credit.
+			if !ok { // queue closed
+				return
+			}
+			q = nil                      // Assume all credit will be used used, will be signaled otherwise.
+			s.h.injecter.Inject(func() { // Inject handler function to actually send
+				if s.h.senders[s.l] != s { // The sender has been closed by the remote end.
+					go func() { q <- m }() // Put the message back on the queue but don't block
 					return
 				}
-				if n, err := h.sendAll(l, q); err != nil {
+				if s.sendOne(m) != nil {
 					return
-				} else if n > 0 {
-					go h.sendWatch(l, q) // Start a new watcher.
 				}
-			}
-		})
-	case <-h.senders[l]: // Closed
-		return
+				// Send as many more messages as we can without blocking
+				for s.l.Credit() > 0 {
+					select { // Non blocking receive from q
+					case m, ok := <-s.q:
+						if ok {
+							s.sendOne(m)
+						}
+					default: // Queue is empty but we have credit, signal the run() goroutine.
+						s.sendable()
+					}
+				}
+			})
+		}
 	}
 }
 
-// closeSender closes a sender link and signals goroutines processing that sender.
-func (h *handler) closeSender(l proton.Link, err error) {
-	util.Debugf("%s sender closed: %s", l, err)
-	proton.CloseError(l, err)
-	close(h.senders[l])
-	delete(h.senders, l)
+// sendOne runs in the handler goroutine. It sends a single message.
+func (s *sender) sendOne(m amqp.Message) error {
+	delivery, err := s.l.Send(m)
+	if err == nil {
+		delivery.Settle() // Pre-settled, unreliable.
+		util.Debugf("link %s sent %s", s.l, util.FormatMessage(m))
+	} else {
+		go func() { s.q <- m }() // Put the message back on the queue but don't block
+	}
+	return err
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/examples/go/util/util.go
----------------------------------------------------------------------
diff --git a/examples/go/util/util.go b/examples/go/util/util.go
index 5118467..20f2192 100644
--- a/examples/go/util/util.go
+++ b/examples/go/util/util.go
@@ -64,5 +64,5 @@ func FormatMessage(m amqp.Message) string {
 func init() {
 	log.SetFlags(0)
 	_, prog := path.Split(os.Args[0])
-	log.SetPrefix(prog + ": ")
+	log.SetPrefix(fmt.Sprintf("%s(%d): ", prog, os.Getpid()))
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 51c2d86..74c7e13 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -75,14 +75,17 @@ foreach (pkg amqp proton electron)
   set(sources "${GoFiles}${CgoFiles}")
 
   # Build the package library
-  add_custom_command(OUTPUT ${lib} COMMAND ${GO_INSTALL} ${package} DEPENDS ${sources} ${cdepends})
+  add_custom_command(
+    OUTPUT ${lib} COMMAND ${GO_INSTALL} ${package} DEPENDS ${sources} ${cdepends}
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
   set(target go-package-${pkg})
   add_custom_target(${target} ALL DEPENDS ${lib})
 
   # Package test
   go_sources(TestGoFiles)
   set(test_exe ${CMAKE_CURRENT_BINARY_DIR}/${pkg}.test)
-  add_custom_command(OUTPUT ${test_exe} COMMAND ${GO_TEST} -c -o ${test_exe} ${package}
+  add_custom_command(
+    OUTPUT ${test_exe} COMMAND ${GO_TEST} -c -o ${test_exe} ${package}
     DEPENDS ${target} qpid-proton)
   add_custom_target(go-package-test-${pkg} ALL DEPENDS ${test_exe})
   add_test(NAME go_test_${pkg} COMMAND ${test_exe} WORKING_DIRECTORY ${dir})

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
index bef8c17..d6761d6 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
@@ -28,131 +28,114 @@ import (
 	"qpid.apache.org/internal"
 	"qpid.apache.org/proton"
 	"sync"
+	"time"
 )
 
 // Connection is an AMQP connection, created by a Container.
 type Connection interface {
 	Endpoint
 
-	// Server puts the connection in server mode, must be called before Open().
-	//
-	// A server connection will do protocol negotiation to accept a incoming AMQP
-	// connection. Normally you would call this for a connection created by
-	// net.Listener.Accept()
-	//
-	Server()
-
-	// Listen arranges for endpoints opened by the remote peer to be passed to accept().
-	// Listen() must be called before Connection.Open().
-	//
-	// accept() is passed a Session, Sender or Receiver.  It can examine endpoint
-	// properties and set some properties (e.g. Receiver.SetCapacity()) Returning nil
-	// will accept the endpoint, returning an error will reject it.
-	//
-	// accept() must not block or use the endpoint other than to examine or set
-	// properties.  It can start a goroutine to process the Endpoint, or pass the
-	// Endpoint to another goroutine via a channel, and that goroutine can use
-	// the endpoint as normal.
-	//
-	// The default Listen function is RejectEndpoint which rejects all endpoints.
-	// You can call Listen(AcceptEndpoint) to accept all endpoints
-	Listen(accept func(Endpoint) error)
-
-	// Open the connection, ready for use.
-	Open() error
-
 	// Sender opens a new sender on the DefaultSession.
 	//
 	// v can be a string, which is used as the Target address, or a SenderSettings
 	// struct containing more details settings.
-	Sender(setting ...LinkSetting) (Sender, error)
+	Sender(...LinkSetting) (Sender, error)
 
 	// Receiver opens a new Receiver on the DefaultSession().
 	//
 	// v can be a string, which is used as the
 	// Source address, or a ReceiverSettings struct containing more details
 	// settings.
-	Receiver(setting ...LinkSetting) (Receiver, error)
+	Receiver(...LinkSetting) (Receiver, error)
 
 	// DefaultSession() returns a default session for the connection. It is opened
 	// on the first call to DefaultSession and returned on subsequent calls.
 	DefaultSession() (Session, error)
 
 	// Session opens a new session.
-	Session() (Session, error)
+	Session(...SessionSetting) (Session, error)
 
 	// Container for the connection.
 	Container() Container
 
 	// Disconnect the connection abruptly with an error.
 	Disconnect(error)
-}
 
-// AcceptEndpoint pass to Connection.Listen to accept all endpoints
-func AcceptEndpoint(Endpoint) error { return nil }
+	// Wait waits for the connection to be disconnected.
+	Wait() error
 
-// RejectEndpoint pass to Connection.Listen to reject all endpoints
-func RejectEndpoint(Endpoint) error {
-	return amqp.Errorf(amqp.NotAllowed, "remote open rejected")
+	// WaitTimeout is like Wait but returns Timeout if the timeout expires.
+	WaitTimeout(time.Duration) error
+}
+
+// ConnectionSetting can be passed when creating a connection.
+// See functions that return ConnectionSetting for details
+type ConnectionSetting func(*connection)
+
+// Server setting puts the connection in server mode.
+//
+// A server connection will do protocol negotiation to accept a incoming AMQP
+// connection. Normally you would call this for a connection created by
+// net.Listener.Accept()
+//
+func Server() ConnectionSetting { return func(c *connection) { c.engine.Server() } }
+
+// Accepter provides a function to be called when a connection receives an incoming
+// request to open an endpoint, one of IncomingSession, IncomingSender or IncomingReceiver.
+//
+// The accept() function must not block or use the accepted endpoint.
+// It can pass the endpoint to another goroutine for processing.
+//
+// By default all incoming endpoints are rejected.
+func Accepter(accept func(Incoming)) ConnectionSetting {
+	return func(c *connection) { c.accept = accept }
 }
 
 type connection struct {
 	endpoint
 	listenOnce, defaultSessionOnce, closeOnce sync.Once
 
-	// Set before Open()
-	container *container
-	conn      net.Conn
-	accept    func(Endpoint) error
-
-	// Set by Open()
+	container   *container
+	conn        net.Conn
+	accept      func(Incoming)
 	handler     *handler
 	engine      *proton.Engine
 	err         internal.ErrorHolder
 	eConnection proton.Connection
 
 	defaultSession Session
+	done           chan struct{}
 }
 
-func newConnection(conn net.Conn, cont *container) (*connection, error) {
-	c := &connection{container: cont, conn: conn, accept: RejectEndpoint}
+func newConnection(conn net.Conn, cont *container, setting ...ConnectionSetting) (*connection, error) {
+	c := &connection{container: cont, conn: conn, accept: func(Incoming) {}, done: make(chan struct{})}
 	c.handler = newHandler(c)
 	var err error
 	c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
 	if err != nil {
 		return nil, err
 	}
+	for _, set := range setting {
+		set(c)
+	}
 	c.str = c.engine.String()
 	c.eConnection = c.engine.Connection()
+	go func() { c.engine.Run(); close(c.done) }()
 	return c, nil
 }
 
-func (c *connection) Server() { c.engine.Server() }
-
-func (c *connection) Listen(accept func(Endpoint) error) { c.accept = accept }
-
-func (c *connection) Open() error {
-	go c.engine.Run()
-	return nil
-}
-
-func (c *connection) Close(err error) { c.engine.Close(err) }
+func (c *connection) Close(err error) { c.err.Set(err); c.engine.Close(err) }
 
-func (c *connection) Disconnect(err error) { c.engine.Disconnect(err) }
+func (c *connection) Disconnect(err error) { c.err.Set(err); c.engine.Disconnect(err) }
 
-func (c *connection) closed(err error) {
-	// Call from another goroutine to initiate close without deadlock.
-	go c.Close(err)
-}
-
-func (c *connection) Session() (Session, error) {
+func (c *connection) Session(setting ...SessionSetting) (Session, error) {
 	var s Session
 	err := c.engine.InjectWait(func() error {
 		eSession, err := c.engine.Connection().Session()
 		if err == nil {
 			eSession.Open()
 			if err == nil {
-				s = newSession(c, eSession)
+				s = newSession(c, eSession, setting...)
 			}
 		}
 		return err
@@ -189,3 +172,47 @@ func (c *connection) Receiver(setting ...LinkSetting) (Receiver, error) {
 }
 
 func (c *connection) Connection() Connection { return c }
+
+func (c *connection) Wait() error { return c.WaitTimeout(Forever) }
+func (c *connection) WaitTimeout(timeout time.Duration) error {
+	_, err := timedReceive(c.done, timeout)
+	if err == Timeout {
+		return Timeout
+	}
+	return c.Error()
+}
+
+// Incoming is the interface for incoming requests to open an endpoint.
+// Implementing types are IncomingSession, IncomingSender and IncomingReceiver.
+type Incoming interface {
+	// Accept the endpoint with default settings.
+	//
+	// You must not use the returned endpoint in the accept() function that
+	// receives the Incoming value, but you can pass it to other goroutines.
+	//
+	// Implementing types provide type-specific Accept functions that take additional settings.
+	Accept() Endpoint
+
+	// Reject the endpoint with an error
+	Reject(error)
+
+	error() error
+}
+
+type incoming struct {
+	err      error
+	accepted bool
+}
+
+func (i *incoming) Reject(err error) { i.err = err }
+
+func (i *incoming) error() error {
+	switch {
+	case i.err != nil:
+		return i.err
+	case !i.accepted:
+		return amqp.Errorf(amqp.NotAllowed, "remote open rejected")
+	default:
+		return nil
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/container.go b/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
index 06a9a14..7bbc4b0 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
@@ -39,7 +39,7 @@ type Container interface {
 	// setting any Connection properties you need to set. Note the net.Conn
 	// can be an outgoing connection (e.g. made with net.Dial) or an incoming
 	// connection (e.g. made with net.Listener.Accept())
-	Connection(conn net.Conn) (Connection, error)
+	Connection(net.Conn, ...ConnectionSetting) (Connection, error)
 }
 
 type container struct {
@@ -66,6 +66,6 @@ func (cont *container) nextLinkName() string {
 	return cont.id + "@" + cont.linkNames.Next()
 }
 
-func (cont *container) Connection(conn net.Conn) (Connection, error) {
-	return newConnection(conn, cont)
+func (cont *container) Connection(conn net.Conn, setting ...ConnectionSetting) (Connection, error) {
+	return newConnection(conn, cont, setting...)
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
index 1b07109..b518e42 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
@@ -27,7 +27,7 @@ import (
 // NOTE: methods in this file are called only in the proton goroutine unless otherwise indicated.
 
 type handler struct {
-	delegator    *proton.MessagingDelegator
+	delegator    *proton.MessagingAdapter
 	connection   *connection
 	links        map[proton.Link]Link
 	sentMessages map[proton.Delivery]*sentMessage
@@ -41,8 +41,8 @@ func newHandler(c *connection) *handler {
 		sentMessages: make(map[proton.Delivery]*sentMessage),
 		sessions:     make(map[proton.Session]*session),
 	}
-	h.delegator = proton.NewMessagingDelegator(h)
-	// Disable auto features of MessagingDelegator, we do these ourselves.
+	h.delegator = proton.NewMessagingAdapter(h)
+	// Disable auto features of MessagingAdapter, we do these ourselves.
 	h.delegator.Prefetch = 0
 	h.delegator.AutoAccept = false
 	h.delegator.AutoSettle = false
@@ -50,6 +50,10 @@ func newHandler(c *connection) *handler {
 	return h
 }
 
+func (h *handler) internalError(fmt string, arg ...interface{}) {
+	proton.CloseError(h.connection.eConnection, amqp.Errorf(amqp.InternalError, fmt, arg...))
+}
+
 func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
 	switch t {
 
@@ -57,9 +61,7 @@ func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event)
 		if r, ok := h.links[e.Link()].(*receiver); ok {
 			r.message(e.Delivery())
 		} else {
-			proton.CloseError(
-				h.connection.eConnection,
-				amqp.Errorf(amqp.InternalError, "no receiver for link %s", e.Link()))
+			h.internalError("no receiver for link %s", e.Link())
 		}
 
 	case proton.MSettled:
@@ -68,19 +70,18 @@ func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event)
 		}
 
 	case proton.MSendable:
-		h.trySend(e.Link())
+		if s, ok := h.links[e.Link()].(*sender); ok {
+			s.sendable()
+		} else {
+			h.internalError("no receiver for link %s", e.Link())
+		}
 
 	case proton.MSessionOpening:
 		if e.Session().State().LocalUninit() { // Remotely opened
-			s := newSession(h.connection, e.Session())
-			if err := h.connection.accept(s); err != nil {
-				proton.CloseError(e.Session(), (err))
-			} else {
-				h.sessions[e.Session()] = s
-				if s.capacity > 0 {
-					e.Session().SetIncomingCapacity(s.capacity)
-				}
-				e.Session().Open()
+			incoming := &IncomingSession{h: h, pSession: e.Session()}
+			h.connection.accept(incoming)
+			if err := incoming.error(); err != nil {
+				proton.CloseError(e.Session(), err)
 			}
 		}
 
@@ -95,33 +96,24 @@ func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event)
 
 	case proton.MLinkOpening:
 		l := e.Link()
-		if l.State().LocalUninit() { // Remotely opened
-			ss := h.sessions[l.Session()]
-			if ss == nil {
-				proton.CloseError(
-					l, amqp.Errorf(amqp.InternalError, ("no session for link")))
-				break
-			}
-			var link Link
-			if l.IsReceiver() {
-				r := &receiver{link: incomingLink(ss, l)}
-				link = r
-				r.inAccept = true
-				defer func() { r.inAccept = false }()
-			} else {
-				link = &sender{link: incomingLink(ss, l)}
-			}
-			if err := h.connection.accept(link); err != nil {
-				proton.CloseError(l, err)
-				break
-			}
-			link.open()
+		if l.State().LocalActive() { // Already opened locally.
+			break
 		}
-
-	case proton.MLinkOpened:
-		l := e.Link()
-		if l.IsSender() {
-			h.trySend(l)
+		ss := h.sessions[l.Session()]
+		if ss == nil {
+			h.internalError("no session for link %s", e.Link())
+			break
+		}
+		var incoming Incoming
+		if l.IsReceiver() {
+			incoming = &IncomingReceiver{makeIncomingLink(ss, l)}
+		} else {
+			incoming = &IncomingSender{makeIncomingLink(ss, l)}
+		}
+		h.connection.accept(incoming)
+		if err := incoming.error(); err != nil {
+			proton.CloseError(l, err)
+			break
 		}
 
 	case proton.MLinkClosing:
@@ -130,7 +122,17 @@ func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event)
 	case proton.MLinkClosed:
 		h.linkClosed(e.Link(), proton.EndpointError(e.Link()))
 
+	case proton.MConnectionClosing:
+		h.connection.err.Set(e.Connection().RemoteCondition().Error())
+
+	case proton.MConnectionClosed:
+		h.connection.err.Set(Closed) // If no error already set, this is an orderly close.
+
 	case proton.MDisconnected:
+		h.connection.err.Set(e.Transport().Condition().Error())
+		// If err not set at this point (e.g. to Closed) then this is unexpected.
+		h.connection.err.Set(amqp.Errorf(amqp.IllegalState, "unexpected disconnect on %s", h.connection))
+
 		err := h.connection.Error()
 		for l, _ := range h.links {
 			h.linkClosed(l, err)
@@ -154,19 +156,3 @@ func (h *handler) linkClosed(l proton.Link, err error) {
 func (h *handler) addLink(rl proton.Link, ll Link) {
 	h.links[rl] = ll
 }
-
-func (h *handler) trySend(l proton.Link) {
-	if l.Credit() <= 0 {
-		return
-	}
-	if s, ok := h.links[l].(*sender); ok {
-		for ch := s.popBlocked(); l.Credit() > 0 && ch != nil; ch = s.popBlocked() {
-			if snd, ok := <-ch; ok {
-				s.doSend(snd)
-			}
-		}
-	} else {
-		h.connection.closed(
-			amqp.Errorf(amqp.InternalError, "cannot find sender for link %s", l))
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/link.go b/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
index abc8431..4bef53b 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
@@ -60,39 +60,39 @@ type Link interface {
 	open()
 }
 
-// LinkSetting is a function that sets a link property. Passed when creating
-// a Sender or Receiver, do not use at any other time.
-type LinkSetting func(Link)
+// LinkSetting can be passed when creating a sender or receiver.
+// See functions that return LinkSetting for details
+type LinkSetting func(*link)
 
 // Source sets address that messages are coming from.
-func Source(s string) LinkSetting { return func(l Link) { l.(*link).source = s } }
+func Source(s string) LinkSetting { return func(l *link) { l.source = s } }
 
 // Target sets address that messages are going to.
-func Target(s string) LinkSetting { return func(l Link) { l.(*link).target = s } }
+func Target(s string) LinkSetting { return func(l *link) { l.target = s } }
 
 // LinkName sets the link name.
-func LinkName(s string) LinkSetting { return func(l Link) { l.(*link).target = s } }
+func LinkName(s string) LinkSetting { return func(l *link) { l.target = s } }
 
 // SndSettle sets the send settle mode
-func SndSettle(m SndSettleMode) LinkSetting { return func(l Link) { l.(*link).sndSettle = m } }
+func SndSettle(m SndSettleMode) LinkSetting { return func(l *link) { l.sndSettle = m } }
 
 // RcvSettle sets the send settle mode
-func RcvSettle(m RcvSettleMode) LinkSetting { return func(l Link) { l.(*link).rcvSettle = m } }
+func RcvSettle(m RcvSettleMode) LinkSetting { return func(l *link) { l.rcvSettle = m } }
 
 // SndSettleMode defines when the sending end of the link settles message delivery.
 type SndSettleMode proton.SndSettleMode
 
 // Capacity sets the link capacity
-func Capacity(n int) LinkSetting { return func(l Link) { l.(*link).capacity = n } }
+func Capacity(n int) LinkSetting { return func(l *link) { l.capacity = n } }
 
 // Prefetch sets a receivers pre-fetch flag. Not relevant for a sender.
-func Prefetch(p bool) LinkSetting { return func(l Link) { l.(*link).prefetch = p } }
+func Prefetch(p bool) LinkSetting { return func(l *link) { l.prefetch = p } }
 
 // AtMostOnce sets "fire and forget" mode, messages are sent but no
 // acknowledgment is received, messages can be lost if there is a network
 // failure. Sets SndSettleMode=SendSettled and RcvSettleMode=RcvFirst
 func AtMostOnce() LinkSetting {
-	return func(l Link) {
+	return func(l *link) {
 		SndSettle(SndSettled)(l)
 		RcvSettle(RcvFirst)(l)
 	}
@@ -104,7 +104,7 @@ func AtMostOnce() LinkSetting {
 // that the message will be received twice in this case.
 // Sets SndSettleMode=SndUnsettled and RcvSettleMode=RcvFirst
 func AtLeastOnce() LinkSetting {
-	return func(l Link) {
+	return func(l *link) {
 		SndSettle(SndUnsettled)(l)
 		RcvSettle(RcvFirst)(l)
 	}
@@ -145,8 +145,6 @@ type link struct {
 	session *session
 	eLink   proton.Link
 	done    chan struct{} // Closed when link is closed
-
-	inAccept bool
 }
 
 func (l *link) Source() string           { return l.source }
@@ -163,8 +161,8 @@ func (l *link) engine() *proton.Engine { return l.session.connection.engine }
 func (l *link) handler() *handler      { return l.session.connection.handler }
 
 // Set up link fields and open the proton.Link
-func localLink(sn *session, isSender bool, setting ...LinkSetting) (*link, error) {
-	l := &link{
+func localLink(sn *session, isSender bool, setting ...LinkSetting) (link, error) {
+	l := link{
 		session:  sn,
 		isSender: isSender,
 		capacity: 1,
@@ -172,7 +170,7 @@ func localLink(sn *session, isSender bool, setting ...LinkSetting) (*link, error
 		done:     make(chan struct{}),
 	}
 	for _, set := range setting {
-		set(l)
+		set(&l)
 	}
 	if l.linkName == "" {
 		l.linkName = l.session.connection.container.nextLinkName()
@@ -184,7 +182,7 @@ func localLink(sn *session, isSender bool, setting ...LinkSetting) (*link, error
 	}
 	if l.eLink.IsNil() {
 		l.err.Set(internal.Errorf("cannot create link %s", l))
-		return nil, l.err.Get()
+		return l, l.err.Get()
 	}
 	l.eLink.Source().SetAddress(l.source)
 	l.eLink.Target().SetAddress(l.target)
@@ -195,20 +193,27 @@ func localLink(sn *session, isSender bool, setting ...LinkSetting) (*link, error
 	return l, nil
 }
 
+type incomingLink struct {
+	incoming
+	link
+}
+
 // Set up a link from an incoming proton.Link.
-func incomingLink(sn *session, eLink proton.Link) link {
-	l := link{
-		session:   sn,
-		isSender:  eLink.IsSender(),
-		eLink:     eLink,
-		source:    eLink.RemoteSource().Address(),
-		target:    eLink.RemoteTarget().Address(),
-		linkName:  eLink.Name(),
-		sndSettle: SndSettleMode(eLink.RemoteSndSettleMode()),
-		rcvSettle: RcvSettleMode(eLink.RemoteRcvSettleMode()),
-		capacity:  1,
-		prefetch:  false,
-		done:      make(chan struct{}),
+func makeIncomingLink(sn *session, eLink proton.Link) incomingLink {
+	l := incomingLink{
+		link: link{
+			session:   sn,
+			isSender:  eLink.IsSender(),
+			eLink:     eLink,
+			source:    eLink.RemoteSource().Address(),
+			target:    eLink.RemoteTarget().Address(),
+			linkName:  eLink.Name(),
+			sndSettle: SndSettleMode(eLink.RemoteSndSettleMode()),
+			rcvSettle: RcvSettleMode(eLink.RemoteRcvSettleMode()),
+			capacity:  1,
+			prefetch:  false,
+			done:      make(chan struct{}),
+		},
 	}
 	l.str = eLink.String()
 	return l

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go b/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
index 92c0b90..59ac018 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
@@ -20,10 +20,9 @@ under the License.
 package electron
 
 import (
+	"qpid.apache.org/amqp"
 	"qpid.apache.org/internal"
 	"qpid.apache.org/proton"
-	"qpid.apache.org/amqp"
-	"sync"
 	"time"
 )
 
@@ -63,10 +62,6 @@ type Receiver interface {
 	// Capacity is the size (number of messages) of the local message buffer
 	// These are messages received but not yet returned to the application by a call to Receive()
 	Capacity() int
-
-	// SetCapacity sets Capacity and Prefetch of an accepted Receiver.
-	// May only be called in an accept() function, see Connection.Listen()
-	SetCapacity(capacity int, prefetch bool)
 }
 
 // Flow control policy for a receiver.
@@ -120,18 +115,12 @@ func (p noPrefetchPolicy) Post(r *receiver, err error) {
 // Receiver implementation
 type receiver struct {
 	link
-	buffer    chan ReceivedMessage
-	policy    policy
-	setupOnce sync.Once
-}
-
-func (r *receiver) SetCapacity(capacity int, prefetch bool) {
-	internal.Assert(r.inAccept, "Receiver.SetCapacity called outside of accept function")
-	r.capacity = capacity
-	r.prefetch = prefetch
+	buffer chan ReceivedMessage
+	policy policy
 }
 
-func (r *receiver) setup() {
+func newReceiver(l link) *receiver {
+	r := &receiver{link: l}
 	if r.capacity < 1 {
 		r.capacity = 1
 	}
@@ -141,6 +130,9 @@ func (r *receiver) setup() {
 		r.policy = &noPrefetchPolicy{}
 	}
 	r.buffer = make(chan ReceivedMessage, r.capacity)
+	r.handler().addLink(r.eLink, r)
+	r.link.open()
+	return r
 }
 
 // call in proton goroutine.
@@ -156,15 +148,14 @@ func (r *receiver) Receive() (rm ReceivedMessage, err error) {
 }
 
 func (r *receiver) ReceiveTimeout(timeout time.Duration) (rm ReceivedMessage, err error) {
-	r.setupOnce.Do(r.setup)
 	internal.Assert(r.buffer != nil, "Receiver is not open: %s", r)
 	r.policy.Pre(r)
 	defer func() { r.policy.Post(r, err) }()
-	rmi, ok, timedout := timedReceive(r.buffer, timeout)
-	switch {
-	case timedout:
+	rmi, err := timedReceive(r.buffer, timeout)
+	switch err {
+	case Timeout:
 		return ReceivedMessage{}, Timeout
-	case !ok:
+	case Closed:
 		return ReceivedMessage{}, r.Error()
 	default:
 		return rmi.(ReceivedMessage), nil
@@ -194,12 +185,6 @@ func (r *receiver) message(delivery proton.Delivery) {
 	}
 }
 
-func (r *receiver) open() {
-	r.setupOnce.Do(r.setup)
-	r.link.open()
-	r.handler().addLink(r.eLink, r)
-}
-
 func (r *receiver) closed(err error) {
 	r.link.closed(err)
 	if r.buffer != nil {
@@ -230,3 +215,24 @@ func (rm *ReceivedMessage) Accept() error { return rm.Acknowledge(Accepted) }
 
 // Reject is short for Acknowledge(Rejected)
 func (rm *ReceivedMessage) Reject() error { return rm.Acknowledge(Rejected) }
+
+// IncomingReceiver is passed to the accept() function given to Connection.Listen()
+// when there is an incoming request for a receiver link.
+type IncomingReceiver struct {
+	incomingLink
+}
+
+// Link provides information about the incoming link.
+func (i *IncomingReceiver) Link() Link { return i }
+
+// AcceptReceiver sets Capacity and Prefetch of the accepted Receiver.
+func (i *IncomingReceiver) AcceptReceiver(capacity int, prefetch bool) Receiver {
+	i.capacity = capacity
+	i.prefetch = prefetch
+	return i.Accept().(Receiver)
+}
+
+func (i *IncomingReceiver) Accept() Endpoint {
+	i.accepted = true
+	return newReceiver(i.link)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go b/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
index 3124f74..68cfbb3 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
@@ -23,10 +23,9 @@ package electron
 import "C"
 
 import (
-	"container/list"
+	"qpid.apache.org/amqp"
 	"qpid.apache.org/internal"
 	"qpid.apache.org/proton"
-	"qpid.apache.org/amqp"
 	"reflect"
 	"time"
 )
@@ -69,7 +68,7 @@ type sendMessage struct {
 
 type sender struct {
 	link
-	blocked list.List // Channel of sendMessage for blocked senders.
+	credit chan struct{} // Signal available credit.
 }
 
 // Disposition indicates the outcome of a settled message delivery.
@@ -102,31 +101,6 @@ func (d Disposition) String() string {
 	}
 }
 
-// Send a message, assumes there is credit
-func (s *sender) doSend(snd sendMessage) {
-	delivery, err := s.eLink.Send(snd.m)
-	switch sm := snd.sm.(type) {
-	case nil:
-		delivery.Settle()
-	case *sentMessage:
-		sm.delivery = delivery
-		if err != nil {
-			sm.settled(err)
-		} else {
-			s.handler().sentMessages[delivery] = sm
-		}
-	default:
-		internal.Assert(false, "bad SentMessage type %T", snd.sm)
-	}
-}
-
-func (s *sender) popBlocked() chan sendMessage {
-	if s.blocked.Len() > 0 {
-		return s.blocked.Remove(s.blocked.Front()).(chan sendMessage)
-	}
-	return nil
-}
-
 func (s *sender) Send(m amqp.Message) (SentMessage, error) {
 	return s.SendTimeout(m, Forever)
 }
@@ -152,52 +126,58 @@ func (s *sender) SendForgetTimeout(m amqp.Message, timeout time.Duration) error
 }
 
 func (s *sender) sendInternal(snd sendMessage, timeout time.Duration) (SentMessage, error) {
-	if s.Error() != nil {
-		return nil, s.Error()
-	}
-	var err error
-	if timeout == 0 {
-		err = s.engine().InjectWait(func() error {
-			if s.eLink.Credit() > 0 {
-				s.doSend(snd)
-				return nil
-			}
-			return Timeout
-		})
-	} else {
-		buf := make(chan sendMessage)
-		done := make(chan struct{})
-		defer close(buf)
-		s.engine().Inject(func() { // Runs concurrently
-			if s.eLink.Credit() > 0 {
-				s.doSend(snd)
-				close(done) // Signal already sent
-			} else {
-				s.blocked.PushBack(buf)
-			}
-		})
-		select {
-		case <-done: // Sent without blocking
-		case buf <- snd: // Sent via blocking channel
-		case <-s.done:
+	if _, err := timedReceive(s.credit, timeout); err != nil { // Wait for credit
+		if err == Closed {
 			err = s.Error()
-		case <-After(timeout):
-			err = Timeout
+			internal.Assert(err != nil)
 		}
+		return nil, err
 	}
-	if err != nil {
+	if err := s.engine().Inject(func() { s.doSend(snd) }); err != nil {
 		return nil, err
 	}
 	return snd.sm, nil
 }
 
+// Send a message. Handler goroutine
+func (s *sender) doSend(snd sendMessage) {
+	delivery, err := s.eLink.Send(snd.m)
+	switch sm := snd.sm.(type) {
+	case nil:
+		delivery.Settle()
+	case *sentMessage:
+		sm.delivery = delivery
+		if err != nil {
+			sm.settled(err)
+		} else {
+			s.handler().sentMessages[delivery] = sm
+		}
+	default:
+		internal.Assert(false, "bad SentMessage type %T", snd.sm)
+	}
+	if s.eLink.Credit() > 0 {
+		s.sendable() // Signal credit.
+	}
+}
+
+// Signal the sender has credit. Any goroutine.
+func (s *sender) sendable() {
+	select { // Non-blocking
+	case s.credit <- struct{}{}: // Set the flag if not already set.
+	default:
+	}
+}
+
 func (s *sender) closed(err error) {
 	s.link.closed(err)
+	close(s.credit)
 }
 
-func (s *sender) open() {
-	s.link.open()
+func newSender(l link) *sender {
+	s := &sender{link: l, credit: make(chan struct{}, 1)}
 	s.handler().addLink(s.eLink, s)
+	s.link.open()
+	return s
 }
 
 // SentMessage represents a previously sent message. It allows you to wait for acknowledgement.
@@ -285,7 +265,7 @@ func (sm *sentMessage) Disposition() (Disposition, error) {
 }
 
 func (sm *sentMessage) DispositionTimeout(timeout time.Duration) (Disposition, error) {
-	if _, _, timedout := timedReceive(sm.done, timeout); timedout {
+	if _, err := timedReceive(sm.done, timeout); err == Timeout {
 		return sm.disposition, Timeout
 	} else {
 		return sm.disposition, sm.err
@@ -317,3 +297,19 @@ func (sm *sentMessage) finish() {
 }
 
 func (sm *sentMessage) Error() error { return sm.err }
+
+// IncomingSender is passed to the accept() function given to Connection.Listen()
+// when there is an incoming request for a sender link.
+type IncomingSender struct {
+	incomingLink
+}
+
+// Link provides information about the incoming link.
+func (i *IncomingSender) Link() Link { return i }
+
+func (i *IncomingSender) AcceptSender() Sender { return i.Accept().(Sender) }
+
+func (i *IncomingSender) Accept() Endpoint {
+	i.accepted = true
+	return newSender(i.link)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/session.go b/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
index 612658a..3531da6 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
@@ -24,7 +24,6 @@ import (
 )
 
 // Session is an AMQP session, it contains Senders and Receivers.
-//
 type Session interface {
 	Endpoint
 
@@ -36,10 +35,6 @@ type Session interface {
 	// Source address, or a ReceiverSettings struct containing more details
 	// settings.
 	Receiver(...LinkSetting) (Receiver, error)
-
-	// SetCapacity sets the session buffer capacity in bytes.
-	// Only has effect if called in an accept() function, see Connection.Listen()
-	SetCapacity(bytes uint)
 }
 
 type session struct {
@@ -49,13 +44,27 @@ type session struct {
 	capacity   uint
 }
 
+// SessionSetting can be passed when creating a sender or receiver.
+// See functions that return SessionSetting for details
+type SessionSetting func(*session)
+
+// IncomingCapacity sets the size (in bytes) of the sessions incoming data buffer..
+func IncomingCapacity(cap uint) SessionSetting { return func(s *session) { s.capacity = cap } }
+
 // in proton goroutine
-func newSession(c *connection, es proton.Session) *session {
-	return &session{
+func newSession(c *connection, es proton.Session, setting ...SessionSetting) *session {
+	s := &session{
 		connection: c,
 		eSession:   es,
 		endpoint:   endpoint{str: es.String()},
 	}
+	for _, set := range setting {
+		set(s)
+	}
+	c.handler.sessions[s.eSession] = s
+	s.eSession.SetIncomingCapacity(s.capacity)
+	s.eSession.Open()
+	return s
 }
 
 func (s *session) Connection() Connection     { return s.connection }
@@ -71,8 +80,7 @@ func (s *session) Sender(setting ...LinkSetting) (snd Sender, err error) {
 	err = s.engine().InjectWait(func() error {
 		l, err := localLink(s, true, setting...)
 		if err == nil {
-			snd = &sender{link: *l}
-			snd.(*sender).open()
+			snd = newSender(l)
 		}
 		return err
 	})
@@ -83,8 +91,7 @@ func (s *session) Receiver(setting ...LinkSetting) (rcv Receiver, err error) {
 	err = s.engine().InjectWait(func() error {
 		l, err := localLink(s, false, setting...)
 		if err == nil {
-			rcv = &receiver{link: *l}
-			rcv.(*receiver).open()
+			rcv = newReceiver(l)
 		}
 		return err
 	})
@@ -96,3 +103,23 @@ func (s *session) closed(err error) {
 	s.err.Set(err)
 	s.err.Set(Closed)
 }
+
+// IncomingSession is passed to the accept() function given to Connection.Listen()
+// when there is an incoming session request.
+type IncomingSession struct {
+	incoming
+	h        *handler
+	pSession proton.Session
+	capacity uint
+}
+
+// AcceptCapacity sets the session buffer capacity of an incoming session in bytes.
+func (i *IncomingSession) AcceptSession(bytes uint) Session {
+	i.capacity = bytes
+	return i.Accept().(Session)
+}
+
+func (i *IncomingSession) Accept() Endpoint {
+	i.accepted = true
+	return newSession(i.h.connection, i.pSession, IncomingCapacity(i.capacity))
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/time.go b/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
index ee61332..3407b82 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
@@ -49,24 +49,25 @@ const Forever time.Duration = -1
 // timeout==0 means do a non-blocking receive attempt. timeout < 0 means block
 // forever. Other values mean block up to the timeout.
 //
-func timedReceive(channel interface{}, timeout time.Duration) (value interface{}, ok bool, timedout bool) {
+// Returns error Timeout on timeout, Closed on channel close.
+func timedReceive(channel interface{}, timeout time.Duration) (interface{}, error) {
 	cases := []reflect.SelectCase{
 		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(channel)},
 	}
-	switch {
-	case timeout == 0: // Non-blocking receive
+	if timeout == 0 { // Non-blocking
 		cases = append(cases, reflect.SelectCase{Dir: reflect.SelectDefault})
-	case timeout == Forever: // Block forever, nothing to add
-	default: // Block up to timeout
+	} else { // Block up to timeout
 		cases = append(cases,
-			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(time.After(timeout))})
+			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(After(timeout))})
 	}
-	chosen, recv, recvOk := reflect.Select(cases)
+	chosen, value, ok := reflect.Select(cases)
 	switch {
+	case !ok:
+		return nil, Closed
 	case chosen == 0:
-		return recv.Interface(), recvOk, false
+		return value.Interface(), nil
 	default:
-		return nil, false, true
+		return nil, Timeout
 	}
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/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 e9d6d6f..51f70f8 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
@@ -23,9 +23,9 @@ You can write clients and servers using this library.
 
 This package is a port of the Proton C API into Go (see
 http://qpid.apache.org/proton) Go programmers may find the 'electron' package
-more convenient, it provides a concurrent-safe API that allows you to do
-procedural loops in goroutines rather than implementing event handlers that must
-run in a single goroutine.
+more convenient. qpid.apache.org/electron provides a concurrent-safe API that
+allows you to run procedural loops in arbitrary goroutines rather than
+implementing event handlers that must run in a single goroutine.
 
 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
@@ -42,21 +42,24 @@ goroutine that feeds events to a proton.MessagingHandler, which you must impleme
 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.)
+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.
 
-All events generated by proton are handled in the single event-loop goroutine
-associated with the Connection and Engine. You can use Engine.Inject() or
-Engine.InjectWait() to inject additional functions into the event loop. Only
-injected functions or handler functions can use proton types (such as Session,
-Link etc.) Handlers and injected functions can set up channels to communicate
-with other goroutines..
+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 Connection and Engine instances are independent, and can run concurrently.
+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 may be easier to use w for some applications.
+handlers to express application logic. It is easier to use for most
+applications.
 
 */
 package proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
index 5dc8727..2cebb49 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
@@ -39,15 +39,26 @@ import (
 	"unsafe"
 )
 
-// Injecter allows functions to be "injected" into an event-processing loop.
+// Injecter allows functions to be "injected" into the event-processing loop, to
+// be called in the same goroutine as event handlers.
 type Injecter interface {
-	// Inject a function into an event-loop concurrency context.
+	// Inject a function into the engine goroutine.
 	//
-	// f() will be called in the same concurrency context as event handers, so it
-	// can safely use values that can used be used in that context. If f blocks it
-	// will block the event loop so be careful calling blocking functions in f.
+	// f() will be called in the same goroutine as event handlers, so it can safely
+	// use values belonging to event handlers without synchronization. f() should
+	// not block, no further events or injected functions can be processed until
+	// f() returns.
 	//
-	// Returns a non-nil error if the function could not be injected.
+	// Returns a non-nil error if the function could not be injected and will
+	// never be called. Otherwise the function will eventually be called.
+	//
+	// Note that proton values (Link, Session, Connection etc.) that existed when
+	// Inject(f) was called may have become invalid by the time f() is executed.
+	// Handlers should handle keep track of Closed events to ensure proton values
+	// are not used after they become invalid. One technique is to have map from
+	// proton values to application values. Check that the map has the correct
+	// proton/application value pair at the start of the injected function and
+	// delete the value from the map when handling a Closed event.
 	Inject(f func()) error
 
 	// InjectWait is like Inject but does not return till f() has completed.
@@ -72,19 +83,14 @@ func (b *bufferChan) buffer() []byte {
 }
 
 // Engine reads from a net.Conn, decodes AMQP events and calls the appropriate
-// Handler functions in a single event-loop goroutine. Actions taken by Handler
-// functions (such as sending messages) are encoded and written to the
-// net.Conn. Create a engine with NewEngine()
-//
-// The Engine runs a proton event loop in the goroutine that calls Engine.Run()
-// and creates goroutines to feed data to/from a net.Conn. You can create
-// multiple Engines to handle multiple connections concurrently.
+// Handler functions sequentially in a single goroutine. Actions taken by
+// Handler functions (such as sending messages) are encoded and written to the
+// net.Conn. You can create multiple Engines to handle multiple connections
+// concurrently.
 //
-// Methods on proton values defined in this package (Sessions, Links etc.) can
-// only be called in the goroutine that executes the corresponding
-// Engine.Run(). You implement the EventHandler or MessagingHandler interfaces
-// and provide those values to NewEngine(). Their HandleEvent method will be
-// called in the Engine goroutine, in typical event-driven style.
+// You implement the EventHandler and/or MessagingHandler interfaces and provide
+// those values to NewEngine(). Their HandleEvent method will be called in the
+// event-handling goroutine.
 //
 // Handlers can pass values from an event (Connections, Links, Deliveries etc.) to
 // other goroutines, store them, or use them as map indexes. Effectively they are
@@ -161,7 +167,7 @@ func NewEngine(conn net.Conn, handlers ...EventHandler) (*Engine, error) {
 	}
 	C.pn_connection_collect(eng.connection.pn, eng.collector)
 	eng.connection.Open()
-	connectionContexts.Put(eng.connection, connectionContext{eng, eng.String()})
+	connectionContexts.Put(eng.connection, connectionContext{eng.String()})
 	return eng, nil
 }
 
@@ -223,6 +229,7 @@ func (eng *Engine) Server() { eng.transport.SetServer() }
 
 // Close the engine's connection, returns when the engine has exited.
 func (eng *Engine) Close(err error) {
+	eng.err.Set(err)
 	eng.Inject(func() {
 		CloseError(eng.connection, err)
 	})
@@ -231,9 +238,7 @@ func (eng *Engine) Close(err error) {
 
 // Disconnect the engine's connection without and AMQP close, returns when the engine has exited.
 func (eng *Engine) Disconnect(err error) {
-	if err != nil {
-		eng.err.Set(err)
-	}
+	eng.err.Set(err)
 	eng.conn.Close()
 	<-eng.running
 }
@@ -281,8 +286,8 @@ func (eng *Engine) Run() error {
 	}()
 
 	wbuf := eng.write.buffer()[:0]
-loop:
-	for {
+
+	for eng.err.Get() == nil {
 		if len(wbuf) == 0 {
 			eng.pop(&wbuf)
 		}
@@ -309,13 +314,12 @@ loop:
 			eng.netError(err)
 		}
 		eng.process()
-		if eng.err.Get() != nil {
-			break loop
-		}
 	}
 	close(eng.write.buffers)
 	eng.conn.Close() // Make sure connection is closed
 	wait.Wait()
+	close(eng.running) // Signal goroutines have exited and Error is set.
+
 	connectionContexts.Delete(eng.connection)
 	if !eng.connection.IsNil() {
 		eng.connection.Free()
@@ -332,15 +336,10 @@ loop:
 			C.pn_handler_free(h.pn)
 		}
 	}
-	close(eng.running) // Signal goroutines have exited and Error is set.
 	return eng.err.Get()
 }
 
 func (eng *Engine) netError(err error) {
-	if err == nil {
-		err = internal.Errorf("unknown network error")
-	}
-	eng.conn.Close() // Make sure both sides are closed
 	eng.err.Set(err)
 	eng.transport.CloseHead()
 	eng.transport.CloseTail()
@@ -389,17 +388,13 @@ func (eng *Engine) handle(e Event) {
 		h.HandleEvent(e)
 	}
 	if e.Type() == ETransportClosed {
-		eng.err.Set(e.Connection().RemoteCondition().Error())
-		eng.err.Set(e.Connection().Transport().Condition().Error())
-		if eng.err.Get() == nil {
-			eng.err.Set(io.EOF)
-		}
+		eng.err.Set(io.EOF)
 	}
 }
 
 func (eng *Engine) process() {
 	for ce := C.pn_collector_peek(eng.collector); ce != nil; ce = C.pn_collector_peek(eng.collector) {
-		eng.handle(makeEvent(ce))
+		eng.handle(makeEvent(ce, eng))
 		C.pn_collector_pop(eng.collector)
 	}
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go b/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
index 8a5cbf8..53b744c 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/handlers.go
@@ -191,7 +191,7 @@ type endpointDelegator struct {
 	remoteOpen, remoteClose, localOpen, localClose EventType
 	opening, opened, closing, closed, error        MessagingEvent
 	endpoint                                       func(Event) Endpoint
-	delegator                                      *MessagingDelegator
+	delegator                                      *MessagingAdapter
 }
 
 // HandleEvent handles an open/close event for an endpoint in a generic way.
@@ -240,10 +240,10 @@ func (d endpointDelegator) HandleEvent(e Event) {
 	}
 }
 
-// MessagingDelegator implments a EventHandler and delegates to a MessagingHandler.
-// You can modify the exported fields before you pass the MessagingDelegator to
+// MessagingAdapter implments a EventHandler and delegates to a MessagingHandler.
+// You can modify the exported fields before you pass the MessagingAdapter to
 // a Engine.
-type MessagingDelegator struct {
+type MessagingAdapter struct {
 	mhandler                  MessagingHandler
 	connection, session, link endpointDelegator
 	flowcontroller            EventHandler
@@ -261,8 +261,8 @@ type MessagingDelegator struct {
 	PeerCloseError bool
 }
 
-func NewMessagingDelegator(h MessagingHandler) *MessagingDelegator {
-	return &MessagingDelegator{
+func NewMessagingAdapter(h MessagingHandler) *MessagingAdapter {
+	return &MessagingAdapter{
 		mhandler:       h,
 		flowcontroller: nil,
 		AutoSettle:     true,
@@ -281,7 +281,7 @@ func handleIf(h EventHandler, e Event) {
 
 // Handle a proton event by passing the corresponding MessagingEvent(s) to
 // the MessagingHandler.
-func (d *MessagingDelegator) HandleEvent(e Event) {
+func (d *MessagingAdapter) HandleEvent(e Event) {
 	handleIf(d.flowcontroller, e)
 
 	switch e.Type() {
@@ -352,7 +352,7 @@ func (d *MessagingDelegator) HandleEvent(e Event) {
 	}
 }
 
-func (d *MessagingDelegator) incoming(e Event) (err error) {
+func (d *MessagingAdapter) incoming(e Event) (err error) {
 	delivery := e.Delivery()
 	if delivery.HasMessage() {
 		d.mhandler.HandleMessagingEvent(MMessage, e)
@@ -368,7 +368,7 @@ func (d *MessagingDelegator) incoming(e Event) (err error) {
 	return
 }
 
-func (d *MessagingDelegator) outgoing(e Event) (err error) {
+func (d *MessagingAdapter) outgoing(e Event) (err error) {
 	delivery := e.Delivery()
 	if delivery.Updated() {
 		switch delivery.Remote().Type() {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
index 7d40890..45a6722 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
@@ -24,20 +24,20 @@ package proton
 
 //#include <proton/codec.h>
 //#include <proton/connection.h>
-//#include <proton/session.h>
-//#include <proton/session.h>
 //#include <proton/delivery.h>
-//#include <proton/link.h>
 //#include <proton/event.h>
-//#include <proton/transport.h>
 //#include <proton/link.h>
+//#include <proton/link.h>
+//#include <proton/object.h>
+//#include <proton/session.h>
+//#include <proton/transport.h>
 //#include <stdlib.h>
 import "C"
 
 import (
 	"fmt"
-	"qpid.apache.org/internal"
 	"qpid.apache.org/amqp"
+	"qpid.apache.org/internal"
 	"reflect"
 	"time"
 	"unsafe"
@@ -45,34 +45,75 @@ import (
 
 // TODO aconway 2015-05-05: Documentation for generated types.
 
+// CHandle holds an unsafe.Pointer to a proton C struct, the C type depends on the
+// Go type implementing this interface. For low level, at-your-own-risk use only.
+type CHandle interface {
+	// CPtr returns the unsafe C pointer, equivalent to a C void*.
+	CPtr() unsafe.Pointer
+}
+
+// Incref increases the refcount of a proton value, which prevents the
+// underlying C struct being freed until you call Decref().
+//
+// It can be useful to "pin" a proton value in memory while it is in use by
+// goroutines other than the event loop goroutine. For example if you Incref() a
+// Link, the underlying object is not freed when the link is closed, so means
+// other goroutines can continue to safely use it as an index in a map or inject
+// it into the event loop goroutine. There will of course be an error if you try
+// to use a link after it is closed, but not a segmentation fault.
+func Incref(c CHandle) {
+	if p := c.CPtr(); p != nil {
+		C.pn_incref(p)
+	}
+}
+
+// Decref decreases the refcount of a proton value, freeing the underlying C
+// struct if this is the last reference.  Only call this if you previously
+// called Incref() for this value.
+func Decref(c CHandle) {
+	if p := c.CPtr(); p != nil {
+		C.pn_decref(p)
+	}
+}
+
 // Event is an AMQP protocol event.
 type Event struct {
 	pn         *C.pn_event_t
 	eventType  EventType
 	connection Connection
+	transport  Transport
 	session    Session
 	link       Link
 	delivery   Delivery
+	injecter   Injecter
 }
 
-func makeEvent(pn *C.pn_event_t) Event {
+func makeEvent(pn *C.pn_event_t, injecter Injecter) Event {
 	return Event{
 		pn:         pn,
 		eventType:  EventType(C.pn_event_type(pn)),
 		connection: Connection{C.pn_event_connection(pn)},
+		transport:  Transport{C.pn_event_transport(pn)},
 		session:    Session{C.pn_event_session(pn)},
 		link:       Link{C.pn_event_link(pn)},
 		delivery:   Delivery{C.pn_event_delivery(pn)},
+		injecter:   injecter,
 	}
 }
 func (e Event) IsNil() bool            { return e.eventType == EventType(0) }
 func (e Event) Type() EventType        { return e.eventType }
 func (e Event) Connection() Connection { return e.connection }
+func (e Event) Transport() Transport   { return e.transport }
 func (e Event) Session() Session       { return e.session }
 func (e Event) Link() Link             { return e.link }
 func (e Event) Delivery() Delivery     { return e.delivery }
 func (e Event) String() string         { return e.Type().String() }
 
+// Injecter should not be used in a handler function, but it can be passed to
+// other goroutines (via a channel or to a goroutine started by handler
+// functions) to let them inject functions back into the handlers goroutine.
+func (e Event) Injecter() Injecter { return e.injecter }
+
 // Data holds a pointer to decoded AMQP data.
 // Use amqp.marshal/unmarshal to access it as Go data types.
 //
@@ -132,12 +173,14 @@ type Endpoint interface {
 	String() string
 }
 
-// CloseError sets an error condition on an endpoint and closes the endpoint.
+// CloseError sets an error condition on an endpoint and closes the endpoint (if not already closed)
 func CloseError(e Endpoint, err error) {
 	if err != nil {
 		e.Condition().SetError(err)
 	}
-	e.Close()
+	if e.State().RemoteActive() {
+		e.Close()
+	}
 }
 
 // EndpointError returns the remote error if there is one, the local error if not
@@ -204,6 +247,20 @@ func (l Link) Delivery(tag string) Delivery {
 	return Delivery{C.pn_delivery(l.pn, pnTag(tag))}
 }
 
+func (l Link) Connection() Connection { return l.Session().Connection() }
+
+// Human-readable link description including name, source, target and direction.
+func (l Link) String() string {
+	switch {
+	case l.IsNil():
+		return fmt.Sprintf("<nil-link>")
+	case l.IsSender():
+		return fmt.Sprintf("%s(%s->%s)", l.Name(), l.Source().Address(), l.Target().Address())
+	default:
+		return fmt.Sprintf("%s(%s<-%s)", l.Name(), l.Target().Address(), l.Source().Address())
+	}
+}
+
 func cPtr(b []byte) *C.char {
 	if len(b) == 0 {
 		return nil
@@ -229,20 +286,11 @@ func (s Session) Receiver(name string) Link {
 
 // Context information per connection.
 type connectionContext struct {
-	injecter Injecter
-	str      string
+	str string
 }
 
 var connectionContexts = internal.MakeSafeMap()
 
-// Injecter for event-loop associated with this connection.
-func (c Connection) Injecter() Injecter {
-	if cc, ok := connectionContexts.Get(c).(connectionContext); ok {
-		return cc.injecter
-	}
-	return nil
-}
-
 // Unique (per process) string identifier for a connection, useful for debugging.
 func (c Connection) String() string {
 	if cc, ok := connectionContexts.Get(c).(connectionContext); ok {
@@ -279,20 +327,6 @@ func (s Session) String() string {
 	return fmt.Sprintf("%s/%p", s.Connection(), s.pn)
 }
 
-func (l Link) Connection() Connection { return l.Session().Connection() }
-
-// Human-readable link description including name, source, target and direction.
-func (l Link) String() string {
-	switch {
-	case l.IsNil():
-		return fmt.Sprintf("<nil-link>")
-	case l.IsSender():
-		return fmt.Sprintf("%s(%s->%s)", l.Name(), l.Source().Address(), l.Target().Address())
-	default:
-		return fmt.Sprintf("%s(%s<-%s)", l.Name(), l.Target().Address(), l.Source().Address())
-	}
-}
-
 // Error returns an instance of amqp.Error or nil.
 func (c Condition) Error() error {
 	if c.IsNil() || !c.IsSet() {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bc0a242e/proton-j/src/main/java/org/apache/qpid/proton/amqp/messaging/Terminus.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/amqp/messaging/Terminus.java b/proton-j/src/main/java/org/apache/qpid/proton/amqp/messaging/Terminus.java
index ac28b32..ef09837 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/amqp/messaging/Terminus.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/amqp/messaging/Terminus.java
@@ -48,7 +48,7 @@ public abstract class Terminus
         _dynamic = other._dynamic;
         if (other._dynamicNodeProperties != null) {
             // TODO: Do we need to copy or can we make a simple reference?
-            _dynamicNodeProperties = new HashMap(other._dynamicNodeProperties); // FIXME
+            _dynamicNodeProperties = new HashMap(other._dynamicNodeProperties); // yFIXME
         }
         if (other._capabilities != null) {
             _capabilities = other._capabilities.clone(); // FIXME?


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


[25/50] [abbrv] qpid-proton git commit: NO-JIRA: Add cmake dependencies to go build, avoid cmake calling 'go build' if up to date.

Posted by ac...@apache.org.
NO-JIRA: Add cmake dependencies to go build, avoid cmake calling 'go build' if up to date.


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

Branch: refs/heads/go1
Commit: d3c53d8cefec7896c9dc2056ac1db9a0da452a10
Parents: f7a4cb3
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Oct 14 13:54:51 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Oct 14 17:41:47 2015 -0400

----------------------------------------------------------------------
 appveyor.yml                                    |  1 -
 examples/go/CMakeLists.txt                      | 37 +++++++-----
 examples/go/example_test.go                     |  1 -
 proton-c/bindings/go/CMakeLists.txt             | 61 +++++++++++++++-----
 .../src/qpid.apache.org/electron/connection.go  |  3 +-
 .../go/src/qpid.apache.org/electron/handler.go  |  6 +-
 .../qpid.apache.org/electron/messaging_test.go  |  2 +-
 .../src/qpid.apache.org/proton/proton_test.go   | 27 +++++++++
 proton-c/include/proton/types.h                 |  1 +
 9 files changed, 100 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/appveyor.yml
----------------------------------------------------------------------
diff --git a/appveyor.yml b/appveyor.yml
index 9729c57..a147e0d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,7 +2,6 @@ version: 0.10-SNAPSHOT-{branch}.{build}
 configuration: RelWithDebInfo
 install:
 - cinst -y swig
-- cinst -y mingw
 before_build:
 - mkdir BLD
 - cd BLD

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 67c6cd7..2a36ec8 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -18,26 +18,37 @@
 #
 
 if(BUILD_GO)
-  set(examples electron/receive electron/send electron/broker proton/broker)
 
+  set(examples electron/broker electron/receive electron/send proton/broker)
+
+  # Build example exes
   foreach(example ${examples})
-    string(REPLACE / - target ${example})
-    add_custom_target(go-example-${target} ALL
-      COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${CMAKE_CURRENT_BINARY_DIR}/${example} ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go
-      DEPENDS go-packages qpid-proton)
+    set(source ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go)
+    set(target ${CMAKE_CURRENT_BINARY_DIR}/${example})
+    add_custom_command(
+      OUTPUT ${target}
+      COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${target} ${source}
+      DEPENDS  ${source} ${GO_TARGETS})
+    list(APPEND example_exes ${target})
   endforeach()
-  add_custom_target(go-example-test ALL
-      COMMAND ${GO_TEST} -c ${GO_EXAMPLE_FLAGS} -o ${CMAKE_CURRENT_BINARY_DIR}/example_test ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go
-      DEPENDS go-packages qpid-proton)
 
-  add_test(
-    NAME go_example_electron_test
-    COMMAND ${GO_ENV} ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
+  # Build test driver exe
+  set(test_exe ${CMAKE_CURRENT_BINARY_DIR}/example_test)
+  add_custom_command(
+    OUTPUT ${test_exe}
+    DEPENDS ${example_exes}
+    COMMAND ${GO_TEST} -c -o ${test_exe} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.go)
 
+  add_custom_target(go-test-exe ALL DEPENDS ${test_exe})
 
   add_test(
-    NAME go_example_proton_test
-    COMMAND ${GO_ENV} ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
+    NAME go_example_electron_test
+    COMMAND ${GO_ENV} ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
+
+  # FIXME aconway 2015-10-14: proton broker is buggy, enable when fixed.
+  # add_test(
+  #   NAME go_example_proton_test
+  #   COMMAND ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
index 479864c..1e497b9 100644
--- a/examples/go/example_test.go
+++ b/examples/go/example_test.go
@@ -113,7 +113,6 @@ func checkStaleLibs(t *testing.T) {
 	var stale []string
 	pp := "qpid.apache.org"
 	for _, p := range []string{pp + "/proton", pp + "/amqp", pp + "/electron"} {
-		t.Log("FIXME", os.Getenv("GOPATH"))
 		out, err := exec.Command("go", "list", "-f", "{{.Stale}}", p).CombinedOutput()
 		if err != nil {
 			t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 27d2349..e791555 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -18,18 +18,17 @@
 #
 
 # Go version
-execute_process(COMMAND ${GO_EXE} version OUTPUT_VARIABLE go_out)
-message(STATUS "Found Go: ${go_out}")
+execute_process(COMMAND ${GO_EXE} version OUTPUT_VARIABLE go_ver OUTPUT_STRIP_TRAILING_WHITESPACE)
+message(STATUS "Found Go: ${GO_EXE} (${go_ver})")
 
 set(GO_BUILD_FLAGS "" CACHE STRING "Flags for 'go build'")
+set(GO_TEST_FLAGS "-v" CACHE STRING "Flags for 'go test'")
 
 # Flags that differ for golang go and gcc go.
 if (go_out MATCHES "gccgo")
   # TODO aconway 2015-10-08: import cycles with -race under gccgo, investigate.
-  set(GO_TEST_FLAGS "-v" CACHE STRING "Flags for 'go test'")
   set(GO_RPATH_FLAGS -gccgoflags "-Wl,-rpath=${CMAKE_BINARY_DIR}/proton-c")
 else()
-  set(GO_TEST_FLAGS "-v -race" CACHE STRING "Flags for 'go test'")
   set(GO_RPATH_FLAGS -ldflags "-r ${CMAKE_BINARY_DIR}/proton-c")
 endif()
 
@@ -49,24 +48,54 @@ set(GO_BUILD ${GO} build ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} CACHE INTERNAL "Run
 set(GO_INSTALL ${GO} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
 set(GO_TEST ${GO} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
 
-# Install packages in the source tree, go tools aren't friendly otherwise.
-# All build output goes in git-ignored pkg or bin subdirectories.
-set(q "qpid.apache.org")
-set(packages ${q}/amqp ${q}/internal ${q}/proton ${q}/electron)
-add_custom_target(go-packages ALL
-  COMMAND ${GO_INSTALL} ${packages}
-  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-  DEPENDS qpid-proton)
+# Go build depends on the C headers
+file(GLOB headers ${CMAKE_SOURCE_DIR}/proton_c/include/proton/*.h)
 
-add_test(
-  NAME go_test_packages
-  COMMAND ${GO_TEST} ${packages}
-  WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
+# Go tools insist on standard Go layout which puts compiled code in the source tree :(
+# Build output is all under git-ignored pkg or bin subdirectories, they are removed by make clean.
+foreach (pkg amqp proton electron)
 
+  set(package "qpid.apache.org/${pkg}")
+
+  # Get the target library location
+  macro(go_list var template)
+    execute_process(COMMAND ${GO} list -f "${template}" ${package}
+      OUTPUT_VARIABLE ${var} OUTPUT_STRIP_TRAILING_WHITESPACE)
+  endmacro()
+  go_list(lib  "{{.Target}}")
+
+  # Get package sources
+  go_list(dir "{{.Dir}}")
+  macro(go_sources field)
+    go_list(${field} "{{range .${field}}}${dir}/{{.}};{{end}}")
+  endmacro()
+  go_sources(GoFiles)
+  go_sources(CgoFiles)
+  set(sources "${GoFiles}${CgoFiles}")
+
+  # Build the package library
+  add_custom_command(OUTPUT ${lib} COMMAND ${GO_INSTALL} ${package} DEPENDS ${sources} ${headers})
+  set(target go-package-${pkg})
+  add_custom_target(${target} ALL DEPENDS ${lib})
+
+  # Package test
+  go_sources(TestGoFiles)
+  set(test_exe ${CMAKE_CURRENT_BINARY_DIR}/${pkg}.test)
+  add_custom_command(OUTPUT ${test_exe} COMMAND ${GO_TEST} -c -o ${test_exe} ${package}
+    DEPENDS ${target} qpid-proton)
+  add_custom_target(go-package-test-${pkg} ALL DEPENDS ${test_exe})
+  add_test(NAME go_test_${pkg} COMMAND ${test_exe} WORKING_DIRECTORY ${dir})
+
+  list(APPEND GO_TARGETS ${target})
+
+endforeach()
+
+# Clean up go output directories.
 list(APPEND ADDITIONAL_MAKE_CLEAN_FILES
   ${CMAKE_CURRENT_SOURCE_DIR}/pkg
   ${CMAKE_CURRENT_SOURCE_DIR}/bin)
 
+# Install go sources.
 set (GO_INSTALL_DIR ${SHARE_INSTALL_DIR}/gocode/src CACHE PATH "Installation directory for Go code")
 mark_as_advanced (GO_INSTALL_DIR)
 install(DIRECTORY src/qpid.apache.org DESTINATION ${GO_INSTALL_DIR} COMPONENT Go)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
index 7c8024b..bef8c17 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
@@ -24,9 +24,9 @@ import "C"
 
 import (
 	"net"
+	"qpid.apache.org/amqp"
 	"qpid.apache.org/internal"
 	"qpid.apache.org/proton"
-	"qpid.apache.org/amqp"
 	"sync"
 )
 
@@ -140,7 +140,6 @@ func (c *connection) Close(err error) { c.engine.Close(err) }
 
 func (c *connection) Disconnect(err error) { c.engine.Disconnect(err) }
 
-// FIXME aconway 2015-10-07:
 func (c *connection) closed(err error) {
 	// Call from another goroutine to initiate close without deadlock.
 	go c.Close(err)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
index f6065a1..1b07109 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
@@ -17,15 +17,11 @@ specific language governing permissions and limitations
 under the License.
 */
 
-// FIXME aconway 2015-10-07: move to amqp or split into sub packages?
-// proton.core
-// proton.msg
-
 package electron
 
 import (
-	"qpid.apache.org/proton"
 	"qpid.apache.org/amqp"
+	"qpid.apache.org/proton"
 )
 
 // NOTE: methods in this file are called only in the proton goroutine unless otherwise indicated.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
index 3b315cd..36b0c24 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
@@ -30,7 +30,7 @@ import (
 )
 
 func fatalIf(t *testing.T, err error) {
-	if err != nil { // FIXME aconway 2015-10-07:
+	if err != nil {
 		_, file, line, ok := runtime.Caller(1) // annotate with location of caller.
 		if ok {
 			_, file = path.Split(file)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/bindings/go/src/qpid.apache.org/proton/proton_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/proton_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/proton_test.go
new file mode 100644
index 0000000..bb3f21c
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/proton_test.go
@@ -0,0 +1,27 @@
+/*
+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
+
+import (
+	"testing"
+)
+
+// TODO aconway 2015-10-14: placeholder, add unit tests.
+func Test(*testing.T) {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d3c53d8c/proton-c/include/proton/types.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/types.h b/proton-c/include/proton/types.h
index 10799ff..4b7c953 100644
--- a/proton-c/include/proton/types.h
+++ b/proton-c/include/proton/types.h
@@ -1,6 +1,7 @@
 #ifndef PROTON_TYPES_H
 #define PROTON_TYPES_H 1
 
+
 /*
  *
  * Licensed to the Apache Software Foundation (ASF) under one


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


[38/50] [abbrv] qpid-proton git commit: NO-JIRA: Remove cmake FIXME message left in by mistake.

Posted by ac...@apache.org.
NO-JIRA: Remove cmake FIXME message left in by mistake.


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

Branch: refs/heads/go1
Commit: 6192c5544ffc7d736cd073fb17a3549d44e39ef8
Parents: cf221b4
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 20 17:01:41 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 20 17:01:41 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6192c554/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index bcfff1a..3235880 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -25,7 +25,6 @@ if(BUILD_GO)
   foreach(example ${examples})
     set(source ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go)
     set(target ${CMAKE_CURRENT_BINARY_DIR}/${example})
-    message("FIXME ${source} ${GO_TARGETS}")
     add_custom_command(
       OUTPUT ${target}
       COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${target} ${source}
@@ -46,10 +45,9 @@ if(BUILD_GO)
     NAME go_example_electron_test
     COMMAND ${GO_ENV} ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
 
-  # FIXME aconway 2015-10-14: proton broker is buggy, enable when fixed.
-  # add_test(
-  #   NAME go_example_proton_test
-  #   COMMAND ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
+  add_test(
+    NAME go_example_proton_test
+    COMMAND ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()


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


[07/50] [abbrv] qpid-proton git commit: PROTON-1011: Go example of event driven broker. Package renaming and some new features.

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/unmarshal.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/unmarshal.go
deleted file mode 100644
index d645273..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/unmarshal.go
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-oor 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
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"qpid.apache.org/proton/internal"
-	"reflect"
-	"unsafe"
-)
-
-const minDecode = 1024
-
-// Error returned if AMQP data cannot be unmarshaled as the desired Go type.
-type UnmarshalError struct {
-	// The name of the AMQP type.
-	AMQPType string
-	// The Go type.
-	GoType reflect.Type
-}
-
-func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError {
-	return &UnmarshalError{Type(pnType).String(), reflect.TypeOf(v)}
-}
-
-func (e UnmarshalError) Error() string {
-	if e.GoType.Kind() != reflect.Ptr {
-		return fmt.Sprintf("proton: cannot unmarshal to type %s, not a pointer", e.GoType)
-	} else {
-		return fmt.Sprintf("proton: cannot unmarshal AMQP %s to %s", e.AMQPType, e.GoType)
-	}
-}
-
-func doRecover(err *error) {
-	r := recover()
-	switch r := r.(type) {
-	case nil:
-	case *UnmarshalError, internal.Error:
-		*err = r.(error)
-	default:
-		panic(r)
-	}
-}
-
-//
-// Decoding from a pn_data_t
-//
-// NOTE: we use panic() to signal a decoding error, simplifies decoding logic.
-// We recover() at the highest possible level - i.e. in the exported Unmarshal or Decode.
-//
-
-// Decoder decodes AMQP values from an io.Reader.
-//
-type Decoder struct {
-	reader io.Reader
-	buffer bytes.Buffer
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder has it's own buffer and may read more data than required for the
-// AMQP values requested.  Use Buffered to see if there is data left in the
-// buffer.
-//
-func NewDecoder(r io.Reader) *Decoder {
-	return &Decoder{r, bytes.Buffer{}}
-}
-
-// Buffered returns a reader of the data remaining in the Decoder's buffer. The
-// reader is valid until the next call to Decode.
-//
-func (d *Decoder) Buffered() io.Reader {
-	return bytes.NewReader(d.buffer.Bytes())
-}
-
-// Decode reads the next AMQP value from the Reader and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
-//
-func (d *Decoder) Decode(v interface{}) (err error) {
-	defer doRecover(&err)
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	var n int
-	for n == 0 && err == nil {
-		n = decode(data, d.buffer.Bytes())
-		if n == 0 { // n == 0 means not enough data, read more
-			err = d.more()
-		} else {
-			unmarshal(v, data)
-		}
-	}
-	d.buffer.Next(n)
-	return
-}
-
-/*
-Unmarshal decodes AMQP-encoded bytes and stores the result in the value pointed to by v.
-Types are converted as follows:
-
- +---------------------------+----------------------------------------------------------------------+
- |To Go types                |From AMQP types                                                       |
- +===========================+======================================================================+
- |bool                       |bool                                                                  |
- +---------------------------+----------------------------------------------------------------------+
- |int, int8, int16,          |Equivalent or smaller signed integer type: byte, short, int, long.    |
- |int32, int64               |                                                                      |
- +---------------------------+----------------------------------------------------------------------+
- |uint, uint8, uint16,       |Equivalent or smaller unsigned integer type: ubyte, ushort, uint,     |
- |uint32, uint64 types       |ulong                                                                 |
- +---------------------------+----------------------------------------------------------------------+
- |float32, float64           |Equivalent or smaller float or double.                                |
- +---------------------------+----------------------------------------------------------------------+
- |string, []byte             |string, symbol or binary.                                             |
- +---------------------------+----------------------------------------------------------------------+
- |Symbol                     |symbol                                                                |
- +---------------------------+----------------------------------------------------------------------+
- |map[K]T                    |map, provided all keys and values can unmarshal to types K, T         |
- +---------------------------+----------------------------------------------------------------------+
- |Map                        |map, any AMQP map                                                     |
- +---------------------------+----------------------------------------------------------------------+
- |interface{}                |Any AMQP value can be unmarshaled to an interface{} as follows:       |
- |                           +------------------------+---------------------------------------------+
- |                           |AMQP Type               |Go Type in interface{}                       |
- |                           +========================+=============================================+
- |                           |bool                    |bool                                         |
- |                           +------------------------+---------------------------------------------+
- |                           |byte,short,int,long     |int8,int16,int32,int64                       |
- |                           +------------------------+---------------------------------------------+
- |                           |ubyte,ushort,uint,ulong |uint8,uint16,uint32,uint64                   |
- |                           +------------------------+---------------------------------------------+
- |                           |float, double           |float32, float64                             |
- |                           +------------------------+---------------------------------------------+
- |                           |string                  |string                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |symbol                  |Symbol                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |binary                  |Binary                                       |
- |                           +------------------------+---------------------------------------------+
- |                           |nulll                   |nil                                          |
- |                           +------------------------+---------------------------------------------+
- |                           |map                     |Map                                          |
- |                           +------------------------+---------------------------------------------+
- |                           |list                    |List                                         |
- +---------------------------+------------------------+---------------------------------------------+
-
-The following Go types cannot be unmarshaled: uintptr, function, interface, channel.
-
-TODO
-
-Go types: array, struct.
-
-AMQP types: decimal32/64/128, char (round trip), timestamp, uuid, array, multi-section message bodies.
-
-AMQP maps with mixed/unhashable key types need an alternate representation.
-
-Described types.
-*/
-func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
-	defer doRecover(&err)
-
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	n = decode(data, bytes)
-	if n == 0 {
-		err = internal.Errorf("not enough data")
-	} else {
-		unmarshal(v, data)
-	}
-	return
-}
-
-// more reads more data when we can't parse a complete AMQP type
-func (d *Decoder) more() error {
-	var readSize int64 = minDecode
-	if int64(d.buffer.Len()) > readSize { // Grow by doubling
-		readSize = int64(d.buffer.Len())
-	}
-	var n int64
-	n, err := d.buffer.ReadFrom(io.LimitReader(d.reader, readSize))
-	if n == 0 && err == nil { // ReadFrom won't report io.EOF, just returns 0
-		err = io.EOF
-	}
-	return err
-}
-
-// Unmarshal from data into value pointed at by v.
-func unmarshal(v interface{}, data *C.pn_data_t) {
-	pnType := C.pn_data_type(data)
-	switch v := v.(type) {
-	case *bool:
-		switch pnType {
-		case C.PN_BOOL:
-			*v = bool(C.pn_data_get_bool(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *int8:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int8(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int8(C.pn_data_get_byte(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *uint8:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint8(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint8(C.pn_data_get_ubyte(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *int16:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int16(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int16(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int16(C.pn_data_get_short(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *uint16:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint16(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint16(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint16(C.pn_data_get_ushort(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *int32:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int32(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int32(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int32(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int32(C.pn_data_get_int(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	case *uint32:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint32(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint32(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint32(C.pn_data_get_ushort(data))
-		case C.PN_UINT:
-			*v = uint32(C.pn_data_get_uint(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *int64:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int64(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int64(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int64(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int64(C.pn_data_get_int(data))
-		case C.PN_LONG:
-			*v = int64(C.pn_data_get_long(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *uint64:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint64(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint64(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint64(C.pn_data_get_ushort(data))
-		case C.PN_ULONG:
-			*v = uint64(C.pn_data_get_ulong(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *int:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = int(C.pn_data_get_char(data))
-		case C.PN_BYTE:
-			*v = int(C.pn_data_get_byte(data))
-		case C.PN_SHORT:
-			*v = int(C.pn_data_get_short(data))
-		case C.PN_INT:
-			*v = int(C.pn_data_get_int(data))
-		case C.PN_LONG:
-			if unsafe.Sizeof(0) == 8 {
-				*v = int(C.pn_data_get_long(data))
-			} else {
-				panic(newUnmarshalError(pnType, v))
-			}
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *uint:
-		switch pnType {
-		case C.PN_CHAR:
-			*v = uint(C.pn_data_get_char(data))
-		case C.PN_UBYTE:
-			*v = uint(C.pn_data_get_ubyte(data))
-		case C.PN_USHORT:
-			*v = uint(C.pn_data_get_ushort(data))
-		case C.PN_UINT:
-			*v = uint(C.pn_data_get_uint(data))
-		case C.PN_ULONG:
-			if unsafe.Sizeof(0) == 8 {
-				*v = uint(C.pn_data_get_ulong(data))
-			} else {
-				panic(newUnmarshalError(pnType, v))
-			}
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *float32:
-		switch pnType {
-		case C.PN_FLOAT:
-			*v = float32(C.pn_data_get_float(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *float64:
-		switch pnType {
-		case C.PN_FLOAT:
-			*v = float64(C.pn_data_get_float(data))
-		case C.PN_DOUBLE:
-			*v = float64(C.pn_data_get_double(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *string:
-		switch pnType {
-		case C.PN_STRING:
-			*v = goString(C.pn_data_get_string(data))
-		case C.PN_SYMBOL:
-			*v = goString(C.pn_data_get_symbol(data))
-		case C.PN_BINARY:
-			*v = goString(C.pn_data_get_binary(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *[]byte:
-		switch pnType {
-		case C.PN_STRING:
-			*v = goBytes(C.pn_data_get_string(data))
-		case C.PN_SYMBOL:
-			*v = goBytes(C.pn_data_get_symbol(data))
-		case C.PN_BINARY:
-			*v = goBytes(C.pn_data_get_binary(data))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *Binary:
-		switch pnType {
-		case C.PN_BINARY:
-			*v = Binary(goBytes(C.pn_data_get_binary(data)))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *Symbol:
-		switch pnType {
-		case C.PN_SYMBOL:
-			*v = Symbol(goBytes(C.pn_data_get_symbol(data)))
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-
-	case *interface{}:
-		getInterface(data, v)
-
-	default:
-		if reflect.TypeOf(v).Kind() != reflect.Ptr {
-			panic(newUnmarshalError(pnType, v))
-		}
-		switch reflect.TypeOf(v).Elem().Kind() {
-		case reflect.Map:
-			getMap(data, v)
-		case reflect.Slice:
-			getList(data, v)
-		default:
-			panic(newUnmarshalError(pnType, v))
-		}
-	}
-	err := dataError("unmarshaling", data)
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func rewindUnmarshal(v interface{}, data *C.pn_data_t) {
-	C.pn_data_rewind(data)
-	C.pn_data_next(data)
-	unmarshal(v, data)
-}
-
-// Getting into an interface is driven completely by the AMQP type, since the interface{}
-// target is type-neutral.
-func getInterface(data *C.pn_data_t, v *interface{}) {
-	pnType := C.pn_data_type(data)
-	switch pnType {
-	case C.PN_NULL, C.PN_INVALID: // No data.
-		*v = nil
-	case C.PN_BOOL:
-		*v = bool(C.pn_data_get_bool(data))
-	case C.PN_UBYTE:
-		*v = uint8(C.pn_data_get_ubyte(data))
-	case C.PN_BYTE:
-		*v = int8(C.pn_data_get_byte(data))
-	case C.PN_USHORT:
-		*v = uint16(C.pn_data_get_ushort(data))
-	case C.PN_SHORT:
-		*v = int16(C.pn_data_get_short(data))
-	case C.PN_UINT:
-		*v = uint32(C.pn_data_get_uint(data))
-	case C.PN_INT:
-		*v = int32(C.pn_data_get_int(data))
-	case C.PN_CHAR:
-		*v = uint8(C.pn_data_get_char(data))
-	case C.PN_ULONG:
-		*v = uint64(C.pn_data_get_ulong(data))
-	case C.PN_LONG:
-		*v = int64(C.pn_data_get_long(data))
-	case C.PN_FLOAT:
-		*v = float32(C.pn_data_get_float(data))
-	case C.PN_DOUBLE:
-		*v = float64(C.pn_data_get_double(data))
-	case C.PN_BINARY:
-		*v = Binary(goBytes(C.pn_data_get_binary(data)))
-	case C.PN_STRING:
-		*v = goString(C.pn_data_get_string(data))
-	case C.PN_SYMBOL:
-		*v = Symbol(goString(C.pn_data_get_symbol(data)))
-	case C.PN_MAP:
-		m := make(Map)
-		unmarshal(&m, data)
-		*v = m
-	case C.PN_LIST:
-		l := make(List, 0)
-		unmarshal(&l, data)
-		*v = l
-	default:
-		panic(newUnmarshalError(pnType, v))
-	}
-}
-
-// get into map pointed at by v
-func getMap(data *C.pn_data_t, v interface{}) {
-	mapValue := reflect.ValueOf(v).Elem()
-	mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map
-	switch pnType := C.pn_data_type(data); pnType {
-	case C.PN_MAP:
-		count := int(C.pn_data_get_map(data))
-		if bool(C.pn_data_enter(data)) {
-			defer C.pn_data_exit(data)
-			for i := 0; i < count/2; i++ {
-				if bool(C.pn_data_next(data)) {
-					key := reflect.New(mapValue.Type().Key())
-					unmarshal(key.Interface(), data)
-					if bool(C.pn_data_next(data)) {
-						val := reflect.New(mapValue.Type().Elem())
-						unmarshal(val.Interface(), data)
-						mapValue.SetMapIndex(key.Elem(), val.Elem())
-					}
-				}
-			}
-		}
-	case C.PN_INVALID: // Leave the map empty
-	default:
-		panic(newUnmarshalError(pnType, v))
-	}
-}
-
-func getList(data *C.pn_data_t, v interface{}) {
-	pnType := C.pn_data_type(data)
-	if pnType != C.PN_LIST {
-		panic(newUnmarshalError(pnType, v))
-	}
-	count := int(C.pn_data_get_list(data))
-	listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count)
-	if bool(C.pn_data_enter(data)) {
-		for i := 0; i < count; i++ {
-			if bool(C.pn_data_next(data)) {
-				val := reflect.New(listValue.Type().Elem())
-				unmarshal(val.Interface(), data)
-				listValue.Index(i).Set(val.Elem())
-			}
-		}
-		C.pn_data_exit(data)
-	}
-	reflect.ValueOf(v).Elem().Set(listValue)
-}
-
-// decode from bytes.
-// Return bytes decoded or 0 if we could not decode a complete object.
-//
-func decode(data *C.pn_data_t, bytes []byte) int {
-	if len(bytes) == 0 {
-		return 0
-	}
-	n := int(C.pn_data_decode(data, cPtr(bytes), cLen(bytes)))
-	if n == int(C.PN_UNDERFLOW) {
-		C.pn_error_clear(C.pn_data_error(data))
-		return 0
-	} else if n <= 0 {
-		panic(internal.Errorf("unmarshal %s", internal.PnErrorCode(n)))
-	}
-	return n
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url.go
deleted file mode 100644
index 7a4ef13..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url.go
+++ /dev/null
@@ -1,96 +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.
-*/
-
-package amqp
-
-/*
-#include <stdlib.h>
-#include <string.h>
-#include <proton/url.h>
-
-// Helper function for setting URL fields.
-typedef void (*setter_fn)(pn_url_t* url, const char* value);
-inline void	set(pn_url_t *url, setter_fn s, const char* value) {
-  s(url, value);
-}
-*/
-import "C"
-
-import (
-	"net"
-	"net/url"
-	"qpid.apache.org/proton/internal"
-	"unsafe"
-)
-
-const (
-	amqp  string = "amqp"
-	amqps        = "amqps"
-)
-
-// ParseUrl parses an AMQP URL string and returns a net/url.Url.
-//
-// It is more forgiving than net/url.Parse and allows most of the parts of the
-// URL to be missing, assuming AMQP defaults.
-//
-func ParseURL(s string) (u *url.URL, err error) {
-	cstr := C.CString(s)
-	defer C.free(unsafe.Pointer(cstr))
-	pnUrl := C.pn_url_parse(cstr)
-	if pnUrl == nil {
-		return nil, internal.Errorf("bad URL %#v", s)
-	}
-	defer C.pn_url_free(pnUrl)
-
-	scheme := C.GoString(C.pn_url_get_scheme(pnUrl))
-	username := C.GoString(C.pn_url_get_username(pnUrl))
-	password := C.GoString(C.pn_url_get_password(pnUrl))
-	host := C.GoString(C.pn_url_get_host(pnUrl))
-	port := C.GoString(C.pn_url_get_port(pnUrl))
-	path := C.GoString(C.pn_url_get_path(pnUrl))
-
-	if err != nil {
-		return nil, internal.Errorf("bad URL %#v: %s", s, err)
-	}
-	if scheme == "" {
-		scheme = amqp
-	}
-	if port == "" {
-		if scheme == amqps {
-			port = amqps
-		} else {
-			port = amqp
-		}
-	}
-	var user *url.Userinfo
-	if password != "" {
-		user = url.UserPassword(username, password)
-	} else if username != "" {
-		user = url.User(username)
-	}
-
-	u = &url.URL{
-		Scheme: scheme,
-		User:   user,
-		Host:   net.JoinHostPort(host, port),
-		Path:   path,
-	}
-
-	return u, nil
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url_test.go
deleted file mode 100644
index f80f1c4..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/url_test.go
+++ /dev/null
@@ -1,51 +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.
-*/
-
-package amqp
-
-import (
-	"fmt"
-)
-
-func ExampleParseURL() {
-	for _, s := range []string{
-		"amqp://username:password@host:1234/path",
-		"host:1234",
-		"host",
-		":1234",
-		"host/path",
-		"amqps://host",
-		"",
-	} {
-		u, err := ParseURL(s)
-		if err != nil {
-			fmt.Println(err)
-		} else {
-			fmt.Println(u)
-		}
-	}
-	// Output:
-	// amqp://username:password@host:1234/path
-	// amqp://host:1234
-	// amqp://host:amqp
-	// amqp://:1234
-	// amqp://host:amqp/path
-	// amqps://host:amqps
-	// proton: bad URL ""
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
deleted file mode 100644
index 63fd3fc..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
+++ /dev/null
@@ -1,213 +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.
-*/
-
-package concurrent
-
-// #include <proton/disposition.h>
-import "C"
-
-import (
-	"net"
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/internal"
-	"sync"
-)
-
-// Connection is an AMQP connection, created by a Container.
-type Connection interface {
-	Endpoint
-
-	// Sender opens a new sender on the DefaultSession.
-	//
-	// v can be a string, which is used as the Target address, or a SenderSettings
-	// struct containing more details settings.
-	Sender(v interface{}) (Sender, error)
-
-	// Receiver opens a new Receiver on the DefaultSession().
-	//
-	// v can be a string, which is used as the
-	// Source address, or a ReceiverSettings struct containing more details
-	// settings.
-	Receiver(v interface{}) (Receiver, error)
-
-	// Server puts the connection in server mode, must be called before Open().
-	//
-	// A server connection will do protocol negotiation to accept a incoming AMQP
-	// connection. Normally you would call this for a connection accepted by
-	// net.Listener.Accept()
-	//
-	Server()
-
-	// Listen enables endpoints opened by the remote peer to be accepted by calling Accept().
-	// Must be called before Open().
-	Listen()
-
-	// DefaultSession() returns a default session for the connection. It is opened
-	// on the first call to DefaultSession and returned on subsequent calls.
-	DefaultSession() (Session, error)
-
-	// Session opens a new session.
-	Session() (Session, error)
-
-	// Accept returns the next Endpoint (Session, Sender or Receiver) opened by
-	// the remote peer. It returns (nil, error) if the connection closes.
-	//
-	// You must call Endpoint.Open() to complete opening the returned Endpoint or
-	// Endpoint.Close(error) to reject it. You can set endpoint properties before
-	// calling Open()
-	//
-	// You can use a type switch or type conversion to test which kind of Endpoint
-	// has been returned.
-	//
-	// You must call Connection.Listen() before Connection.Open() to enable Accept.
-	//
-	// The connection buffers endpoints until you call Accept() so normally you
-	// should have a dedicated goroutine calling Accept() in a loop to process it
-	// rapidly.
-	//
-	Accept() (Endpoint, error)
-
-	// Container for the connection.
-	Container() Container
-
-	// Disconnect the connection abruptly with an error.
-	Disconnect(error)
-}
-
-type connection struct {
-	endpoint
-	listenOnce, defaultSessionOnce sync.Once
-
-	// Set before Open()
-	container *container
-	conn      net.Conn
-	incoming  *internal.FlexChannel
-
-	// Set by Open()
-	handler     *handler
-	engine      *proton.Engine
-	err         internal.FirstError
-	eConnection proton.Connection
-
-	defaultSession Session
-}
-
-func newConnection(conn net.Conn, cont *container) (*connection, error) {
-	c := &connection{container: cont, conn: conn}
-	c.handler = newHandler(c)
-	var err error
-	c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
-	if err != nil {
-		return nil, err
-	}
-	c.str = c.engine.String()
-	c.eConnection = c.engine.Connection()
-	return c, nil
-}
-
-func (c *connection) Server() { c.engine.Server() }
-
-func (c *connection) Listen() {
-	c.listenOnce.Do(func() { c.incoming = internal.NewFlexChannel(-1) })
-}
-
-func (c *connection) Open() error {
-	go c.engine.Run()
-	return nil
-}
-
-func (c *connection) Close(err error) {
-	c.engine.Close(err)
-	c.setError(c.engine.Error()) // Will be io.EOF on close OK
-	if c.incoming != nil {
-		close(c.incoming.In)
-	}
-}
-
-func (c *connection) Disconnect(err error) {
-	c.engine.Disconnect(err)
-	if c.incoming != nil {
-		close(c.incoming.In)
-	}
-}
-
-func (c *connection) closed(err error) {
-	// Call from another goroutine to initiate close without deadlock.
-	go c.Close(err)
-}
-
-func (c *connection) Session() (Session, error) {
-	var s Session
-	err := c.engine.InjectWait(func() error {
-		eSession, err := c.engine.Connection().Session()
-		if err == nil {
-			eSession.Open()
-			if err == nil {
-				s = newSession(c, eSession)
-			}
-		}
-		return err
-	})
-	return s, err
-}
-
-func (c *connection) handleIncoming(sn *session, l proton.Link) {
-	if l.IsReceiver() {
-		c.incoming.In <- newReceiver(makeIncomingLink(sn, l))
-	} else {
-		c.incoming.In <- newSender(makeIncomingLink(sn, l))
-	}
-}
-
-func (c *connection) Accept() (Endpoint, error) {
-	v, ok := <-c.incoming.Out
-	if !ok {
-		return nil, c.Error()
-	} else {
-		return v.(Endpoint), nil
-	}
-}
-
-func (c *connection) Container() Container { return c.container }
-
-func (c *connection) DefaultSession() (s Session, err error) {
-	c.defaultSessionOnce.Do(func() {
-		c.defaultSession, err = c.Session()
-	})
-	if err == nil {
-		err = c.Error()
-	}
-	return c.defaultSession, err
-}
-
-func (c *connection) Sender(v interface{}) (Sender, error) {
-	if s, err := c.DefaultSession(); err == nil {
-		return s.Sender(v)
-	} else {
-		return nil, err
-	}
-}
-
-func (c *connection) Receiver(v interface{}) (Receiver, error) {
-	if s, err := c.DefaultSession(); err == nil {
-		return s.Receiver(v)
-	} else {
-		return nil, err
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
deleted file mode 100644
index 5edecfc..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
+++ /dev/null
@@ -1,71 +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.
-*/
-
-package concurrent
-
-import (
-	"net"
-	"qpid.apache.org/proton/internal"
-)
-
-// Container is an AMQP container, it represents a single AMQP "application".It
-// provides functions to create new Connections to remote containers.
-//
-// Create with NewContainer()
-//
-type Container interface {
-	// Id is a unique identifier for the container in your distributed application.
-	Id() string
-
-	// Create a new AMQP Connection over the supplied net.Conn connection.
-	//
-	// You must call Connection.Open() on the returned Connection, after
-	// setting any Connection properties you need to set. Note the net.Conn
-	// can be an outgoing connection (e.g. made with net.Dial) or an incoming
-	// connection (e.g. made with net.Listener.Accept())
-	Connection(conn net.Conn) (Connection, error)
-}
-
-type container struct {
-	id        string
-	linkNames internal.IdCounter
-}
-
-// NewContainer creates a new container. The id must be unique in your
-// distributed application, all connections created by the container
-// will have this container-id.
-//
-// If id == "" a random UUID will be generated for the id.
-func NewContainer(id string) Container {
-	if id == "" {
-		id = internal.UUID4().String()
-	}
-	cont := &container{id: id}
-	return cont
-}
-
-func (cont *container) Id() string { return cont.id }
-
-func (cont *container) nextLinkName() string {
-	return cont.id + "@" + cont.linkNames.Next()
-}
-
-func (cont *container) Connection(conn net.Conn) (Connection, error) {
-	return newConnection(conn, cont)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
deleted file mode 100644
index 810a5da..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
+++ /dev/null
@@ -1,46 +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.
-*/
-
-/*
-
-Package concurrent provides a procedural, concurrent Go API for exchanging AMQP
-messages. You can write clients or servers using this API.
-
-Start by creating a Container with NewContainer. A Container represents a client
-or server application that can contain incoming or outgoing connections.
-
-You can create connections with the standard Go 'net' package using net.Dial or
-net.Listen. Create an AMQP connection over a net.Conn with
-Container.Connection() and open it with Connection.Open().
-
-AMQP sends messages over "links", each link has a Sender and Receiver
-end. Connection.Sender() and Connection.Receiver() allow you to create links to
-send and receive messages.
-
-You can also create an AMQP server connection by calling Connection.Listen()
-before calling Open() on the connection. You can then call Connection.Accept()
-after calling Connection.Open() to accept incoming sessions and links.
-
-*/
-package concurrent
-
-//#cgo LDFLAGS: -lqpid-proton
-import "C"
-
-// Just for package comment

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
deleted file mode 100644
index f647058..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
+++ /dev/null
@@ -1,87 +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.
-*/
-
-package concurrent
-
-import (
-	"io"
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/internal"
-)
-
-// Closed is an alias for io.EOF. It is returned as an error when an endpoint
-// was closed cleanly.
-var Closed = io.EOF
-
-// Endpoint is the common interface for Connection, Session, Link, Sender and Receiver.
-//
-// Endpoints can be created locally or by the remote peer. You must Open() an
-// endpoint before you can use it. Some endpoints have additional Set*() methods
-// that must be called before Open() to take effect, see Connection, Session,
-// Link, Sender and Receiver for details.
-//
-type Endpoint interface {
-	// Open the local end of a remotely-initiated endpoint. You must Open()
-	// endpoints returned by Connection.Accept() before using them.
-	Open() error
-
-	// Close an endpoint and signal an error to the remote end if error != nil.
-	Close(error)
-
-	// String is a human readable identifier, useful for debugging and logging.
-	String() string
-
-	// Error returns nil if the endpoint is open, otherwise returns an error.
-	// Error() == Closed means the endpoint was closed without error.
-	Error() error
-}
-
-// Implements setError() and Error() from Endpoint values that hold an error.
-type errorHolder struct {
-	err internal.FirstError
-}
-
-func (e *errorHolder) setError(err error) error { return e.err.Set(err) }
-func (e *errorHolder) Error() error             { return e.err.Get() }
-
-// Implements Error() and String() from Endpoint
-type endpoint struct {
-	errorHolder
-	str string // Must be set by the value that embeds endpoint.
-}
-
-func (e *endpoint) String() string { return e.str }
-
-// Call in proton goroutine to close an endpoint locally
-// handler will complete the close when remote end closes.
-func localClose(ep proton.Endpoint, err error) {
-	if ep.State().LocalActive() {
-		if err != nil {
-			ep.Condition().SetError(err)
-		}
-		ep.Close()
-	}
-}
-
-func (e *endpoint) closeError(err error) {
-	if err == nil {
-		err = Closed
-	}
-	e.err.Set(err)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/handler.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/handler.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/handler.go
deleted file mode 100644
index bf8fcd3..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/handler.go
+++ /dev/null
@@ -1,137 +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.
-*/
-
-package concurrent
-
-import (
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/amqp"
-)
-
-// NOTE: methods in this file are called only in the proton goroutine unless otherwise indicated.
-
-type handler struct {
-	delegator    *proton.MessagingDelegator
-	connection   *connection
-	links        map[proton.Link]Link
-	sentMessages map[proton.Delivery]*sentMessage
-	sessions     map[proton.Session]*session
-}
-
-func newHandler(c *connection) *handler {
-	h := &handler{
-		connection:   c,
-		links:        make(map[proton.Link]Link),
-		sentMessages: make(map[proton.Delivery]*sentMessage),
-		sessions:     make(map[proton.Session]*session),
-	}
-	h.delegator = proton.NewMessagingDelegator(h)
-	// Disable auto features of MessagingDelegator, we do these ourselves.
-	h.delegator.Prefetch = 0
-	h.delegator.AutoAccept = false
-	h.delegator.AutoSettle = false
-	h.delegator.AutoOpen = false
-	return h
-}
-
-func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
-	switch t {
-
-	case proton.MMessage:
-		if r, ok := h.links[e.Link()].(*receiver); ok {
-			r.handleDelivery(e.Delivery())
-		} else {
-			h.connection.closed(
-				amqp.Errorf(amqp.InternalError, "cannot find receiver for link %s", e.Link()))
-		}
-
-	case proton.MSettled:
-		if sm := h.sentMessages[e.Delivery()]; sm != nil {
-			sm.settled(nil)
-		}
-
-	case proton.MSessionOpening:
-		if e.Session().State().LocalUninit() { // Remotely opened
-			s := newSession(h.connection, e.Session())
-			h.sessions[e.Session()] = s
-			if h.connection.incoming != nil {
-				h.connection.incoming.In <- s
-			} else {
-				proton.CloseError(e.Session(), amqp.Errorf(amqp.NotAllowed, "remote sessions not allowed"))
-			}
-		}
-
-	case proton.MSessionClosing:
-		e.Session().Close()
-
-	case proton.MSessionClosed:
-		err := e.Session().RemoteCondition().Error()
-		for l, _ := range h.links {
-			if l.Session() == e.Session() {
-				h.linkClosed(l, err)
-			}
-		}
-		delete(h.sessions, e.Session())
-
-	case proton.MLinkOpening:
-		l := e.Link()
-		if l.State().LocalUninit() { // Remotely opened
-			if h.connection.incoming == nil {
-				proton.CloseError(l, amqp.Errorf(amqp.NotAllowed, ("no remote links")))
-				break
-			}
-			s := h.sessions[l.Session()]
-			if s == nil {
-				proton.CloseError(
-					l, amqp.Errorf(amqp.InternalError, ("cannot find session for link")))
-				break
-			}
-			h.connection.handleIncoming(s, l)
-		}
-
-	case proton.MLinkClosing:
-		e.Link().Close()
-
-	case proton.MLinkClosed:
-		h.linkClosed(e.Link(), e.Link().RemoteCondition().Error())
-
-	case proton.MDisconnected:
-		err := h.connection.Error()
-		for l, _ := range h.links {
-			h.linkClosed(l, err)
-		}
-		for _, s := range h.sessions {
-			s.closed(err)
-		}
-		for _, sm := range h.sentMessages {
-			sm.settled(err)
-		}
-	}
-}
-
-func (h *handler) linkClosed(l proton.Link, err error) {
-	if link := h.links[l]; link != nil {
-		link.closed(err)
-		delete(h.links, l)
-	}
-}
-
-func (h *handler) addLink(rl proton.Link, ll Link) {
-	h.links[rl] = ll
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/link.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/link.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/link.go
deleted file mode 100644
index cf4b8aa..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/link.go
+++ /dev/null
@@ -1,232 +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.
-*/
-
-package concurrent
-
-import (
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/internal"
-)
-
-type LinkSettings struct {
-	// Source address that messages come from.
-	Source string
-	// Target address that messages are going to.
-	Target string
-
-	// Unique (per container) name of the link.
-	// Leave blank to have the container generate a unique name automatically.
-	Name string
-
-	// SndSettleMode defines when the sending end of the link settles message delivery.
-	// Can set via AtMostOnce or AtLeastOnce.
-	SndSettleMode SndSettleMode
-
-	// RcvSettleMode defines when the receiving end of the link settles message delivery.
-	RcvSettleMode RcvSettleMode
-}
-
-// AtMostOnce sets "fire and forget" mode, messages are sent but no
-// acknowledgment is received, messages can be lost if there is a network
-// failure. Sets SndSettleMode=SendSettled and RcvSettleMode=RcvFirst
-func (s *LinkSettings) AtMostOnce() {
-	s.SndSettleMode = SndSettled
-	s.RcvSettleMode = RcvFirst
-}
-
-// AtLeastOnce requests acknowledgment for every message, acknowledgment
-// indicates the message was definitely received. In the event of a
-// failure, unacknowledged messages can be re-sent but there is a chance
-// that the message will be received twice in this case.
-// Sets SndSettleMode=SndUnsettled and RcvSettleMode=RcvFirst
-func (s *LinkSettings) AtLeastOnce() {
-	s.SndSettleMode = SndUnsettled
-	s.RcvSettleMode = RcvFirst
-}
-
-// Link is the common interface for Sender and Receiver links.
-type Link interface {
-	Endpoint
-
-	// Settings for this link.
-	Settings() LinkSettings
-
-	IsSender() bool
-	IsReceiver() bool
-
-	IsOpen() bool
-
-	// Credit indicates how many messages the receiving end of the link can accept.
-	//
-	// A Receiver adds credit automatically when it can accept more messages.
-	//
-	// On a Sender credit can be negative, meaning that messages in excess of the
-	// receiver's credit limit have been buffered locally till credit is available.
-	Credit() (int, error)
-
-	// Called in event loop on closed event.
-	closed(err error)
-}
-
-// SndSettleMode defines when the sending end of the link settles message delivery.
-// Can set via AtMostOnce or AtLeastOnce.
-type SndSettleMode proton.SndSettleMode
-
-const (
-	// Messages are sent unsettled
-	SndUnsettled = SndSettleMode(proton.SndUnsettled)
-	// Messages are sent already settled
-	SndSettled = SndSettleMode(proton.SndSettled)
-	// Sender can send either unsettled or settled messages.
-	SendMixed = SndSettleMode(proton.SndMixed)
-)
-
-// RcvSettleMode defines when the receiving end of the link settles message delivery.
-type RcvSettleMode proton.RcvSettleMode
-
-const (
-	// Receiver settles first.
-	RcvFirst = RcvSettleMode(proton.RcvFirst)
-	// Receiver waits for sender to settle before settling.
-	RcvSecond = RcvSettleMode(proton.RcvSecond)
-)
-
-// Implement Link interface, for embedding in sender and receiver.
-//
-// Link creation: there are two ways to create a link.
-//
-// Session.NewSender() and Session.NewReceiver() create a "local" link which has
-// the session and isSender fields set. The user can set properties like Name,
-// Target and Source. On Open() the eLink is created and the properties are set
-// on the eLink.
-//
-// An "incoming" is created by the connection. with session, isSender, name,
-// source, target all set from the incoming eLink, these properties cannot be
-// changed by the user. There may be other properties (e.g. Receiver.SetCapacity())
-// that can be set by the user before Open().
-//
-type link struct {
-	endpoint
-
-	settings LinkSettings
-	session  *session
-	eLink    proton.Link
-	isOpen   bool
-	isSender bool
-}
-
-func (l *link) Settings() LinkSettings { return l.settings }
-func (l *link) IsSender() bool         { return l.isSender }
-func (l *link) IsReceiver() bool       { return !l.isSender }
-func (l *link) IsOpen() bool           { return l.isOpen }
-func (l *link) Session() Session       { return l.session }
-func (l *link) Connection() Connection { return l.session.Connection() }
-
-func (l *link) engine() *proton.Engine { return l.session.connection.engine }
-func (l *link) handler() *handler      { return l.session.connection.handler }
-
-// initLocal initializes a local link associated with a session.
-// Call in proton goroutine
-func makeLocalLink(sn *session, isSender bool, settings LinkSettings) (link, error) {
-	var l link
-	l.session = sn
-	l.settings = settings
-	l.isSender = isSender
-	if l.settings.Name == "" {
-		l.settings.Name = l.session.connection.container.nextLinkName()
-	}
-	if l.IsSender() {
-		l.eLink = l.session.eSession.Sender(l.settings.Name)
-	} else {
-		l.eLink = l.session.eSession.Receiver(l.settings.Name)
-	}
-	if l.eLink.IsNil() {
-		return l, l.setError(internal.Errorf("cannot create link %s", l))
-	}
-	l.setSettings()
-	return l, nil
-}
-
-// Set local end of the link to match LinkSettings.
-func (l *link) setSettings() {
-	l.eLink.Source().SetAddress(l.settings.Source)
-	l.eLink.Target().SetAddress(l.settings.Target)
-	l.eLink.SetSndSettleMode(proton.SndSettleMode(l.settings.SndSettleMode))
-	l.eLink.SetRcvSettleMode(proton.RcvSettleMode(l.settings.RcvSettleMode))
-	l.str = l.eLink.String()
-}
-
-// initIncoming sets link settings from an incoming proton.Link.
-// Call in proton goroutine
-func makeIncomingLink(sn *session, eLink proton.Link) link {
-	l := link{
-		session:  sn,
-		isSender: eLink.IsSender(),
-		eLink:    eLink,
-		settings: LinkSettings{
-			Source:        eLink.RemoteSource().Address(),
-			Target:        eLink.RemoteTarget().Address(),
-			Name:          eLink.Name(),
-			SndSettleMode: SndSettleMode(eLink.RemoteSndSettleMode()),
-			RcvSettleMode: RcvSettleMode(eLink.RemoteRcvSettleMode()),
-		},
-	}
-	l.setSettings()
-	return l
-}
-
-func (l *link) setPanicIfOpen() {
-	if l.IsOpen() {
-		panic(internal.Errorf("link is already open %s", l))
-	}
-}
-
-// open a link, local or incoming. Call in proton goroutine
-func (l *link) open() error {
-	if l.Error() != nil {
-		return l.Error()
-	}
-	l.eLink.Open()
-	l.isOpen = true
-	return nil
-}
-
-// Called in proton goroutine
-func (l *link) closed(err error) {
-	l.setError(err)
-	if l.eLink.State().RemoteActive() {
-		if l.Error() != nil {
-			l.eLink.Condition().SetError(l.Error())
-		}
-		l.eLink.Close()
-	}
-	l.setError(Closed) // If no error set, mark as closed.
-}
-
-func (l *link) Credit() (credit int, err error) {
-	err = l.engine().InjectWait(func() error {
-		credit = l.eLink.Credit()
-		return nil
-	})
-	return
-}
-
-func (l *link) Close(err error) {
-	l.engine().Inject(func() { localClose(l.eLink, err) })
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
deleted file mode 100644
index 0ee9f1a..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
+++ /dev/null
@@ -1,205 +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.
-*/
-
-package concurrent
-
-import (
-	"fmt"
-	"net"
-	"qpid.apache.org/proton/amqp"
-	"testing"
-	"time"
-)
-
-func panicIf(err error) {
-	if err != nil {
-		panic(err)
-	}
-}
-
-// Start a server, return listening addr and channel for incoming Connection.
-func newServer(cont Container) (net.Addr, <-chan Connection) {
-	listener, err := net.Listen("tcp", "")
-	panicIf(err)
-	addr := listener.Addr()
-	ch := make(chan Connection)
-	go func() {
-		conn, err := listener.Accept()
-		c, err := cont.Connection(conn)
-		panicIf(err)
-		c.Server()
-		c.Listen()
-		panicIf(c.Open())
-		ch <- c
-	}()
-	return addr, ch
-}
-
-// Return open an client connection and session, return the session.
-func newClient(cont Container, addr net.Addr) Session {
-	conn, err := net.Dial(addr.Network(), addr.String())
-	panicIf(err)
-	c, err := cont.Connection(conn)
-	panicIf(err)
-	c.Open()
-	sn, err := c.Session()
-	panicIf(err)
-	panicIf(sn.Open())
-	return sn
-}
-
-// Return client and server ends of the same connection.
-func newClientServer() (client Session, server Connection) {
-	addr, ch := newServer(NewContainer(""))
-	client = newClient(NewContainer(""), addr)
-	return client, <-ch
-}
-
-// Close client and server
-func closeClientServer(client Session, server Connection) {
-	client.Connection().Close(nil)
-	server.Close(nil)
-}
-
-// Send a message one way with a client sender and server receiver, verify ack.
-func TestClientSendServerReceive(t *testing.T) {
-	var err error
-	client, server := newClientServer()
-	defer func() {
-		closeClientServer(client, server)
-	}()
-
-	timeout := time.Second * 2
-	nLinks := 3
-	nMessages := 3
-
-	s := make([]Sender, nLinks)
-	for i := 0; i < nLinks; i++ {
-		s[i], err = client.Sender(fmt.Sprintf("foo%d", i))
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	// Server accept session and receivers
-	ep, err := server.Accept()
-	ep.Open() // Accept incoming session
-	r := make([]Receiver, nLinks)
-	for i := 0; i < nLinks; i++ { // Accept incoming receivers
-		ep, err = server.Accept()
-		r[i] = ep.(Receiver)
-		err = r[i].Open()
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	for i := 0; i < nLinks; i++ {
-		for j := 0; j < nMessages; j++ {
-			// Client send
-			m := amqp.NewMessageWith(fmt.Sprintf("foobar%v-%v", i, j))
-			sm, err := s[i].Send(m)
-			if err != nil {
-				t.Fatal(err)
-			}
-
-			// Server recieve
-			rm, err := r[i].Receive()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if want, got := interface{}(fmt.Sprintf("foobar%v-%v", i, j)), rm.Message.Body(); want != got {
-				t.Errorf("%#v != %#v", want, got)
-			}
-
-			// Should not be acknowledged on client yet
-			if d, err := sm.DispositionTimeout(0); err != Timeout || NoDisposition != d {
-				t.Errorf("want [no-disposition/timeout] got [%v/%v]", d, err)
-			}
-			// Server ack
-			if err := rm.Acknowledge(Rejected); err != nil {
-				t.Error(err)
-			}
-			// Client get ack.
-			if d, err := sm.DispositionTimeout(timeout); err != nil || Rejected != d {
-				t.Errorf("want [rejected/nil] got [%v/%v]", d, err)
-			}
-		}
-	}
-}
-
-func TestClientReceiver(t *testing.T) {
-	client, server := newClientServer()
-	nMessages := 3
-
-	done := make(chan struct{})
-	go func() { // Server sends
-		defer close(done)
-		for {
-			ep, err := server.Accept()
-			switch {
-			case err == Closed:
-				return
-			case err == nil:
-				break
-			default:
-				t.Error(err)
-				return
-			}
-			ep.Open()
-			if s, ok := ep.(Sender); ok {
-				go func() {
-					for i := int32(0); i < int32(nMessages); i++ {
-						sm, err := s.Send(amqp.NewMessageWith(i))
-						if err != nil {
-							t.Error(err)
-							return
-						} else {
-							sm.Disposition() // Sync send.
-						}
-					}
-					s.Close(nil)
-				}()
-			}
-		}
-	}()
-
-	r, err := client.Receiver("foo")
-	if err != nil {
-		t.Fatal(err)
-	}
-	for i := int32(0); i < int32(nMessages); i++ {
-		rm, err := r.Receive()
-		if err != nil {
-			if err != Closed {
-				t.Error(err)
-			}
-			break
-		}
-		if err := rm.Accept(); err != nil {
-			t.Error(err)
-		}
-		if b, ok := rm.Message.Body().(int32); !ok || b != i {
-			t.Errorf("want %v, true got %v, %v", i, b, ok)
-		}
-	}
-	server.Close(nil)
-	<-done
-	client.Connection().Close(nil)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
deleted file mode 100644
index 5bcf9f2..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
+++ /dev/null
@@ -1,241 +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.
-*/
-
-package concurrent
-
-import (
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/internal"
-	"time"
-)
-
-type ReceiverSettings struct {
-	LinkSettings
-
-	// Capacity is the number of messages that the receiver can buffer locally.
-	// If unset (zero) it will be set to 1.
-	Capacity int
-
-	// Prefetch==true means the Receiver will automatically issue credit to the
-	// remote sender to keep its buffer as full as possible, i.e. it will
-	// "pre-fetch" messages independently of the application calling
-	// Receive(). This gives good throughput for applications that handle a
-	// continuous stream of messages. Larger capacity may improve throughput, the
-	// optimal value depends on the characteristics of your application.
-	//
-	// Prefetch==false means the Receiver will issue only issue credit when you
-	// call Receive(), and will only issue enough credit to satisfy the calls
-	// actually made. This gives lower throughput but will not fetch any messages
-	// in advance. It is good for synchronous applications that need to evaluate
-	// each message before deciding whether to receive another. The
-	// request-response pattern is a typical example.  If you make concurrent
-	// calls to Receive with pre-fetch disabled, you can improve performance by
-	// setting the capacity close to the expected number of concurrent calls.
-	//
-	Prefetch bool
-}
-
-// Receiver is a Link that receives messages.
-//
-type Receiver interface {
-	Link
-
-	// SetCapacity sets the Capacity and Prefetch (see ReceiverSettings) It may
-	// may called before Open() on an accepted receiver, it cannot be changed once
-	// the receiver is Open().
-	SetCapacity(capacity int, prefetch bool)
-
-	// Receive blocks until a message is available or until the Receiver is closed
-	// and has no more buffered messages.
-	Receive() (ReceivedMessage, error)
-
-	// ReceiveTimeout is like Receive but gives up after timeout, see Timeout.
-	ReceiveTimeout(timeout time.Duration) (ReceivedMessage, error)
-}
-
-// Flow control policy for a receiver.
-type policy interface {
-	// Called at the start of Receive() to adjust credit before fetching a message.
-	Pre(*receiver)
-	// Called after Receive() has received a message from Buffer() before it returns.
-	// Non-nil error means no message was received because of an error.
-	Post(*receiver, error)
-}
-
-type prefetchPolicy struct{}
-
-func (p prefetchPolicy) Flow(r *receiver) {
-	r.engine().Inject(func() {
-		_, _, max := r.credit()
-		if max > 0 {
-			r.eLink.Flow(max)
-		}
-	})
-}
-func (p prefetchPolicy) Pre(r *receiver) { p.Flow(r) }
-func (p prefetchPolicy) Post(r *receiver, err error) {
-	if err == nil {
-		p.Flow(r)
-	}
-}
-
-type noPrefetchPolicy struct{ waiting int }
-
-func (p noPrefetchPolicy) Flow(r *receiver) { // Not called in proton goroutine
-	r.engine().Inject(func() {
-		len, credit, max := r.credit()
-		add := p.waiting - (len + credit)
-		if add > max {
-			add = max // Don't overflow
-		}
-		if add > 0 {
-			r.eLink.Flow(add)
-		}
-	})
-}
-func (p noPrefetchPolicy) Pre(r *receiver) { p.waiting++; p.Flow(r) }
-func (p noPrefetchPolicy) Post(r *receiver, err error) {
-	p.waiting--
-	if err == nil {
-		p.Flow(r)
-	}
-}
-
-// Receiver implementation
-type receiver struct {
-	link
-	// Set in Setup()
-	capacity int
-	prefetch bool
-
-	// Set in Open()
-	buffer chan ReceivedMessage
-	policy policy
-}
-
-func newReceiver(l link) Receiver { return &receiver{link: l} }
-
-func (r *receiver) SetCapacity(capacity int, prefetch bool) {
-	r.setPanicIfOpen()
-	if capacity < 1 {
-		capacity = 1
-	}
-	r.capacity = capacity
-	r.prefetch = prefetch
-}
-
-// Accept and open an incoming receiver.
-func (r *receiver) Open() error {
-	if r.capacity == 0 {
-		r.SetCapacity(1, false)
-	}
-	if r.prefetch {
-		r.policy = &prefetchPolicy{}
-	} else {
-		r.policy = &noPrefetchPolicy{}
-	}
-	err := r.engine().InjectWait(func() error {
-		err := r.open()
-		if err == nil {
-			r.buffer = make(chan ReceivedMessage, r.capacity)
-			r.handler().addLink(r.eLink, r)
-		}
-		return err
-	})
-	return r.setError(err)
-}
-
-// call in proton goroutine
-func (r *receiver) credit() (buffered, credit, capacity int) {
-	return len(r.buffer), r.eLink.Credit(), cap(r.buffer)
-}
-
-func (r *receiver) Capacity() int { return cap(r.buffer) }
-
-func (r *receiver) Receive() (rm ReceivedMessage, err error) {
-	return r.ReceiveTimeout(Forever)
-}
-
-func (r *receiver) ReceiveTimeout(timeout time.Duration) (rm ReceivedMessage, err error) {
-	internal.Assert(r.buffer != nil, "Receiver is not open: %s", r)
-	r.policy.Pre(r)
-	defer func() { r.policy.Post(r, err) }()
-	rmi, ok, timedout := timedReceive(r.buffer, timeout)
-	switch {
-	case timedout:
-		return ReceivedMessage{}, Timeout
-	case !ok:
-		return ReceivedMessage{}, r.Error()
-	default:
-		return rmi.(ReceivedMessage), nil
-	}
-}
-
-// Called in proton goroutine
-func (r *receiver) handleDelivery(delivery proton.Delivery) {
-	if r.eLink.State().RemoteClosed() {
-		localClose(r.eLink, r.eLink.RemoteCondition().Error())
-		return
-	}
-	if delivery.HasMessage() {
-		m, err := delivery.Message()
-		if err != nil {
-			localClose(r.eLink, err)
-			return
-		}
-		internal.Assert(m != nil)
-		r.eLink.Advance()
-		if r.eLink.Credit() < 0 {
-			localClose(r.eLink, internal.Errorf("received message in excess of credit limit"))
-		} else {
-			// We never issue more credit than cap(buffer) so this will not block.
-			r.buffer <- ReceivedMessage{m, delivery, r}
-		}
-	}
-}
-
-func (r *receiver) closed(err error) {
-	r.closeError(err)
-	close(r.buffer)
-}
-
-// ReceivedMessage contains an amqp.Message and allows the message to be acknowledged.
-type ReceivedMessage struct {
-	// Message is the received message.
-	Message amqp.Message
-
-	eDelivery proton.Delivery
-	receiver  Receiver
-}
-
-// Acknowledge a ReceivedMessage with the given disposition code.
-func (rm *ReceivedMessage) Acknowledge(disposition Disposition) error {
-	return rm.receiver.(*receiver).engine().InjectWait(func() error {
-		// Settle doesn't return an error but if the receiver is broken the settlement won't happen.
-		rm.eDelivery.SettleAs(uint64(disposition))
-		return rm.receiver.Error()
-	})
-}
-
-// Accept is short for Acknowledge(Accpeted)
-func (rm *ReceivedMessage) Accept() error { return rm.Acknowledge(Accepted) }
-
-// Reject is short for Acknowledge(Rejected)
-func (rm *ReceivedMessage) Reject() error { return rm.Acknowledge(Rejected) }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/sender.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/sender.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/sender.go
deleted file mode 100644
index 7a65a24..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/sender.go
+++ /dev/null
@@ -1,190 +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.
-*/
-
-package concurrent
-
-// #include <proton/disposition.h>
-import "C"
-
-import (
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/internal"
-	"time"
-)
-
-type SenderSettings struct {
-	LinkSettings
-}
-
-// Sender is a Link that sends messages.
-type Sender interface {
-	Link
-
-	// Send a message asynchronously, return a SentMessage to identify it.
-	//
-	// Returns nil if the link is in Unreliable mode and no acknowledgement
-	// will be received.
-	//
-	// See Credit() for note on buffering.
-	//
-	// Use SentMessage.Disposition() to wait for acknowledgement.
-	Send(m amqp.Message) (sm SentMessage, err error)
-}
-
-type sender struct{ link }
-
-func newSender(l link) Sender { return &sender{l} }
-
-// Open the Sender, must be called before calling Send().
-func (s *sender) Open() error {
-	err := s.engine().InjectWait(func() error {
-		err := s.open()
-		if err == nil {
-			s.handler().addLink(s.eLink, s)
-		}
-		return err
-	})
-	return s.setError(err)
-}
-
-// Disposition indicates the outcome of a settled message delivery.
-type Disposition uint64
-
-const (
-	// No disposition available, not yet acknowledged or an error occurred
-	NoDisposition Disposition = 0
-	// Message was accepted by the receiver
-	Accepted = proton.Accepted
-	// Message was rejected as invalid by the receiver
-	Rejected = proton.Rejected
-	// Message was not processed by the receiver but may be processed by some other receiver.
-	Released = proton.Released
-)
-
-// String human readable name for a Disposition.
-func (d Disposition) String() string {
-	switch d {
-	case NoDisposition:
-		return "no-disposition"
-	case Accepted:
-		return "accepted"
-	case Rejected:
-		return "rejected"
-	case Released:
-		return "released"
-	default:
-		return "unknown"
-	}
-}
-
-func (s *sender) Send(m amqp.Message) (SentMessage, error) {
-	internal.Assert(s.IsOpen(), "sender is not open: %s", s)
-	if err := s.Error(); err != nil {
-		return nil, err
-	}
-	var sm SentMessage
-	err := s.engine().InjectWait(func() error {
-		eDelivery, err := s.eLink.Send(m)
-		if err == nil {
-			if s.eLink.SndSettleMode() == proton.SndSettled {
-				eDelivery.Settle()
-			} else {
-				sm = newSentMessage(s.session.connection, eDelivery)
-				s.session.connection.handler.sentMessages[eDelivery] = sm.(*sentMessage)
-			}
-		}
-		return err
-	})
-	return sm, err
-}
-
-func (s *sender) closed(err error) {
-	s.closeError(err)
-}
-
-// SentMessage represents a previously sent message. It allows you to wait for acknowledgement.
-type SentMessage interface {
-	// Disposition blocks till the message is acknowledged and returns the
-	// disposition state.  NoDisposition means the Connection or the SentMessage
-	// was closed before the message was acknowledged.
-	Disposition() (Disposition, error)
-
-	// DispositionTimeout is like Disposition but gives up after timeout, see Timeout.
-	DispositionTimeout(time.Duration) (Disposition, error)
-
-	// Forget interrupts any call to Disposition on this SentMessage and tells the
-	// peer we are no longer interested in the disposition of this message.
-	Forget()
-
-	// Error returns the error that closed the disposition, or nil if there was no error.
-	// If the disposition closed because the connection closed, it will return Closed.
-	Error() error
-}
-
-type sentMessage struct {
-	connection  *connection
-	eDelivery   proton.Delivery
-	done        chan struct{}
-	disposition Disposition
-	err         error
-}
-
-func newSentMessage(c *connection, d proton.Delivery) *sentMessage {
-	return &sentMessage{c, d, make(chan struct{}), NoDisposition, nil}
-}
-
-func (sm *sentMessage) Disposition() (Disposition, error) {
-	<-sm.done
-	return sm.disposition, sm.err
-}
-
-func (sm *sentMessage) DispositionTimeout(timeout time.Duration) (Disposition, error) {
-	if _, _, timedout := timedReceive(sm.done, timeout); timedout {
-		return sm.disposition, Timeout
-	} else {
-		return sm.disposition, sm.err
-	}
-}
-
-func (sm *sentMessage) Forget() {
-	sm.connection.engine.Inject(func() {
-		sm.eDelivery.Settle()
-		delete(sm.connection.handler.sentMessages, sm.eDelivery)
-	})
-	sm.finish()
-}
-
-func (sm *sentMessage) settled(err error) {
-	if sm.eDelivery.Settled() {
-		sm.disposition = Disposition(sm.eDelivery.Remote().Type())
-	}
-	sm.err = err
-	sm.finish()
-}
-
-func (sm *sentMessage) finish() {
-	select {
-	case <-sm.done: // No-op if already closed
-	default:
-		close(sm.done)
-	}
-}
-
-func (sm *sentMessage) Error() error { return sm.err }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
deleted file mode 100644
index 2f609be..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
+++ /dev/null
@@ -1,114 +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.
-*/
-
-package concurrent
-
-import (
-	"qpid.apache.org/proton"
-	"qpid.apache.org/proton/internal"
-)
-
-// Session is an AMQP session, it contains Senders and Receivers.
-//
-type Session interface {
-	Endpoint
-
-	// Connection owning this session.
-	Connection() Connection
-
-	// Sender opens a new sender. v can be a string, which is used as the Target
-	// address, or a SenderSettings struct containing more details settings.
-	Sender(v interface{}) (Sender, error)
-
-	// Receiver opens a new Receiver. v can be a string, which is used as the
-	// Source address, or a ReceiverSettings struct containing more details
-	// settings.
-	Receiver(v interface{}) (Receiver, error)
-}
-
-type session struct {
-	endpoint
-	eSession   proton.Session
-	connection *connection
-}
-
-// in proton goroutine
-func newSession(c *connection, es proton.Session) *session {
-	return &session{
-		connection: c,
-		eSession:   es,
-		endpoint:   endpoint{str: es.String()},
-	}
-}
-
-func (s *session) Connection() Connection     { return s.connection }
-func (s *session) eEndpoint() proton.Endpoint { return s.eSession }
-func (s *session) engine() *proton.Engine     { return s.connection.engine }
-func (s *session) Open() error                { s.engine().Inject(s.eSession.Open); return nil }
-func (s *session) Close(err error) {
-	s.engine().Inject(func() { localClose(s.eSession, err) })
-}
-
-func (s *session) Sender(v interface{}) (snd Sender, err error) {
-	var settings LinkSettings
-	switch v := v.(type) {
-	case string:
-		settings.Target = v
-	case SenderSettings:
-		settings = v.LinkSettings
-	default:
-		internal.Assert(false, "NewSender() want string or SenderSettings, got %T", v)
-	}
-	err = s.engine().InjectWait(func() error {
-		l, err := makeLocalLink(s, true, settings)
-		snd = newSender(l)
-		return err
-	})
-	if err == nil {
-		err = snd.Open()
-	}
-	return
-}
-
-func (s *session) Receiver(v interface{}) (rcv Receiver, err error) {
-	var settings ReceiverSettings
-	switch v := v.(type) {
-	case string:
-		settings.Source = v
-	case ReceiverSettings:
-		settings = v
-	default:
-		internal.Assert(false, "NewReceiver() want string or ReceiverSettings, got %T", v)
-	}
-	err = s.engine().InjectWait(func() error {
-		l, err := makeLocalLink(s, false, settings.LinkSettings)
-		rcv = newReceiver(l)
-		return err
-	})
-	rcv.SetCapacity(settings.Capacity, settings.Prefetch)
-	if err == nil {
-		err = rcv.Open()
-	}
-	return
-}
-
-// Called from handler on closed.
-func (s *session) closed(err error) {
-	s.closeError(err)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/time.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/time.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/time.go
deleted file mode 100644
index e9093d3..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/time.go
+++ /dev/null
@@ -1,71 +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.
-*/
-
-package concurrent
-
-import (
-	"qpid.apache.org/proton/internal"
-	"reflect"
-	"time"
-)
-
-// Timeout is the error returned if an operation does not complete on time.
-//
-// Methods named *Timeout in this package take time.Duration timeout parameter.
-//
-// If timeout > 0 and there is no result available before the timeout, they
-// return a zero or nil value and Timeout as an error.
-//
-// If timeout == 0 they will return a result if one is immediatley available or
-// nil/zero and Timeout as an error if not.
-//
-// If timeout == Forever the function will return only when there is a result or
-// some non-timeout error occurs.
-//
-var Timeout = internal.Errorf("timeout")
-
-// Forever can be used as a timeout parameter to indicate wait forever.
-const Forever time.Duration = -1
-
-// timedReceive receives on channel (which can be a chan of any type), waiting
-// up to timeout.
-//
-// timeout==0 means do a non-blocking receive attempt. timeout < 0 means block
-// forever. Other values mean block up to the timeout.
-//
-func timedReceive(channel interface{}, timeout time.Duration) (value interface{}, ok bool, timedout bool) {
-	cases := []reflect.SelectCase{
-		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(channel)},
-	}
-	switch {
-	case timeout == 0: // Non-blocking receive
-		cases = append(cases, reflect.SelectCase{Dir: reflect.SelectDefault})
-	case timeout < 0: // Block forever, nothing to add
-	default: // Block up to timeout
-		cases = append(cases,
-			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(time.After(timeout))})
-	}
-	chosen, recv, recvOk := reflect.Select(cases)
-	switch {
-	case chosen == 0:
-		return recv.Interface(), recvOk, false
-	default:
-		return nil, false, true
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/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 25b43af..e9d6d6f 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
@@ -18,19 +18,14 @@ under the License.
 */
 
 /*
+Package proton is an event-driven, concurrent-unsafe Go library for AMQP messaging.
+You can write clients and servers using this library.
 
-Package proton is a Go binding for the Qpid Proton AMQP messaging toolkit (see
-http://qpid.apache.org/proton) It is a concurrent-unsafe, event-driven API that
-closely follows the Proton C API.
-
-Package qpid.apache.org/proton/concurrent provides an alternative,
-concurrent-safe, procedural API. Most applications will find the concurrent API
-easier to use.
-
-If you need direct access to the underlying proton library for some reason, this
-package provides it. The types in this package are simple wrappers for C
-pointers. They provide access to C functions as Go methods and do some trivial
-conversions, for example between Go string and C null-terminated char* strings.
+This package is a port of the Proton C API into Go (see
+http://qpid.apache.org/proton) Go programmers may find the 'electron' package
+more convenient, it provides a concurrent-safe API that allows you to do
+procedural loops in goroutines rather than implementing event handlers that must
+run in a single goroutine.
 
 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
@@ -42,22 +37,26 @@ and Go method
 
     func (proton.Foo) DoSomething(...)
 
-The proton.Engine type pumps data between a Go net.Conn connection and a
-proton.Connection goroutine that feeds events to a proton.MessagingHandler. See
-the proton.Engine documentation for more detail.
+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.)
 
-EventHandler and MessagingHandler define an event handling interfaces that you
-can implement to react to protocol events. MessagingHandler provides a somewhat
-simpler set of events and automates some common tasks for you.
+All events generated by proton are handled in the single event-loop goroutine
+associated with the Connection and Engine. You can use Engine.Inject() or
+Engine.InjectWait() to inject additional functions into the event loop. Only
+injected functions or handler functions can use proton types (such as Session,
+Link etc.) Handlers and injected functions can set up channels to communicate
+with other goroutines..
 
-You must ensure that all events are handled in a single goroutine or that you
-serialize all all uses of the proton objects associated with a single connection
-using a lock.  You can use channels to communicate between application
-goroutines and the event-handling goroutine, see Engine documentation for more details.
+Separate Connection and Engine instances are independent, and can run concurrently.
 
-Package qpid.apache.org/proton/concurrent does all this for you and presents a
-simple concurrent-safe interface, for most applications you should use that
-instead.
+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 may be easier to use w for some applications.
 
 */
 package proton


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


[17/50] [abbrv] qpid-proton git commit: NO-JIRA: C++: Add event::name() to give event type name as string, for debugging/logging.

Posted by ac...@apache.org.
NO-JIRA: C++: Add event::name() to give event type name as string, for debugging/logging.


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

Branch: refs/heads/go1
Commit: da3ee2c8fe67530ec8421f2b95148190b7aac255
Parents: 8112f5f
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 9 15:26:55 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 9 15:37:43 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/include/proton/event.hpp  |  5 +++
 .../cpp/include/proton/messaging_event.hpp      |  2 +
 .../cpp/include/proton/proton_event.hpp         |  4 +-
 proton-c/bindings/cpp/src/event.cpp             |  1 -
 proton-c/bindings/cpp/src/messaging_event.cpp   | 44 ++++++++++++++++++++
 proton-c/bindings/cpp/src/proton_event.cpp      |  6 ++-
 6 files changed, 59 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/include/proton/event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event.hpp b/proton-c/bindings/cpp/include/proton/event.hpp
index 486a5c9..82f6cb6 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -26,6 +26,7 @@
 #include "proton/connection.hpp"
 #include "proton/message.hpp"
 #include <vector>
+#include <string>
 
 namespace proton {
 
@@ -41,6 +42,9 @@ class event {
     /// Dispatch this event to a handler.
     virtual PN_CPP_EXTERN void dispatch(handler &h) = 0;
 
+    /// Return the name of the event type
+    virtual PN_CPP_EXTERN std::string name() const = 0;
+
     /// Get container.
     virtual PN_CPP_EXTERN class container &container();
     /// Get connection.
@@ -64,6 +68,7 @@ class event {
     event& operator=(const event&);
 };
 
+
 }
 
 #endif  /*!PROTON_CPP_EVENT_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/include/proton/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_event.hpp b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
index 5553faf..d130064 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_event.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
@@ -37,6 +37,8 @@ class messaging_event : public proton_event
 {
   public:
 
+    std::string name() const;
+
     // TODO aconway 2015-07-16: document meaning of each event type.
 
     /** Event types for a messaging_handler */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/include/proton/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/proton_event.hpp b/proton-c/bindings/cpp/include/proton/proton_event.hpp
index c809e55..f71af55 100644
--- a/proton-c/bindings/cpp/include/proton/proton_event.hpp
+++ b/proton-c/bindings/cpp/include/proton/proton_event.hpp
@@ -38,6 +38,8 @@ class proton_event : public event
 {
   public:
 
+    std::string name() const;
+
     ///@name Event types
     ///@{
 
@@ -279,7 +281,7 @@ class proton_event : public event
     virtual PN_CPP_EXTERN class delivery& delivery();
 
     /** Get type of event */
-    PN_CPP_EXTERN event_type type();
+    PN_CPP_EXTERN event_type type() const;
 
     PN_CPP_EXTERN pn_event_t* pn_event();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/src/event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/event.cpp b/proton-c/bindings/cpp/src/event.cpp
index d7a99dc..84927c4 100644
--- a/proton-c/bindings/cpp/src/event.cpp
+++ b/proton-c/bindings/cpp/src/event.cpp
@@ -38,7 +38,6 @@ event::event() {}
 
 event::~event() {}
 
-
 container &event::container() {
     // Subclasses to override as appropriate
     throw error(MSG("No container context for event"));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index 82f9159..e602dc4 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -152,4 +152,48 @@ void messaging_event::dispatch(handler &h) {
     }
 }
 
+std::string messaging_event::name() const {
+    switch (type()) {
+      case PROTON: return pn_event_type_name(pn_event_type_t(proton_event::type()));
+      case ABORT: return "ABORT";
+      case ACCEPTED: return "ACCEPTED";
+      case COMMIT: return "COMMIT";
+      case CONNECTION_CLOSED: return "CONNECTION_CLOSED";
+      case CONNECTION_CLOSING: return "CONNECTION_CLOSING";
+      case CONNECTION_ERROR: return "CONNECTION_ERROR";
+      case CONNECTION_OPENED: return "CONNECTION_OPENED";
+      case CONNECTION_OPENING: return "CONNECTION_OPENING";
+      case DISCONNECTED: return "DISCONNECTED";
+      case FETCH: return "FETCH";
+      case ID_LOADED: return "ID_LOADED";
+      case LINK_CLOSED: return "LINK_CLOSED";
+      case LINK_CLOSING: return "LINK_CLOSING";
+      case LINK_OPENED: return "LINK_OPENED";
+      case LINK_OPENING: return "LINK_OPENING";
+      case LINK_ERROR: return "LINK_ERROR";
+      case MESSAGE: return "MESSAGE";
+      case QUIT: return "QUIT";
+      case RECORD_INSERTED: return "RECORD_INSERTED";
+      case RECORDS_LOADED: return "RECORDS_LOADED";
+      case REJECTED: return "REJECTED";
+      case RELEASED: return "RELEASED";
+      case REQUEST: return "REQUEST";
+      case RESPONSE: return "RESPONSE";
+      case SENDABLE: return "SENDABLE";
+      case SESSION_CLOSED: return "SESSION_CLOSED";
+      case SESSION_CLOSING: return "SESSION_CLOSING";
+      case SESSION_OPENED: return "SESSION_OPENED";
+      case SESSION_OPENING: return "SESSION_OPENING";
+      case SESSION_ERROR: return "SESSION_ERROR";
+      case SETTLED: return "SETTLED";
+      case START: return "START";
+      case TIMER: return "TIMER";
+      case TRANSACTION_ABORTED: return "TRANSACTION_ABORTED";
+      case TRANSACTION_COMMITTED: return "TRANSACTION_COMMITTED";
+      case TRANSACTION_DECLARED: return "TRANSACTION_DECLARED";
+      case TRANSPORT_CLOSED: return "TRANSPORT_CLOSED";
+      default: return "UNKNOWN";
+    }
+}
+
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da3ee2c8/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 4b2d3ac..9b08826 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -42,7 +42,9 @@ proton_event::proton_event(pn_event_t *ce, proton_event::event_type t, class con
     container_(c)
 {}
 
-int proton_event::type() { return type_; }
+int proton_event::type() const { return type_; }
+
+std::string proton_event::name() const { return pn_event_type_name(pn_event_type_t(type_)); }
 
 pn_event_t *proton_event::pn_event() { return pn_event_; }
 
@@ -181,3 +183,5 @@ const proton_event::event_type proton_event::SELECTABLE_ERROR=PN_SELECTABLE_ERRO
 const proton_event::event_type proton_event::SELECTABLE_EXPIRED=PN_SELECTABLE_EXPIRED;
 const proton_event::event_type proton_event::SELECTABLE_FINAL=PN_SELECTABLE_FINAL;
 }
+
+


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


[04/50] [abbrv] qpid-proton git commit: PROTON-1008: add toggle for sasl layer

Posted by ac...@apache.org.
PROTON-1008: add toggle for sasl layer


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

Branch: refs/heads/go1
Commit: baaf74ab7ab4ff699cbde374db1fdc2006eede0a
Parents: fe0817e
Author: Gordon Sim <gs...@redhat.com>
Authored: Tue Sep 29 22:48:37 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Fri Oct 2 20:02:06 2015 +0100

----------------------------------------------------------------------
 proton-c/bindings/python/proton/reactor.py | 54 +++++++++++++++++++------
 1 file changed, 42 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/baaf74ab/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 8de5d89..b8e4b6a 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -497,6 +497,7 @@ class Connector(Handler):
         self.ssl_domain = None
         self.allow_insecure_mechs = True
         self.allowed_mechs = None
+        self.sasl_enabled = True
 
     def _connect(self, connection):
         url = self.address.next()
@@ -505,17 +506,15 @@ class Connector(Handler):
         logging.info("connecting to %s..." % connection.hostname)
 
         transport = Transport()
-        sasl = None
-        if url.username:
-            connection.user = url.username
+        if self.sasl_enabled:
             sasl = transport.sasl()
             sasl.allow_insecure_mechs = self.allow_insecure_mechs
-        if url.password:
-            connection.password = url.password
-        if self.allowed_mechs:
-            if sasl == None:
-                sasl = transport.sasl()
-            sasl.allowed_mechs(self.allowed_mechs)
+            if url.username:
+                connection.user = url.username
+            if url.password:
+                connection.password = url.password
+            if self.allowed_mechs:
+                sasl.allowed_mechs(self.allowed_mechs)
         transport.bind(connection)
         if self.heartbeat:
             transport.idle_timeout = self.heartbeat
@@ -623,19 +622,50 @@ class Container(Reactor):
             self.container_id = str(generate_uuid())
             self.allow_insecure_mechs = True
             self.allowed_mechs = None
+            self.sasl_enabled = True
             Wrapper.__setattr__(self, 'subclass', self.__class__)
 
-    def connect(self, url=None, urls=None, address=None, handler=None, reconnect=None, heartbeat=None, ssl_domain=None):
+    def connect(self, url=None, urls=None, address=None, handler=None, reconnect=None, heartbeat=None, ssl_domain=None, **kwargs):
         """
         Initiates the establishment of an AMQP connection. Returns an
         instance of proton.Connection.
+
+        @param url: URL string of process to connect to
+
+        @param urls: list of URL strings of process to try to connect to
+
+        Only one of url or urls should be specified.
+
+        @param reconnect: A value of False will prevent the library
+        form automatically trying to reconnect if the underlying
+        socket is disconnected before the connection has been closed.
+
+        @param heartbeat: A value in milliseconds indicating the
+        desired frequency of heartbeats used to test the underlying
+        socket is alive.
+
+        @param ssl_domain: SSL configuration in the form of an
+        instance of proton.SSLdomain.
+
+        @param handler: a connection scoped handler that will be
+        called to process any events in the scope of this connection
+        or its child links
+
+        @param kwargs: sasl_enabled, which determines whether a sasl
+        layer is used for the connection; allowed_mechs an optional
+        list of SASL mechanisms to allow if sasl is enabled;
+        allow_insecure_mechs a flag indicating whether insecure
+        mechanisms, such as PLAIN over a non-encrypted socket, are
+        allowed. These options can also be set at container scope.
+
         """
         conn = self.connection(handler)
         conn.container = self.container_id or str(generate_uuid())
 
         connector = Connector(conn)
-        connector.allow_insecure_mechs = self.allow_insecure_mechs
-        connector.allowed_mechs = self.allowed_mechs
+        connector.allow_insecure_mechs = kwargs.get('allow_insecure_mechs', self.allow_insecure_mechs)
+        connector.allowed_mechs = kwargs.get('allowed_mechs', self.allowed_mechs)
+        connector.sasl_enabled = kwargs.get('sasl_enabled', self.sasl_enabled)
         conn._overrides = connector
         if url: connector.address = Urls([url])
         elif urls: connector.address = Urls(urls)


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


[08/50] [abbrv] qpid-proton git commit: PROTON-1011: Go example of event driven broker. Package renaming and some new features.

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go b/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
new file mode 100644
index 0000000..92c0b90
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/receiver.go
@@ -0,0 +1,232 @@
+/*
+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
+
+import (
+	"qpid.apache.org/internal"
+	"qpid.apache.org/proton"
+	"qpid.apache.org/amqp"
+	"sync"
+	"time"
+)
+
+// Receiver is a Link that receives messages.
+//
+type Receiver interface {
+	Link
+
+	// Receive blocks until a message is available or until the Receiver is closed
+	// and has no more buffered messages.
+	Receive() (ReceivedMessage, error)
+
+	// ReceiveTimeout is like Receive but gives up after timeout, see Timeout.
+	//
+	// Note that that if Prefetch is false, after a Timeout the credit issued by
+	// Receive remains on the link. It will be used by the next call to Receive.
+	ReceiveTimeout(timeout time.Duration) (ReceivedMessage, error)
+
+	// Prefetch==true means the Receiver will automatically issue credit to the
+	// remote sender to keep its buffer as full as possible, i.e. it will
+	// "pre-fetch" messages independently of the application calling
+	// Receive(). This gives good throughput for applications that handle a
+	// continuous stream of messages. Larger capacity may improve throughput, the
+	// optimal value depends on the characteristics of your application.
+	//
+	// Prefetch==false means the Receiver will issue only issue credit when you
+	// call Receive(), and will only issue enough credit to satisfy the calls
+	// actually made. This gives lower throughput but will not fetch any messages
+	// in advance. It is good for synchronous applications that need to evaluate
+	// each message before deciding whether to receive another. The
+	// request-response pattern is a typical example.  If you make concurrent
+	// calls to Receive with pre-fetch disabled, you can improve performance by
+	// setting the capacity close to the expected number of concurrent calls.
+	//
+	Prefetch() bool
+
+	// Capacity is the size (number of messages) of the local message buffer
+	// These are messages received but not yet returned to the application by a call to Receive()
+	Capacity() int
+
+	// SetCapacity sets Capacity and Prefetch of an accepted Receiver.
+	// May only be called in an accept() function, see Connection.Listen()
+	SetCapacity(capacity int, prefetch bool)
+}
+
+// Flow control policy for a receiver.
+type policy interface {
+	// Called at the start of Receive() to adjust credit before fetching a message.
+	Pre(*receiver)
+	// Called after Receive() has received a message from Buffer() before it returns.
+	// Non-nil error means no message was received because of an error.
+	Post(*receiver, error)
+}
+
+type prefetchPolicy struct{}
+
+func (p prefetchPolicy) Flow(r *receiver) {
+	r.engine().Inject(func() {
+		_, _, max := r.credit()
+		if max > 0 {
+			r.eLink.Flow(max)
+		}
+	})
+}
+func (p prefetchPolicy) Pre(r *receiver) { p.Flow(r) }
+func (p prefetchPolicy) Post(r *receiver, err error) {
+	if err == nil {
+		p.Flow(r)
+	}
+}
+
+type noPrefetchPolicy struct{ waiting int }
+
+func (p noPrefetchPolicy) Flow(r *receiver) { // Not called in proton goroutine
+	r.engine().Inject(func() {
+		len, credit, max := r.credit()
+		add := p.waiting - (len + credit)
+		if add > max {
+			add = max // Don't overflow
+		}
+		if add > 0 {
+			r.eLink.Flow(add)
+		}
+	})
+}
+func (p noPrefetchPolicy) Pre(r *receiver) { p.waiting++; p.Flow(r) }
+func (p noPrefetchPolicy) Post(r *receiver, err error) {
+	p.waiting--
+	if err == nil {
+		p.Flow(r)
+	}
+}
+
+// Receiver implementation
+type receiver struct {
+	link
+	buffer    chan ReceivedMessage
+	policy    policy
+	setupOnce sync.Once
+}
+
+func (r *receiver) SetCapacity(capacity int, prefetch bool) {
+	internal.Assert(r.inAccept, "Receiver.SetCapacity called outside of accept function")
+	r.capacity = capacity
+	r.prefetch = prefetch
+}
+
+func (r *receiver) setup() {
+	if r.capacity < 1 {
+		r.capacity = 1
+	}
+	if r.prefetch {
+		r.policy = &prefetchPolicy{}
+	} else {
+		r.policy = &noPrefetchPolicy{}
+	}
+	r.buffer = make(chan ReceivedMessage, r.capacity)
+}
+
+// call in proton goroutine.
+func (r *receiver) credit() (buffered, credit, max int) {
+	return len(r.buffer), r.eLink.Credit(), cap(r.buffer) - len(r.buffer)
+}
+
+func (r *receiver) Capacity() int  { return cap(r.buffer) }
+func (r *receiver) Prefetch() bool { return r.prefetch }
+
+func (r *receiver) Receive() (rm ReceivedMessage, err error) {
+	return r.ReceiveTimeout(Forever)
+}
+
+func (r *receiver) ReceiveTimeout(timeout time.Duration) (rm ReceivedMessage, err error) {
+	r.setupOnce.Do(r.setup)
+	internal.Assert(r.buffer != nil, "Receiver is not open: %s", r)
+	r.policy.Pre(r)
+	defer func() { r.policy.Post(r, err) }()
+	rmi, ok, timedout := timedReceive(r.buffer, timeout)
+	switch {
+	case timedout:
+		return ReceivedMessage{}, Timeout
+	case !ok:
+		return ReceivedMessage{}, r.Error()
+	default:
+		return rmi.(ReceivedMessage), nil
+	}
+}
+
+// Called in proton goroutine on MMessage event.
+func (r *receiver) message(delivery proton.Delivery) {
+	if r.eLink.State().RemoteClosed() {
+		localClose(r.eLink, r.eLink.RemoteCondition().Error())
+		return
+	}
+	if delivery.HasMessage() {
+		m, err := delivery.Message()
+		if err != nil {
+			localClose(r.eLink, err)
+			return
+		}
+		internal.Assert(m != nil)
+		r.eLink.Advance()
+		if r.eLink.Credit() < 0 {
+			localClose(r.eLink, internal.Errorf("received message in excess of credit limit"))
+		} else {
+			// We never issue more credit than cap(buffer) so this will not block.
+			r.buffer <- ReceivedMessage{m, delivery, r}
+		}
+	}
+}
+
+func (r *receiver) open() {
+	r.setupOnce.Do(r.setup)
+	r.link.open()
+	r.handler().addLink(r.eLink, r)
+}
+
+func (r *receiver) closed(err error) {
+	r.link.closed(err)
+	if r.buffer != nil {
+		close(r.buffer)
+	}
+}
+
+// ReceivedMessage contains an amqp.Message and allows the message to be acknowledged.
+type ReceivedMessage struct {
+	// Message is the received message.
+	Message amqp.Message
+
+	eDelivery proton.Delivery
+	receiver  Receiver
+}
+
+// Acknowledge a ReceivedMessage with the given disposition code.
+func (rm *ReceivedMessage) Acknowledge(disposition Disposition) error {
+	return rm.receiver.(*receiver).engine().InjectWait(func() error {
+		// Settle doesn't return an error but if the receiver is broken the settlement won't happen.
+		rm.eDelivery.SettleAs(uint64(disposition))
+		return rm.receiver.Error()
+	})
+}
+
+// Accept is short for Acknowledge(Accpeted)
+func (rm *ReceivedMessage) Accept() error { return rm.Acknowledge(Accepted) }
+
+// Reject is short for Acknowledge(Rejected)
+func (rm *ReceivedMessage) Reject() error { return rm.Acknowledge(Rejected) }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go b/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
new file mode 100644
index 0000000..3124f74
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/sender.go
@@ -0,0 +1,319 @@
+/*
+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
+
+// #include <proton/disposition.h>
+import "C"
+
+import (
+	"container/list"
+	"qpid.apache.org/internal"
+	"qpid.apache.org/proton"
+	"qpid.apache.org/amqp"
+	"reflect"
+	"time"
+)
+
+// Sender is a Link that sends messages.
+type Sender interface {
+	Link
+
+	// Send a message without waiting for acknowledgement. Returns a SentMessage.
+	// use SentMessage.Disposition() to wait for acknowledgement and get the
+	// disposition code.
+	//
+	// If the send buffer is full, send blocks until there is space in the buffer.
+	Send(m amqp.Message) (sm SentMessage, err error)
+
+	// SendTimeout is like send but only waits up to timeout for buffer space.
+	//
+	// Returns Timeout error if the timeout expires and the message has not been sent.
+	SendTimeout(m amqp.Message, timeout time.Duration) (sm SentMessage, err error)
+
+	// Send a message and forget it, there will be no acknowledgement.
+	// If the send buffer is full, send blocks until there is space in the buffer.
+	SendForget(m amqp.Message) error
+
+	// SendForgetTimeout is like send but only waits up to timeout for buffer space.
+	// Returns Timeout error if the timeout expires and the message has not been sent.
+	SendForgetTimeout(m amqp.Message, timeout time.Duration) error
+
+	// Credit indicates how many messages the receiving end of the link can accept.
+	//
+	// On a Sender credit can be negative, meaning that messages in excess of the
+	// receiver's credit limit have been buffered locally till credit is available.
+	Credit() (int, error)
+}
+
+type sendMessage struct {
+	m  amqp.Message
+	sm SentMessage
+}
+
+type sender struct {
+	link
+	blocked list.List // Channel of sendMessage for blocked senders.
+}
+
+// Disposition indicates the outcome of a settled message delivery.
+type Disposition uint64
+
+const (
+	// No disposition available: pre-settled, not yet acknowledged or an error occurred
+	NoDisposition Disposition = 0
+	// Message was accepted by the receiver
+	Accepted = proton.Accepted
+	// Message was rejected as invalid by the receiver
+	Rejected = proton.Rejected
+	// Message was not processed by the receiver but may be processed by some other receiver.
+	Released = proton.Released
+)
+
+// String human readable name for a Disposition.
+func (d Disposition) String() string {
+	switch d {
+	case NoDisposition:
+		return "no-disposition"
+	case Accepted:
+		return "accepted"
+	case Rejected:
+		return "rejected"
+	case Released:
+		return "released"
+	default:
+		return "unknown"
+	}
+}
+
+// Send a message, assumes there is credit
+func (s *sender) doSend(snd sendMessage) {
+	delivery, err := s.eLink.Send(snd.m)
+	switch sm := snd.sm.(type) {
+	case nil:
+		delivery.Settle()
+	case *sentMessage:
+		sm.delivery = delivery
+		if err != nil {
+			sm.settled(err)
+		} else {
+			s.handler().sentMessages[delivery] = sm
+		}
+	default:
+		internal.Assert(false, "bad SentMessage type %T", snd.sm)
+	}
+}
+
+func (s *sender) popBlocked() chan sendMessage {
+	if s.blocked.Len() > 0 {
+		return s.blocked.Remove(s.blocked.Front()).(chan sendMessage)
+	}
+	return nil
+}
+
+func (s *sender) Send(m amqp.Message) (SentMessage, error) {
+	return s.SendTimeout(m, Forever)
+}
+
+func (s *sender) SendTimeout(m amqp.Message, timeout time.Duration) (SentMessage, error) {
+	var sm SentMessage
+	if s.sndSettle == SndSettled {
+		sm = nil
+	} else {
+		sm = newSentMessage(s.session.connection)
+	}
+	return s.sendInternal(sendMessage{m, sm}, timeout)
+}
+
+func (s *sender) SendForget(m amqp.Message) error {
+	return s.SendForgetTimeout(m, Forever)
+}
+
+func (s *sender) SendForgetTimeout(m amqp.Message, timeout time.Duration) error {
+	snd := sendMessage{m, nil}
+	_, err := s.sendInternal(snd, timeout)
+	return err
+}
+
+func (s *sender) sendInternal(snd sendMessage, timeout time.Duration) (SentMessage, error) {
+	if s.Error() != nil {
+		return nil, s.Error()
+	}
+	var err error
+	if timeout == 0 {
+		err = s.engine().InjectWait(func() error {
+			if s.eLink.Credit() > 0 {
+				s.doSend(snd)
+				return nil
+			}
+			return Timeout
+		})
+	} else {
+		buf := make(chan sendMessage)
+		done := make(chan struct{})
+		defer close(buf)
+		s.engine().Inject(func() { // Runs concurrently
+			if s.eLink.Credit() > 0 {
+				s.doSend(snd)
+				close(done) // Signal already sent
+			} else {
+				s.blocked.PushBack(buf)
+			}
+		})
+		select {
+		case <-done: // Sent without blocking
+		case buf <- snd: // Sent via blocking channel
+		case <-s.done:
+			err = s.Error()
+		case <-After(timeout):
+			err = Timeout
+		}
+	}
+	if err != nil {
+		return nil, err
+	}
+	return snd.sm, nil
+}
+
+func (s *sender) closed(err error) {
+	s.link.closed(err)
+}
+
+func (s *sender) open() {
+	s.link.open()
+	s.handler().addLink(s.eLink, s)
+}
+
+// SentMessage represents a previously sent message. It allows you to wait for acknowledgement.
+type SentMessage interface {
+
+	// Disposition blocks till the message is acknowledged and returns the
+	// disposition state.
+	//
+	// NoDisposition with Error() != nil means the Connection was closed before
+	// the message was acknowledged.
+	//
+	// NoDisposition with Error() == nil means the message was pre-settled or
+	// Forget() was called.
+	Disposition() (Disposition, error)
+
+	// DispositionTimeout is like Disposition but gives up after timeout, see Timeout.
+	DispositionTimeout(time.Duration) (Disposition, error)
+
+	// Forget interrupts any call to Disposition on this SentMessage and tells the
+	// peer we are no longer interested in the disposition of this message.
+	Forget()
+
+	// Error returns the error that closed the disposition, or nil if there was no error.
+	// If the disposition closed because the connection closed, it will return Closed.
+	Error() error
+
+	// Value is an optional value you wish to associate with the SentMessage. It
+	// can be the message itself or some form of identifier.
+	Value() interface{}
+	SetValue(interface{})
+}
+
+// SentMessageSet is a concurrent-safe set of sent messages that can be checked
+// to get the next completed sent message
+type SentMessageSet struct {
+	cases []reflect.SelectCase
+	sm    []SentMessage
+	done  chan SentMessage
+}
+
+func (s *SentMessageSet) Add(sm SentMessage) {
+	s.sm = append(s.sm, sm)
+	s.cases = append(s.cases, reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sm.(*sentMessage).done)})
+}
+
+// Wait waits up to timeout and returns the next SentMessage that has a valid dispositionb
+// or an error.
+func (s *SentMessageSet) Wait(sm SentMessage, timeout time.Duration) (SentMessage, error) {
+	s.cases = s.cases[:len(s.sm)] // Remove previous timeout cases
+	if timeout == 0 {             // Non-blocking
+		s.cases = append(s.cases, reflect.SelectCase{Dir: reflect.SelectDefault})
+	} else {
+		s.cases = append(s.cases,
+			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(After(timeout))})
+	}
+	chosen, _, _ := reflect.Select(s.cases)
+	if chosen > len(s.sm) {
+		return nil, Timeout
+	} else {
+		sm := s.sm[chosen]
+		s.sm = append(s.sm[:chosen], s.sm[chosen+1:]...)
+		return sm, nil
+	}
+}
+
+// SentMessage implementation
+type sentMessage struct {
+	connection  *connection
+	done        chan struct{}
+	delivery    proton.Delivery
+	disposition Disposition
+	err         error
+	value       interface{}
+}
+
+func newSentMessage(c *connection) *sentMessage {
+	return &sentMessage{connection: c, done: make(chan struct{})}
+}
+
+func (sm *sentMessage) SetValue(v interface{}) { sm.value = v }
+func (sm *sentMessage) Value() interface{}     { return sm.value }
+func (sm *sentMessage) Disposition() (Disposition, error) {
+	<-sm.done
+	return sm.disposition, sm.err
+}
+
+func (sm *sentMessage) DispositionTimeout(timeout time.Duration) (Disposition, error) {
+	if _, _, timedout := timedReceive(sm.done, timeout); timedout {
+		return sm.disposition, Timeout
+	} else {
+		return sm.disposition, sm.err
+	}
+}
+
+func (sm *sentMessage) Forget() {
+	sm.connection.engine.Inject(func() {
+		sm.delivery.Settle()
+		delete(sm.connection.handler.sentMessages, sm.delivery)
+	})
+	sm.finish()
+}
+
+func (sm *sentMessage) settled(err error) {
+	if sm.delivery.Settled() {
+		sm.disposition = Disposition(sm.delivery.Remote().Type())
+	}
+	sm.err = err
+	sm.finish()
+}
+
+func (sm *sentMessage) finish() {
+	select {
+	case <-sm.done: // No-op if already closed
+	default:
+		close(sm.done)
+	}
+}
+
+func (sm *sentMessage) Error() error { return sm.err }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/session.go b/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
new file mode 100644
index 0000000..612658a
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/session.go
@@ -0,0 +1,98 @@
+/*
+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
+
+import (
+	"qpid.apache.org/proton"
+)
+
+// Session is an AMQP session, it contains Senders and Receivers.
+//
+type Session interface {
+	Endpoint
+
+	// Sender opens a new sender. v can be a string, which is used as the Target
+	// address, or a SenderSettings struct containing more details settings.
+	Sender(...LinkSetting) (Sender, error)
+
+	// Receiver opens a new Receiver. v can be a string, which is used as the
+	// Source address, or a ReceiverSettings struct containing more details
+	// settings.
+	Receiver(...LinkSetting) (Receiver, error)
+
+	// SetCapacity sets the session buffer capacity in bytes.
+	// Only has effect if called in an accept() function, see Connection.Listen()
+	SetCapacity(bytes uint)
+}
+
+type session struct {
+	endpoint
+	eSession   proton.Session
+	connection *connection
+	capacity   uint
+}
+
+// in proton goroutine
+func newSession(c *connection, es proton.Session) *session {
+	return &session{
+		connection: c,
+		eSession:   es,
+		endpoint:   endpoint{str: es.String()},
+	}
+}
+
+func (s *session) Connection() Connection     { return s.connection }
+func (s *session) eEndpoint() proton.Endpoint { return s.eSession }
+func (s *session) engine() *proton.Engine     { return s.connection.engine }
+func (s *session) Close(err error) {
+	s.engine().Inject(func() { localClose(s.eSession, err) })
+}
+
+func (s *session) SetCapacity(bytes uint) { s.capacity = bytes }
+
+func (s *session) Sender(setting ...LinkSetting) (snd Sender, err error) {
+	err = s.engine().InjectWait(func() error {
+		l, err := localLink(s, true, setting...)
+		if err == nil {
+			snd = &sender{link: *l}
+			snd.(*sender).open()
+		}
+		return err
+	})
+	return
+}
+
+func (s *session) Receiver(setting ...LinkSetting) (rcv Receiver, err error) {
+	err = s.engine().InjectWait(func() error {
+		l, err := localLink(s, false, setting...)
+		if err == nil {
+			rcv = &receiver{link: *l}
+			rcv.(*receiver).open()
+		}
+		return err
+	})
+	return
+}
+
+// Called from handler on closed.
+func (s *session) closed(err error) {
+	s.err.Set(err)
+	s.err.Set(Closed)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/time.go b/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
new file mode 100644
index 0000000..ee61332
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/time.go
@@ -0,0 +1,81 @@
+/*
+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
+
+import (
+	"qpid.apache.org/internal"
+	"reflect"
+	"time"
+)
+
+// Timeout is the error returned if an operation does not complete on time.
+//
+// Methods named *Timeout in this package take time.Duration timeout parameter.
+//
+// If timeout > 0 and there is no result available before the timeout, they
+// return a zero or nil value and Timeout as an error.
+//
+// If timeout == 0 they will return a result if one is immediatley available or
+// nil/zero and Timeout as an error if not.
+//
+// If timeout == Forever the function will return only when there is a result or
+// some non-timeout error occurs.
+//
+var Timeout = internal.Errorf("timeout")
+
+// Forever can be used as a timeout parameter to indicate wait forever.
+const Forever time.Duration = -1
+
+// timedReceive receives on channel (which can be a chan of any type), waiting
+// up to timeout.
+//
+// timeout==0 means do a non-blocking receive attempt. timeout < 0 means block
+// forever. Other values mean block up to the timeout.
+//
+func timedReceive(channel interface{}, timeout time.Duration) (value interface{}, ok bool, timedout bool) {
+	cases := []reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(channel)},
+	}
+	switch {
+	case timeout == 0: // Non-blocking receive
+		cases = append(cases, reflect.SelectCase{Dir: reflect.SelectDefault})
+	case timeout == Forever: // Block forever, nothing to add
+	default: // Block up to timeout
+		cases = append(cases,
+			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(time.After(timeout))})
+	}
+	chosen, recv, recvOk := reflect.Select(cases)
+	switch {
+	case chosen == 0:
+		return recv.Interface(), recvOk, false
+	default:
+		return nil, false, true
+	}
+}
+
+// After is like time.After but returns a nil channel if timeout == Forever
+// since selecting on a nil channel will never return.
+func After(timeout time.Duration) <-chan time.Time {
+	if timeout == Forever {
+		return nil
+	} else {
+		return time.After(timeout)
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/internal/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/internal/error.go b/proton-c/bindings/go/src/qpid.apache.org/internal/error.go
new file mode 100644
index 0000000..1b108e6
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/internal/error.go
@@ -0,0 +1,118 @@
+/*
+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 internal
+
+// #cgo LDFLAGS: -lqpid-proton
+// #include <proton/error.h>
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"fmt"
+	"sync"
+	"sync/atomic"
+	"unsafe"
+)
+
+// Error type for proton runtime errors returned as error values.
+type Error string
+
+// Error prefixes error message with proton:
+func (e Error) Error() string {
+	return "proton: " + string(e)
+}
+
+// Errorf creates an Error with a formatted message
+func Errorf(format string, a ...interface{}) Error {
+	return Error(fmt.Sprintf(format, a...))
+}
+
+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(p unsafe.Pointer) error {
+	e := (*C.pn_error_t)(p)
+	if e == nil || C.pn_error_code(e) == 0 {
+		return nil
+	}
+	return Errorf("%s: %s", PnErrorCode(C.pn_error_code(e)), C.GoString(C.pn_error_text(e)))
+}
+
+// panicIf panics if condition is true, the panic value is Errorf(fmt, args...)
+func panicIf(condition bool, fmt string, args ...interface{}) {
+	if condition {
+		panic(Errorf(fmt, args...))
+	}
+}
+
+// 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(Errorf(format[0].(string), format[1:]...))
+		} else {
+			panic(Errorf("assertion failed"))
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel.go b/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel.go
new file mode 100644
index 0000000..77b524c
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel.go
@@ -0,0 +1,82 @@
+/*
+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 internal
+
+// FlexChannel acts like a channel with an automatically sized buffer, see NewFlexChannel().
+type FlexChannel struct {
+	// In channel to send to. close(In) will close the FlexChannel once buffer has drained.
+	In chan<- interface{}
+	// Out channel to receive from. Out closes when In has closed and the buffer is empty.
+	Out <-chan interface{}
+
+	in, out chan interface{}
+	buffer  []interface{}
+	limit   int
+}
+
+// NewFlexChannel creates a FlexChannel, a channel with an automatically-sized buffer.
+//
+// Initially the buffer size is 0, the buffer grows as needed up to limit. limit < 0 means
+// there is no limit.
+//
+func NewFlexChannel(limit int) *FlexChannel {
+	fc := &FlexChannel{
+		in:     make(chan interface{}),
+		out:    make(chan interface{}),
+		buffer: make([]interface{}, 0),
+		limit:  limit,
+	}
+	fc.In = fc.in
+	fc.Out = fc.out
+	go fc.run()
+	return fc
+}
+
+func (fc *FlexChannel) run() {
+	defer func() { // Flush the channel on exit
+		for _, data := range fc.buffer {
+			fc.out <- data
+		}
+		close(fc.out)
+	}()
+
+	for {
+		var usein, useout chan interface{}
+		var outvalue interface{}
+		if len(fc.buffer) > 0 {
+			useout = fc.out
+			outvalue = fc.buffer[0]
+		}
+		if len(fc.buffer) < fc.limit || fc.limit < 0 {
+			usein = fc.in
+		}
+		Assert(usein != nil || useout != nil)
+		select {
+		case useout <- outvalue:
+			fc.buffer = fc.buffer[1:]
+		case data, ok := <-usein:
+			if ok {
+				fc.buffer = append(fc.buffer, data)
+			} else {
+				return
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel_test.go b/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel_test.go
new file mode 100644
index 0000000..d0e1a44
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/internal/flexchannel_test.go
@@ -0,0 +1,89 @@
+/*
+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 internal
+
+import (
+	"testing"
+)
+
+func recvall(ch <-chan interface{}) (result []interface{}) {
+	for {
+		select {
+		case x := <-ch:
+			result = append(result, x)
+		default:
+			return
+		}
+	}
+}
+
+func sendall(data []interface{}, ch chan<- interface{}) {
+}
+
+func TestFlex(t *testing.T) {
+	fc := NewFlexChannel(5)
+
+	// Test send/receve
+	go func() {
+		for i := 0; i < 4; i++ {
+			fc.In <- i
+		}
+	}()
+
+	for i := 0; i < 4; i++ {
+		j := <-fc.Out
+		if i != j {
+			t.Error("%v != %v", i, j)
+		}
+	}
+	select {
+	case x, ok := <-fc.Out:
+		t.Error("receive empty channel got", x, ok)
+	default:
+	}
+
+	// Test buffer limit
+	for i := 10; i < 15; i++ {
+		fc.In <- i
+	}
+	select {
+	case fc.In <- 0:
+		t.Error("send to full channel did not block")
+	default:
+	}
+	i := <-fc.Out
+	if i != 10 {
+		t.Error("%v != %v", i, 10)
+	}
+	fc.In <- 15
+	close(fc.In)
+
+	for i := 11; i < 16; i++ {
+		j := <-fc.Out
+		if i != j {
+			t.Error("%v != %v", i, j)
+		}
+	}
+
+	x, ok := <-fc.Out
+	if ok {
+		t.Error("Unexpected value on Out", x)
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/internal/safemap.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/internal/safemap.go b/proton-c/bindings/go/src/qpid.apache.org/internal/safemap.go
new file mode 100644
index 0000000..3a1fe2b
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/internal/safemap.go
@@ -0,0 +1,57 @@
+/*
+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 internal
+
+import (
+	"sync"
+)
+
+// SafeMap is a goroutine-safe map of interface{} to interface{}.
+type SafeMap struct {
+	m    map[interface{}]interface{}
+	lock sync.Mutex
+}
+
+func MakeSafeMap() SafeMap { return SafeMap{m: make(map[interface{}]interface{})} }
+
+func (m *SafeMap) Get(key interface{}) interface{} {
+	m.lock.Lock()
+	defer m.lock.Unlock()
+	return m.m[key]
+}
+
+func (m *SafeMap) GetOk(key interface{}) (interface{}, bool) {
+	m.lock.Lock()
+	defer m.lock.Unlock()
+	v, ok := m.m[key]
+	return v, ok
+}
+
+func (m *SafeMap) Put(key, value interface{}) {
+	m.lock.Lock()
+	defer m.lock.Unlock()
+	m.m[key] = value
+}
+
+func (m *SafeMap) Delete(key interface{}) {
+	m.lock.Lock()
+	defer m.lock.Unlock()
+	delete(m.m, key)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/internal/uuid.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/internal/uuid.go b/proton-c/bindings/go/src/qpid.apache.org/internal/uuid.go
new file mode 100644
index 0000000..ef941a1
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/internal/uuid.go
@@ -0,0 +1,70 @@
+/*
+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 internal
+
+import (
+	"fmt"
+	"math/rand"
+	"strconv"
+	"sync"
+	"sync/atomic"
+	"time"
+)
+
+type UUID [16]byte
+
+func (u UUID) String() string {
+	return fmt.Sprintf("%X-%X-%X-%X-%X", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
+}
+
+// Don't mess with the default random source.
+var randomSource = rand.NewSource(time.Now().UnixNano())
+var randomLock sync.Mutex
+
+func random() byte {
+	randomLock.Lock()
+	defer randomLock.Unlock()
+	return byte(randomSource.Int63())
+}
+
+func UUID4() UUID {
+	var u UUID
+	for i := 0; i < len(u); i++ {
+		u[i] = random()
+	}
+	// See /https://tools.ietf.org/html/rfc4122#section-4.4
+	u[6] = (u[6] & 0x0F) | 0x40 // Version bits to 4
+	u[8] = (u[8] & 0x3F) | 0x80 // Reserved bits (top two) set to 01
+	return u
+}
+
+// A simple atomic counter to generate unique 64 bit IDs.
+type IdCounter struct{ count uint64 }
+
+// NextInt gets the next uint64 value from the atomic counter.
+func (uc *IdCounter) NextInt() uint64 {
+	return atomic.AddUint64(&uc.count, 1)
+}
+
+// Next gets the next integer value encoded as a base32 string, safe for NUL
+// terminated C strings.
+func (uc *IdCounter) Next() string {
+	return strconv.FormatUint(uc.NextInt(), 32)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/README.md b/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
deleted file mode 100644
index ad57b47..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Go binding for proton
-
-This is a a [Go](http://golang.org) binding for proton.
-Package documentation is available at: <http://godoc.org/qpid.apache.org/proton>
-
-See the [examples](https://github.com/apache/qpid-proton/blob/master/examples/cpp/README.md)
-for working examples and practical instructions on how to get started.
-
-Feedback is encouraged at:
-
-- Email <pr...@qpid.apache.org>
-- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/doc.go
deleted file mode 100644
index cc2cd0e..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/doc.go
+++ /dev/null
@@ -1,34 +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.
-*/
-
-/*
-Package amqp encodes and decodes AMQP messages and data 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.
-
-AMQP is an open standard for inter-operable message exchange, see <http://www.amqp.org/>
-*/
-package amqp
-
-// #cgo LDFLAGS: -lqpid-proton
-import "C"
-
-// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/error.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/error.go
deleted file mode 100644
index 868dbf3..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/error.go
+++ /dev/null
@@ -1,66 +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.
-*/
-
-package amqp
-
-import (
-	"fmt"
-	"reflect"
-)
-
-// Error is an AMQP error condition. It has a name and a description.
-// It implements the Go error interface so can be returned as an error value.
-//
-// You can pass amqp.Error to methods that pass an error to a remote endpoint,
-// this gives you full control over what the remote endpoint will see.
-//
-// You can also pass any Go error to such functions, the remote peer
-// will see the equivalent of MakeError(error)
-//
-type Error struct{ Name, Description string }
-
-// Error implements the Go error interface for AMQP error errors.
-func (c Error) Error() string { return fmt.Sprintf("proton %s: %s", c.Name, c.Description) }
-
-// Errorf makes a Error with name and formatted description as per fmt.Sprintf
-func Errorf(name, format string, arg ...interface{}) Error {
-	return Error{name, fmt.Sprintf(format, arg...)}
-}
-
-// MakeError makes an AMQP error from a go error using the Go error type as the name
-// and the err.Error() string as the description.
-func MakeError(err error) Error {
-	return Error{reflect.TypeOf(err).Name(), err.Error()}
-}
-
-var (
-	InternalError      = "amqp:internal-error"
-	NotFound           = "amqp:not-found"
-	UnauthorizedAccess = "amqp:unauthorized-access"
-	DecodeError        = "amqp:decode-error"
-	ResourceLimit      = "amqp:resource-limit"
-	NotAllowed         = "amqp:not-allowed"
-	InvalidField       = "amqp:invalid-field"
-	NotImplemented     = "amqp:not-implemented"
-	ResourceLocked     = "amqp:resource-locked"
-	PreerrorFailed     = "amqp:preerror-failed"
-	ResourceDeleted    = "amqp:resource-deleted"
-	IllegalState       = "amqp:illegal-state"
-	FrameSizeTooSmall  = "amqp:frame-size-too-small"
-)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop
deleted file mode 120000
index b2dd603..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../../tests/interop
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop_test.go
deleted file mode 100644
index b36ef64..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/interop_test.go
+++ /dev/null
@@ -1,381 +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 that conversion of Go type to/from AMQP is compatible with other
-// bindings.
-//
-package amqp
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-func checkEqual(want interface{}, got interface{}) error {
-	if !reflect.DeepEqual(want, got) {
-		return fmt.Errorf("%#v != %#v", want, got)
-	}
-	return nil
-}
-
-func getReader(name string) (r io.Reader) {
-	r, err := os.Open("interop/" + name + ".amqp")
-	if err != nil {
-		panic(fmt.Errorf("Can't open %#v: %v", name, err))
-	}
-	return
-}
-
-func remaining(d *Decoder) string {
-	remainder, _ := ioutil.ReadAll(io.MultiReader(d.Buffered(), d.reader))
-	return string(remainder)
-}
-
-// checkDecode: want is the expected value, gotPtr is a pointer to a
-// instance of the same type for Decode.
-func checkDecode(d *Decoder, want interface{}, gotPtr interface{}, t *testing.T) {
-
-	if err := d.Decode(gotPtr); err != nil {
-		t.Error("Decode failed", err)
-		return
-	}
-	got := reflect.ValueOf(gotPtr).Elem().Interface()
-	if err := checkEqual(want, got); err != nil {
-		t.Error("Decode bad value:", err)
-		return
-	}
-
-	// Try round trip encoding
-	bytes, err := Marshal(want, nil)
-	if err != nil {
-		t.Error("Marshal failed", err)
-		return
-	}
-	n, err := Unmarshal(bytes, gotPtr)
-	if err != nil {
-		t.Error("Unmarshal failed", err)
-		return
-	}
-	if err := checkEqual(n, len(bytes)); err != nil {
-		t.Error("Bad unmarshal length", err)
-		return
-	}
-	got = reflect.ValueOf(gotPtr).Elem().Interface()
-	if err = checkEqual(want, got); err != nil {
-		t.Error("Bad unmarshal value", err)
-		return
-	}
-}
-
-func TestUnmarshal(t *testing.T) {
-	bytes, err := ioutil.ReadAll(getReader("strings"))
-	if err != nil {
-		t.Error(err)
-	}
-	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
-		var got string
-		n, err := Unmarshal(bytes, &got)
-		if err != nil {
-			t.Error(err)
-		}
-		if want != got {
-			t.Errorf("%#v != %#v", want, got)
-		}
-		bytes = bytes[n:]
-	}
-}
-
-func TestPrimitivesExact(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	// Decoding into exact types
-	var b bool
-	checkDecode(d, true, &b, t)
-	checkDecode(d, false, &b, t)
-	var u8 uint8
-	checkDecode(d, uint8(42), &u8, t)
-	var u16 uint16
-	checkDecode(d, uint16(42), &u16, t)
-	var i16 int16
-	checkDecode(d, int16(-42), &i16, t)
-	var u32 uint32
-	checkDecode(d, uint32(12345), &u32, t)
-	var i32 int32
-	checkDecode(d, int32(-12345), &i32, t)
-	var u64 uint64
-	checkDecode(d, uint64(12345), &u64, t)
-	var i64 int64
-	checkDecode(d, int64(-12345), &i64, t)
-	var f32 float32
-	checkDecode(d, float32(0.125), &f32, t)
-	var f64 float64
-	checkDecode(d, float64(0.125), &f64, t)
-}
-
-func TestPrimitivesCompatible(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	// Decoding into compatible types
-	var b bool
-	var i int
-	var u uint
-	var f float64
-	checkDecode(d, true, &b, t)
-	checkDecode(d, false, &b, t)
-	checkDecode(d, uint(42), &u, t)
-	checkDecode(d, uint(42), &u, t)
-	checkDecode(d, -42, &i, t)
-	checkDecode(d, uint(12345), &u, t)
-	checkDecode(d, -12345, &i, t)
-	checkDecode(d, uint(12345), &u, t)
-	checkDecode(d, -12345, &i, t)
-	checkDecode(d, 0.125, &f, t)
-	checkDecode(d, 0.125, &f, t)
-}
-
-// checkDecodeValue: want is the expected value, decode into a reflect.Value
-func checkDecodeInterface(d *Decoder, want interface{}, t *testing.T) {
-
-	var got, got2 interface{}
-	if err := d.Decode(&got); err != nil {
-		t.Error("Decode failed", err)
-		return
-	}
-	if err := checkEqual(want, got); err != nil {
-		t.Error(err)
-		return
-	}
-	// Try round trip encoding
-	bytes, err := Marshal(got, nil)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	n, err := Unmarshal(bytes, &got2)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	if err := checkEqual(n, len(bytes)); err != nil {
-		t.Error(err)
-		return
-	}
-	if err := checkEqual(want, got2); err != nil {
-		t.Error(err)
-		return
-	}
-}
-
-func TestPrimitivesInterface(t *testing.T) {
-	d := NewDecoder(getReader("primitives"))
-	checkDecodeInterface(d, true, t)
-	checkDecodeInterface(d, false, t)
-	checkDecodeInterface(d, uint8(42), t)
-	checkDecodeInterface(d, uint16(42), t)
-	checkDecodeInterface(d, int16(-42), t)
-	checkDecodeInterface(d, uint32(12345), t)
-	checkDecodeInterface(d, int32(-12345), t)
-	checkDecodeInterface(d, uint64(12345), t)
-	checkDecodeInterface(d, int64(-12345), t)
-	checkDecodeInterface(d, float32(0.125), t)
-	checkDecodeInterface(d, float64(0.125), t)
-}
-
-func TestStrings(t *testing.T) {
-	d := NewDecoder(getReader("strings"))
-	// Test decoding as plain Go strings
-	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
-		var got string
-		checkDecode(d, want, &got, t)
-	}
-	remains := remaining(d)
-	if remains != "" {
-		t.Errorf("leftover: %s", remains)
-	}
-
-	// Test decoding as specific string types
-	d = NewDecoder(getReader("strings"))
-	var bytes []byte
-	var str, sym string
-	checkDecode(d, []byte("abc\000defg"), &bytes, t)
-	checkDecode(d, "abcdefg", &str, t)
-	checkDecode(d, "abcdefg", &sym, t)
-	checkDecode(d, make([]byte, 0), &bytes, t)
-	checkDecode(d, "", &str, t)
-	checkDecode(d, "", &sym, t)
-	remains = remaining(d)
-	if remains != "" {
-		t.Fatalf("leftover: %s", remains)
-	}
-
-	// Test some error handling
-	d = NewDecoder(getReader("strings"))
-	var s string
-	err := d.Decode(s)
-	if err == nil {
-		t.Fatal("Expected error")
-	}
-	if !strings.Contains(err.Error(), "not a pointer") {
-		t.Error(err)
-	}
-	var i int
-	err = d.Decode(&i)
-	if !strings.Contains(err.Error(), "cannot unmarshal") {
-		t.Error(err)
-	}
-	_, err = Unmarshal([]byte{}, nil)
-	if !strings.Contains(err.Error(), "not enough data") {
-		t.Error(err)
-	}
-	_, err = Unmarshal([]byte("foobar"), nil)
-	if !strings.Contains(err.Error(), "invalid-argument") {
-		t.Error(err)
-	}
-}
-
-func TestEncodeDecode(t *testing.T) {
-	type data struct {
-		s  string
-		i  int
-		u8 uint8
-		b  bool
-		f  float32
-		v  interface{}
-	}
-
-	in := data{"foo", 42, 9, true, 1.234, "thing"}
-
-	buf := bytes.Buffer{}
-	e := NewEncoder(&buf)
-	if err := e.Encode(in.s); err != nil {
-		t.Error(err)
-	}
-	if err := e.Encode(in.i); err != nil {
-		t.Error(err)
-	}
-	if err := e.Encode(in.u8); err != nil {
-		t.Error(err)
-	}
-	if err := e.Encode(in.b); err != nil {
-		t.Error(err)
-	}
-	if err := e.Encode(in.f); err != nil {
-		t.Error(err)
-	}
-	if err := e.Encode(in.v); err != nil {
-		t.Error(err)
-	}
-
-	var out data
-	d := NewDecoder(&buf)
-	if err := d.Decode(&out.s); err != nil {
-		t.Error(err)
-	}
-	if err := d.Decode(&out.i); err != nil {
-		t.Error(err)
-	}
-	if err := d.Decode(&out.u8); err != nil {
-		t.Error(err)
-	}
-	if err := d.Decode(&out.b); err != nil {
-		t.Error(err)
-	}
-	if err := d.Decode(&out.f); err != nil {
-		t.Error(err)
-	}
-	if err := d.Decode(&out.v); err != nil {
-		t.Error(err)
-	}
-
-	if err := checkEqual(in, out); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestMap(t *testing.T) {
-	d := NewDecoder(getReader("maps"))
-
-	// Generic map
-	var m Map
-	checkDecode(d, Map{"one": int32(1), "two": int32(2), "three": int32(3)}, &m, t)
-
-	// Interface as map
-	var i interface{}
-	checkDecode(d, Map{int32(1): "one", int32(2): "two", int32(3): "three"}, &i, t)
-
-	d = NewDecoder(getReader("maps"))
-	// Specific typed map
-	var m2 map[string]int
-	checkDecode(d, map[string]int{"one": 1, "two": 2, "three": 3}, &m2, t)
-
-	// Nested map
-	m = Map{int64(1): "one", "two": int32(2), true: Map{uint8(1): true, uint8(2): false}}
-	bytes, err := Marshal(m, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = Unmarshal(bytes, &i)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err = checkEqual(m, i); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestList(t *testing.T) {
-	d := NewDecoder(getReader("lists"))
-	var l List
-	checkDecode(d, List{int32(32), "foo", true}, &l, t)
-	checkDecode(d, List{}, &l, t)
-}
-
-// TODO aconway 2015-09-08: the message.amqp file seems to be incorrectly coded as
-// as an AMQP string *inside* an AMQP binary?? Skip the test for now.
-func TODO_TestMessage(t *testing.T) {
-	bytes, err := ioutil.ReadAll(getReader("message"))
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	m, err := DecodeMessage(bytes)
-	if err != nil {
-		t.Fatal(err)
-	} else {
-		if err := checkEqual(m.Body(), "hello"); err != nil {
-			t.Error(err)
-		}
-	}
-
-	m2 := NewMessageWith("hello")
-	bytes2, err := m2.Encode(nil)
-	if err != nil {
-		t.Error(err)
-	} else {
-		if err = checkEqual(bytes, bytes2); err != nil {
-			t.Error(err)
-		}
-	}
-}
-
-// TODO aconway 2015-03-13: finish the full interop test

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/marshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/marshal.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/marshal.go
deleted file mode 100644
index e393c97..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/marshal.go
+++ /dev/null
@@ -1,250 +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.
-*/
-
-package amqp
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"io"
-	"qpid.apache.org/proton/internal"
-	"reflect"
-	"unsafe"
-)
-
-func dataError(prefix string, data *C.pn_data_t) error {
-	err := internal.PnError(unsafe.Pointer(C.pn_data_error(data)))
-	if err != nil {
-		err = internal.Errorf("%s: %s", prefix, err.(internal.Error))
-	}
-	return err
-}
-
-/*
-Marshal encodes a Go value as AMQP data in buffer.
-If buffer is nil, or is not large enough, a new buffer  is created.
-
-Returns the buffer used for encoding with len() adjusted to the actual size of data.
-
-Go types are encoded as follows
-
- +-------------------------------------+--------------------------------------------+
- |Go type                              |AMQP type                                   |
- +-------------------------------------+--------------------------------------------+
- |bool                                 |bool                                        |
- +-------------------------------------+--------------------------------------------+
- |int8, int16, int32, int64 (int)      |byte, short, int, long (int or long)        |
- +-------------------------------------+--------------------------------------------+
- |uint8, uint16, uint32, uint64 (uint) |ubyte, ushort, uint, ulong (uint or ulong)  |
- +-------------------------------------+--------------------------------------------+
- |float32, float64                     |float, double.                              |
- +-------------------------------------+--------------------------------------------+
- |string                               |string                                      |
- +-------------------------------------+--------------------------------------------+
- |[]byte, Binary                       |binary                                      |
- +-------------------------------------+--------------------------------------------+
- |Symbol                               |symbol                                      |
- +-------------------------------------+--------------------------------------------+
- |interface{}                          |the contained type                          |
- +-------------------------------------+--------------------------------------------+
- |nil                                  |null                                        |
- +-------------------------------------+--------------------------------------------+
- |map[K]T                              |map with K and T converted as above         |
- +-------------------------------------+--------------------------------------------+
- |Map                                  |map, may have mixed types for keys, values  |
- +-------------------------------------+--------------------------------------------+
- |[]T                                  |list with T converted as above              |
- +-------------------------------------+--------------------------------------------+
- |List                                 |list, may have mixed types  values          |
- +-------------------------------------+--------------------------------------------+
-
-The following Go types cannot be marshaled: uintptr, function, interface, channel
-
-TODO
-
-Go types: array, slice, struct, complex64/128.
-
-AMQP types: decimal32/64/128, char, timestamp, uuid, array, multi-section message bodies.
-
-Described types.
-
-*/
-func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) {
-	defer doRecover(&err)
-	data := C.pn_data(0)
-	defer C.pn_data_free(data)
-	marshal(v, data)
-	encode := func(buf []byte) ([]byte, error) {
-		n := int(C.pn_data_encode(data, cPtr(buf), cLen(buf)))
-		switch {
-		case n == int(C.PN_OVERFLOW):
-			return buf, overflow
-		case n < 0:
-			return buf, dataError("marshal error", data)
-		default:
-			return buf[:n], nil
-		}
-	}
-	return encodeGrow(buffer, encode)
-}
-
-const minEncode = 256
-
-// overflow is returned when an encoding function can't fit data in the buffer.
-var overflow = internal.Errorf("buffer too small")
-
-// encodeFn encodes into buffer[0:len(buffer)].
-// Returns buffer with length adjusted for data encoded.
-// If buffer too small, returns overflow as error.
-type encodeFn func(buffer []byte) ([]byte, error)
-
-// encodeGrow calls encode() into buffer, if it returns overflow grows the buffer.
-// Returns the final buffer.
-func encodeGrow(buffer []byte, encode encodeFn) ([]byte, error) {
-	if buffer == nil || len(buffer) == 0 {
-		buffer = make([]byte, minEncode)
-	}
-	var err error
-	for buffer, err = encode(buffer); err == overflow; buffer, err = encode(buffer) {
-		buffer = make([]byte, 2*len(buffer))
-	}
-	return buffer, err
-}
-
-func marshal(v interface{}, data *C.pn_data_t) {
-	switch v := v.(type) {
-	case nil:
-		C.pn_data_put_null(data)
-	case bool:
-		C.pn_data_put_bool(data, C.bool(v))
-	case int8:
-		C.pn_data_put_byte(data, C.int8_t(v))
-	case int16:
-		C.pn_data_put_short(data, C.int16_t(v))
-	case int32:
-		C.pn_data_put_int(data, C.int32_t(v))
-	case int64:
-		C.pn_data_put_long(data, C.int64_t(v))
-	case int:
-		if unsafe.Sizeof(0) == 8 {
-			C.pn_data_put_long(data, C.int64_t(v))
-		} else {
-			C.pn_data_put_int(data, C.int32_t(v))
-		}
-	case uint8:
-		C.pn_data_put_ubyte(data, C.uint8_t(v))
-	case uint16:
-		C.pn_data_put_ushort(data, C.uint16_t(v))
-	case uint32:
-		C.pn_data_put_uint(data, C.uint32_t(v))
-	case uint64:
-		C.pn_data_put_ulong(data, C.uint64_t(v))
-	case uint:
-		if unsafe.Sizeof(0) == 8 {
-			C.pn_data_put_ulong(data, C.uint64_t(v))
-		} else {
-			C.pn_data_put_uint(data, C.uint32_t(v))
-		}
-	case float32:
-		C.pn_data_put_float(data, C.float(v))
-	case float64:
-		C.pn_data_put_double(data, C.double(v))
-	case string:
-		C.pn_data_put_string(data, pnBytes([]byte(v)))
-	case []byte:
-		C.pn_data_put_binary(data, pnBytes(v))
-	case Binary:
-		C.pn_data_put_binary(data, pnBytes([]byte(v)))
-	case Symbol:
-		C.pn_data_put_symbol(data, pnBytes([]byte(v)))
-	case Map: // Special map type
-		C.pn_data_put_map(data)
-		C.pn_data_enter(data)
-		for key, val := range v {
-			marshal(key, data)
-			marshal(val, data)
-		}
-		C.pn_data_exit(data)
-	default:
-		switch reflect.TypeOf(v).Kind() {
-		case reflect.Map:
-			putMap(data, v)
-		case reflect.Slice:
-			putList(data, v)
-		default:
-			panic(internal.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
-		}
-	}
-	err := dataError("marshal", data)
-	if err != nil {
-		panic(err)
-	}
-	return
-}
-
-func clearMarshal(v interface{}, data *C.pn_data_t) {
-	C.pn_data_clear(data)
-	marshal(v, data)
-}
-
-func putMap(data *C.pn_data_t, v interface{}) {
-	mapValue := reflect.ValueOf(v)
-	C.pn_data_put_map(data)
-	C.pn_data_enter(data)
-	for _, key := range mapValue.MapKeys() {
-		marshal(key.Interface(), data)
-		marshal(mapValue.MapIndex(key).Interface(), data)
-	}
-	C.pn_data_exit(data)
-}
-
-func putList(data *C.pn_data_t, v interface{}) {
-	listValue := reflect.ValueOf(v)
-	C.pn_data_put_list(data)
-	C.pn_data_enter(data)
-	for i := 0; i < listValue.Len(); i++ {
-		marshal(listValue.Index(i).Interface(), data)
-	}
-	C.pn_data_exit(data)
-}
-
-// Encoder encodes AMQP values to an io.Writer
-type Encoder struct {
-	writer io.Writer
-	buffer []byte
-}
-
-// New encoder returns a new encoder that writes to w.
-func NewEncoder(w io.Writer) *Encoder {
-	return &Encoder{w, make([]byte, minEncode)}
-}
-
-func (e *Encoder) Encode(v interface{}) (err error) {
-	e.buffer, err = Marshal(v, e.buffer)
-	if err == nil {
-		e.writer.Write(e.buffer)
-	}
-	return err
-}
-
-func replace(data *C.pn_data_t, v interface{}) {
-	C.pn_data_clear(data)
-	marshal(v, data)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message.go
deleted file mode 100644
index 20cfa02..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message.go
+++ /dev/null
@@ -1,347 +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.
-*/
-
-package amqp
-
-// #include <proton/types.h>
-// #include <proton/message.h>
-// #include <proton/codec.h>
-// #include <stdlib.h>
-//
-// /* Helper for setting message string fields */
-// typedef int (*set_fn)(pn_message_t*, const char*);
-// int msg_set_str(pn_message_t* m, char* s, set_fn set) {
-//     int result = set(m, s);
-//     free(s);
-//     return result;
-// }
-//
-import "C"
-
-import (
-	"qpid.apache.org/proton/internal"
-	"runtime"
-	"time"
-	"unsafe"
-)
-
-// Message is the interface to an AMQP message.
-type Message interface {
-	// Durable indicates that any parties taking responsibility
-	// for the message must durably store the content.
-	Durable() bool
-	SetDurable(bool)
-
-	// Priority impacts ordering guarantees. Within a
-	// given ordered context, higher priority messages may jump ahead of
-	// lower priority messages.
-	Priority() uint8
-	SetPriority(uint8)
-
-	// TTL or Time To Live, a message it may be dropped after this duration
-	TTL() time.Duration
-	SetTTL(time.Duration)
-
-	// FirstAcquirer indicates
-	// that the recipient of the message is the first recipient to acquire
-	// the message, i.e. there have been no failed delivery attempts to
-	// other acquirers. Note that this does not mean the message has not
-	// been delivered to, but not acquired, by other recipients.
-	FirstAcquirer() bool
-	SetFirstAcquirer(bool)
-
-	// DeliveryCount tracks how many attempts have been made to
-	// delivery a message.
-	DeliveryCount() uint32
-	SetDeliveryCount(uint32)
-
-	// MessageId provides a unique identifier for a message.
-	// it can be an a string, an unsigned long, a uuid or a
-	// binary value.
-	MessageId() interface{}
-	SetMessageId(interface{})
-
-	UserId() string
-	SetUserId(string)
-
-	Address() string
-	SetAddress(string)
-
-	Subject() string
-	SetSubject(string)
-
-	ReplyTo() string
-	SetReplyTo(string)
-
-	// CorrelationId is set on correlated request and response messages. It can be
-	// an a string, an unsigned long, a uuid or a binary value.
-	CorrelationId() interface{}
-	SetCorrelationId(interface{})
-
-	ContentType() string
-	SetContentType(string)
-
-	ContentEncoding() string
-	SetContentEncoding(string)
-
-	// ExpiryTime indicates an absoulte time when the message may be dropped.
-	// A Zero time (i.e. t.isZero() == true) indicates a message never expires.
-	ExpiryTime() time.Time
-	SetExpiryTime(time.Time)
-
-	CreationTime() time.Time
-	SetCreationTime(time.Time)
-
-	GroupId() string
-	SetGroupId(string)
-
-	GroupSequence() int32
-	SetGroupSequence(int32)
-
-	ReplyToGroupId() string
-	SetReplyToGroupId(string)
-
-	// Instructions - AMQP delivery instructions.
-	Instructions() map[string]interface{}
-	SetInstructions(v map[string]interface{})
-
-	// Annotations - AMQP annotations.
-	Annotations() map[string]interface{}
-	SetAnnotations(v map[string]interface{})
-
-	// Properties - Application properties.
-	Properties() map[string]interface{}
-	SetProperties(v map[string]interface{})
-
-	// Inferred indicates how the message content
-	// is encoded into AMQP sections. If inferred is true then binary and
-	// list values in the body of the message will be encoded as AMQP DATA
-	// and AMQP SEQUENCE sections, respectively. If inferred is false,
-	// then all values in the body of the message will be encoded as AMQP
-	// VALUE sections regardless of their type.
-	Inferred() bool
-	SetInferred(bool)
-
-	// Marshal a Go value into the message body. See amqp.Marshal() for details.
-	Marshal(interface{})
-
-	// Unmarshal the message body into the value pointed to by v. See amqp.Unmarshal() for details.
-	Unmarshal(interface{})
-
-	// Body value resulting from the default unmarshalling of message body as interface{}
-	Body() interface{}
-
-	// Encode encodes the message as AMQP data. If buffer is non-nil and is large enough
-	// the message is encoded into it, otherwise a new buffer is created.
-	// Returns the buffer containing the message.
-	Encode(buffer []byte) ([]byte, error)
-
-	// Decode data into this message. Overwrites an existing message content.
-	Decode(buffer []byte) error
-
-	// Clear the message contents.
-	Clear()
-
-	// Copy the contents of another message to this one.
-	Copy(m Message) error
-}
-
-type message struct{ pn *C.pn_message_t }
-
-func freeMessage(m *message) {
-	C.pn_message_free(m.pn)
-	m.pn = nil
-}
-
-// NewMessage creates a new message instance.
-func NewMessage() Message {
-	m := &message{C.pn_message()}
-	runtime.SetFinalizer(m, freeMessage)
-	return m
-}
-
-// NewMessageWith creates a message with value as the body. Equivalent to
-//     m := NewMessage(); m.Marshal(body)
-func NewMessageWith(value interface{}) Message {
-	m := NewMessage()
-	m.Marshal(value)
-	return m
-}
-
-func (m *message) Clear() { C.pn_message_clear(m.pn) }
-
-func (m *message) Copy(x Message) error {
-	if data, err := x.Encode(nil); err == nil {
-		return m.Decode(data)
-	} else {
-		return err
-	}
-}
-
-// ==== message get functions
-
-func rewindGet(data *C.pn_data_t) (v interface{}) {
-	C.pn_data_rewind(data)
-	C.pn_data_next(data)
-	unmarshal(&v, data)
-	return v
-}
-
-func rewindMap(data *C.pn_data_t) (v map[string]interface{}) {
-	C.pn_data_rewind(data)
-	C.pn_data_next(data)
-	unmarshal(&v, data)
-	return v
-}
-
-func (m *message) Inferred() bool  { return bool(C.pn_message_is_inferred(m.pn)) }
-func (m *message) Durable() bool   { return bool(C.pn_message_is_durable(m.pn)) }
-func (m *message) Priority() uint8 { return uint8(C.pn_message_get_priority(m.pn)) }
-func (m *message) TTL() time.Duration {
-	return time.Duration(C.pn_message_get_ttl(m.pn)) * time.Millisecond
-}
-func (m *message) FirstAcquirer() bool        { return bool(C.pn_message_is_first_acquirer(m.pn)) }
-func (m *message) DeliveryCount() uint32      { return uint32(C.pn_message_get_delivery_count(m.pn)) }
-func (m *message) MessageId() interface{}     { return rewindGet(C.pn_message_id(m.pn)) }
-func (m *message) UserId() string             { return goString(C.pn_message_get_user_id(m.pn)) }
-func (m *message) Address() string            { return C.GoString(C.pn_message_get_address(m.pn)) }
-func (m *message) Subject() string            { return C.GoString(C.pn_message_get_subject(m.pn)) }
-func (m *message) ReplyTo() string            { return C.GoString(C.pn_message_get_reply_to(m.pn)) }
-func (m *message) CorrelationId() interface{} { return rewindGet(C.pn_message_correlation_id(m.pn)) }
-func (m *message) ContentType() string        { return C.GoString(C.pn_message_get_content_type(m.pn)) }
-func (m *message) ContentEncoding() string    { return C.GoString(C.pn_message_get_content_encoding(m.pn)) }
-
-func (m *message) ExpiryTime() time.Time {
-	return time.Unix(0, int64(time.Millisecond*time.Duration(C.pn_message_get_expiry_time(m.pn))))
-}
-func (m *message) CreationTime() time.Time {
-	return time.Unix(0, int64(time.Millisecond)*int64(C.pn_message_get_creation_time(m.pn)))
-}
-func (m *message) GroupId() string        { return C.GoString(C.pn_message_get_group_id(m.pn)) }
-func (m *message) GroupSequence() int32   { return int32(C.pn_message_get_group_sequence(m.pn)) }
-func (m *message) ReplyToGroupId() string { return C.GoString(C.pn_message_get_reply_to_group_id(m.pn)) }
-
-func (m *message) Instructions() map[string]interface{} {
-	return rewindMap(C.pn_message_instructions(m.pn))
-}
-func (m *message) Annotations() map[string]interface{} {
-	return rewindMap(C.pn_message_annotations(m.pn))
-}
-func (m *message) Properties() map[string]interface{} {
-	return rewindMap(C.pn_message_properties(m.pn))
-}
-
-// ==== message set methods
-
-func setData(v interface{}, data *C.pn_data_t) {
-	C.pn_data_clear(data)
-	marshal(v, data)
-}
-
-func dataString(data *C.pn_data_t) string {
-	str := C.pn_string(C.CString(""))
-	defer C.pn_free(unsafe.Pointer(str))
-	C.pn_inspect(unsafe.Pointer(data), str)
-	return C.GoString(C.pn_string_get(str))
-}
-
-func (m *message) SetInferred(b bool)  { C.pn_message_set_inferred(m.pn, C.bool(m.Inferred())) }
-func (m *message) SetDurable(b bool)   { C.pn_message_set_durable(m.pn, C.bool(b)) }
-func (m *message) SetPriority(b uint8) { C.pn_message_set_priority(m.pn, C.uint8_t(b)) }
-func (m *message) SetTTL(d time.Duration) {
-	C.pn_message_set_ttl(m.pn, C.pn_millis_t(d/time.Millisecond))
-}
-func (m *message) SetFirstAcquirer(b bool)     { C.pn_message_set_first_acquirer(m.pn, C.bool(b)) }
-func (m *message) SetDeliveryCount(c uint32)   { C.pn_message_set_delivery_count(m.pn, C.uint32_t(c)) }
-func (m *message) SetMessageId(id interface{}) { setData(id, C.pn_message_id(m.pn)) }
-func (m *message) SetUserId(s string)          { C.pn_message_set_user_id(m.pn, pnBytes(([]byte)(s))) }
-func (m *message) SetAddress(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_address))
-}
-func (m *message) SetSubject(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_subject))
-}
-func (m *message) SetReplyTo(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to))
-}
-func (m *message) SetCorrelationId(c interface{}) { setData(c, C.pn_message_correlation_id(m.pn)) }
-func (m *message) SetContentType(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_type))
-}
-func (m *message) SetContentEncoding(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_encoding))
-}
-func (m *message) SetExpiryTime(t time.Time)   { C.pn_message_set_expiry_time(m.pn, pnTime(t)) }
-func (m *message) SetCreationTime(t time.Time) { C.pn_message_set_creation_time(m.pn, pnTime(t)) }
-func (m *message) SetGroupId(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_group_id))
-}
-func (m *message) SetGroupSequence(s int32) {
-	C.pn_message_set_group_sequence(m.pn, C.pn_sequence_t(s))
-}
-func (m *message) SetReplyToGroupId(s string) {
-	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to_group_id))
-}
-
-func (m *message) SetInstructions(v map[string]interface{}) {
-	setData(v, C.pn_message_instructions(m.pn))
-}
-func (m *message) SetAnnotations(v map[string]interface{}) { setData(v, C.pn_message_annotations(m.pn)) }
-func (m *message) SetProperties(v map[string]interface{})  { setData(v, C.pn_message_properties(m.pn)) }
-
-// Marshal/Unmarshal body
-func (m *message) Marshal(v interface{})   { clearMarshal(v, C.pn_message_body(m.pn)) }
-func (m *message) Unmarshal(v interface{}) { rewindUnmarshal(v, C.pn_message_body(m.pn)) }
-func (m *message) Body() (v interface{})   { m.Unmarshal(&v); return }
-
-func (m *message) Decode(data []byte) error {
-	m.Clear()
-	if len(data) == 0 {
-		return internal.Errorf("empty buffer for decode")
-	}
-	if C.pn_message_decode(m.pn, cPtr(data), cLen(data)) < 0 {
-		return internal.Errorf("decoding message: %s",
-			internal.PnError(unsafe.Pointer(C.pn_message_error(m.pn))))
-	}
-	return nil
-}
-
-func DecodeMessage(data []byte) (m Message, err error) {
-	m = NewMessage()
-	err = m.Decode(data)
-	return
-}
-
-func (m *message) Encode(buffer []byte) ([]byte, error) {
-	encode := func(buf []byte) ([]byte, error) {
-		len := cLen(buf)
-		result := C.pn_message_encode(m.pn, cPtr(buf), &len)
-		switch {
-		case result == C.PN_OVERFLOW:
-			return buf, overflow
-		case result < 0:
-			return buf, internal.Errorf("cannot encode message: %s", internal.PnErrorCode(result))
-		default:
-			return buf[:len], nil
-		}
-	}
-	return encodeGrow(buffer, encode)
-}
-
-// TODO aconway 2015-09-14: Multi-section messages.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message_test.go
deleted file mode 100644
index 7a6e5a8..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/message_test.go
+++ /dev/null
@@ -1,166 +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.
-*/
-
-package amqp
-
-import (
-	"testing"
-	"time"
-)
-
-func roundTrip(m Message) error {
-	buffer, err := m.Encode(nil)
-	if err != nil {
-		return err
-	}
-	m2, err := DecodeMessage(buffer)
-	if err != nil {
-		return err
-	}
-	return checkEqual(m, m2)
-}
-
-func TestDefaultMessage(t *testing.T) {
-	m := NewMessage()
-	// Check defaults
-	for _, data := range [][]interface{}{
-		{m.Inferred(), false},
-		{m.Durable(), false},
-		{m.Priority(), uint8(4)},
-		{m.TTL(), time.Duration(0)},
-		{m.UserId(), ""},
-		{m.Address(), ""},
-		{m.Subject(), ""},
-		{m.ReplyTo(), ""},
-		{m.ContentType(), ""},
-		{m.ContentEncoding(), ""},
-		{m.GroupId(), ""},
-		{m.GroupSequence(), int32(0)},
-		{m.ReplyToGroupId(), ""},
-		{m.MessageId(), nil},
-		{m.CorrelationId(), nil},
-		{m.Instructions(), map[string]interface{}{}},
-		{m.Annotations(), map[string]interface{}{}},
-		{m.Properties(), map[string]interface{}{}},
-		{m.Body(), nil},
-	} {
-		if err := checkEqual(data[0], data[1]); err != nil {
-			t.Error(err)
-		}
-	}
-	if err := roundTrip(m); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestMessageRoundTrip(t *testing.T) {
-	m := NewMessage()
-	m.SetInferred(false)
-	m.SetDurable(true)
-	m.SetPriority(42)
-	m.SetTTL(0)
-	m.SetUserId("user")
-	m.SetAddress("address")
-	m.SetSubject("subject")
-	m.SetReplyTo("replyto")
-	m.SetContentType("content")
-	m.SetContentEncoding("encoding")
-	m.SetGroupId("group")
-	m.SetGroupSequence(42)
-	m.SetReplyToGroupId("replytogroup")
-	m.SetMessageId("id")
-	m.SetCorrelationId("correlation")
-	m.SetInstructions(map[string]interface{}{"instructions": "foo"})
-	m.SetAnnotations(map[string]interface{}{"annotations": "foo"})
-	m.SetProperties(map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"})
-	m.Marshal("hello")
-
-	for _, data := range [][]interface{}{
-		{m.Inferred(), false},
-		{m.Durable(), true},
-		{m.Priority(), uint8(42)},
-		{m.TTL(), time.Duration(0)},
-		{m.UserId(), "user"},
-		{m.Address(), "address"},
-		{m.Subject(), "subject"},
-		{m.ReplyTo(), "replyto"},
-		{m.ContentType(), "content"},
-		{m.ContentEncoding(), "encoding"},
-		{m.GroupId(), "group"},
-		{m.GroupSequence(), int32(42)},
-		{m.ReplyToGroupId(), "replytogroup"},
-		{m.MessageId(), "id"},
-		{m.CorrelationId(), "correlation"},
-		{m.Instructions(), map[string]interface{}{"instructions": "foo"}},
-		{m.Annotations(), map[string]interface{}{"annotations": "foo"}},
-		{m.Properties(), map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"}},
-		{m.Body(), "hello"},
-	} {
-		if err := checkEqual(data[0], data[1]); err != nil {
-			t.Error(err)
-		}
-	}
-	if err := roundTrip(m); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestMessageBodyTypes(t *testing.T) {
-	var s string
-	var body interface{}
-	var i int64
-
-	m := NewMessageWith(int64(42))
-	m.Unmarshal(&body)
-	m.Unmarshal(&i)
-	if err := checkEqual(body.(int64), int64(42)); err != nil {
-		t.Error(err)
-	}
-	if err := checkEqual(i, int64(42)); err != nil {
-		t.Error(err)
-	}
-
-	m = NewMessageWith("hello")
-	m.Unmarshal(&s)
-	m.Unmarshal(&body)
-	if err := checkEqual(s, "hello"); err != nil {
-		t.Error(err)
-	}
-	if err := checkEqual(body.(string), "hello"); err != nil {
-		t.Error(err)
-	}
-	if err := roundTrip(m); err != nil {
-		t.Error(err)
-	}
-
-	m = NewMessageWith(Binary("bin"))
-	m.Unmarshal(&s)
-	m.Unmarshal(&body)
-	if err := checkEqual(body.(Binary), Binary("bin")); err != nil {
-		t.Error(err)
-	}
-	if err := checkEqual(s, "bin"); err != nil {
-		t.Error(err)
-	}
-	if err := roundTrip(m); err != nil {
-		t.Error(err)
-	}
-
-	// TODO aconway 2015-09-08: array etc.
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/types.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/types.go b/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/types.go
deleted file mode 100644
index 131c974..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/amqp/types.go
+++ /dev/null
@@ -1,198 +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.
-*/
-
-package amqp
-
-// #include <proton/codec.h>
-import "C"
-
-import (
-	"bytes"
-	"fmt"
-	"reflect"
-	"time"
-	"unsafe"
-)
-
-type Type C.pn_type_t
-
-func (t Type) String() string {
-	switch C.pn_type_t(t) {
-	case C.PN_NULL:
-		return "null"
-	case C.PN_BOOL:
-		return "bool"
-	case C.PN_UBYTE:
-		return "ubyte"
-	case C.PN_BYTE:
-		return "byte"
-	case C.PN_USHORT:
-		return "ushort"
-	case C.PN_SHORT:
-		return "short"
-	case C.PN_CHAR:
-		return "char"
-	case C.PN_UINT:
-		return "uint"
-	case C.PN_INT:
-		return "int"
-	case C.PN_ULONG:
-		return "ulong"
-	case C.PN_LONG:
-		return "long"
-	case C.PN_TIMESTAMP:
-		return "timestamp"
-	case C.PN_FLOAT:
-		return "float"
-	case C.PN_DOUBLE:
-		return "double"
-	case C.PN_DECIMAL32:
-		return "decimal32"
-	case C.PN_DECIMAL64:
-		return "decimal64"
-	case C.PN_DECIMAL128:
-		return "decimal128"
-	case C.PN_UUID:
-		return "uuid"
-	case C.PN_BINARY:
-		return "binary"
-	case C.PN_STRING:
-		return "string"
-	case C.PN_SYMBOL:
-		return "symbol"
-	case C.PN_DESCRIBED:
-		return "described"
-	case C.PN_ARRAY:
-		return "array"
-	case C.PN_LIST:
-		return "list"
-	case C.PN_MAP:
-		return "map"
-	case C.PN_INVALID:
-		return "no-data"
-	default:
-		return fmt.Sprintf("unknown-type(%d)", t)
-	}
-}
-
-// Go types
-var (
-	bytesType = reflect.TypeOf([]byte{})
-	valueType = reflect.TypeOf(reflect.Value{})
-)
-
-// TODO aconway 2015-04-08: can't handle AMQP maps with key types that are not valid Go map keys.
-
-// Map is a generic map that can have mixed key and value types and so can represent any AMQP map
-type Map map[interface{}]interface{}
-
-// List is a generic list that can hold mixed values and can represent any AMQP list.
-//
-type List []interface{}
-
-// Symbol is a string that is encoded as an AMQP symbol
-type Symbol string
-
-func (s Symbol) GoString() string { return fmt.Sprintf("s\"%s\"", s) }
-
-// Binary is a string that is encoded as an AMQP binary.
-// It is a string rather than a byte[] because byte[] is not hashable and can't be used as
-// a map key, AMQP frequently uses binary types as map keys. It can convert to and from []byte
-type Binary string
-
-func (b Binary) GoString() string { return fmt.Sprintf("b\"%s\"", b) }
-
-// GoString for Map prints values with their types, useful for debugging.
-func (m Map) GoString() string {
-	out := &bytes.Buffer{}
-	fmt.Fprintf(out, "%T{", m)
-	i := len(m)
-	for k, v := range m {
-		fmt.Fprintf(out, "%T(%#v): %T(%#v)", k, k, v, v)
-		i--
-		if i > 0 {
-			fmt.Fprint(out, ", ")
-		}
-	}
-	fmt.Fprint(out, "}")
-	return out.String()
-}
-
-// GoString for List prints values with their types, useful for debugging.
-func (l List) GoString() string {
-	out := &bytes.Buffer{}
-	fmt.Fprintf(out, "%T{", l)
-	for i := 0; i < len(l); i++ {
-		fmt.Fprintf(out, "%T(%#v)", l[i], l[i])
-		if i == len(l)-1 {
-			fmt.Fprint(out, ", ")
-		}
-	}
-	fmt.Fprint(out, "}")
-	return out.String()
-}
-
-// pnTime converts Go time.Time to Proton millisecond Unix time.
-func pnTime(t time.Time) C.pn_timestamp_t {
-	secs := t.Unix()
-	// Note: sub-second accuracy is not guaraunteed if the Unix time in
-	// nanoseconds cannot be represented by an int64 (sometime around year 2260)
-	msecs := (t.UnixNano() % int64(time.Second)) / int64(time.Millisecond)
-	return C.pn_timestamp_t(secs*1000 + msecs)
-}
-
-// goTime converts a pn_timestamp_t to a Go time.Time.
-func goTime(t C.pn_timestamp_t) time.Time {
-	secs := int64(t) / 1000
-	nsecs := (int64(t) % 1000) * int64(time.Millisecond)
-	return time.Unix(secs, nsecs)
-}
-
-func goBytes(cBytes C.pn_bytes_t) (bytes []byte) {
-	if cBytes.start != nil {
-		bytes = C.GoBytes(unsafe.Pointer(cBytes.start), C.int(cBytes.size))
-	}
-	return
-}
-
-func goString(cBytes C.pn_bytes_t) (str string) {
-	if cBytes.start != nil {
-		str = C.GoStringN(cBytes.start, C.int(cBytes.size))
-	}
-	return
-}
-
-func pnBytes(b []byte) C.pn_bytes_t {
-	if len(b) == 0 {
-		return C.pn_bytes_t{0, nil}
-	} else {
-		return C.pn_bytes_t{C.size_t(len(b)), (*C.char)(unsafe.Pointer(&b[0]))}
-	}
-}
-
-func cPtr(b []byte) *C.char {
-	if len(b) == 0 {
-		return nil
-	}
-	return (*C.char)(unsafe.Pointer(&b[0]))
-}
-
-func cLen(b []byte) C.size_t {
-	return C.size_t(len(b))
-}


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


[23/50] [abbrv] qpid-proton git commit: NO-JIRA: Add gcc to appveyor config so cgo will work.

Posted by ac...@apache.org.
NO-JIRA: Add gcc to appveyor config so cgo will work.


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

Branch: refs/heads/go1
Commit: f7a4cb3ea11d6da3a9008b89350f5f4707f4975b
Parents: 63cd40f
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 12 16:54:20 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 13 10:59:42 2015 -0400

----------------------------------------------------------------------
 appveyor.yml                   |  1 +
 examples/go/electron/broker.go | 31 ++++++++++++++++++-------------
 2 files changed, 19 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f7a4cb3e/appveyor.yml
----------------------------------------------------------------------
diff --git a/appveyor.yml b/appveyor.yml
index a147e0d..9729c57 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,6 +2,7 @@ version: 0.10-SNAPSHOT-{branch}.{build}
 configuration: RelWithDebInfo
 install:
 - cinst -y swig
+- cinst -y mingw
 before_build:
 - mkdir BLD
 - cd BLD

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f7a4cb3e/examples/go/electron/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/broker.go b/examples/go/electron/broker.go
index 0ecfb92..1e4a931 100644
--- a/examples/go/electron/broker.go
+++ b/examples/go/electron/broker.go
@@ -30,6 +30,7 @@ import (
 	"./util"
 	"flag"
 	"fmt"
+	"log"
 	"net"
 	"os"
 	"qpid.apache.org/electron"
@@ -51,14 +52,27 @@ var qsize = flag.Int("qsize", 1000, "Max queue size")
 func main() {
 	flag.Usage = usage
 	flag.Parse()
+	if err := newBroker().run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+type broker struct {
+	queues    util.Queues
+	container electron.Container
+}
+
+func newBroker() *broker {
+	return &broker{util.MakeQueues(*qsize), electron.NewContainer("")}
+}
 
-	b := newBroker()
+func (b *broker) run() (err error) {
 	listener, err := net.Listen("tcp", *addr)
-	util.ExitIf(err)
+	if err != nil {
+		return err
+	}
 	defer listener.Close()
 	fmt.Printf("Listening on %s\n", listener.Addr())
-
-	// Loop accepting new connections.
 	for {
 		conn, err := listener.Accept()
 		if err != nil {
@@ -74,15 +88,6 @@ func main() {
 	}
 }
 
-type broker struct {
-	queues    util.Queues
-	container electron.Container
-}
-
-func newBroker() *broker {
-	return &broker{util.MakeQueues(*qsize), electron.NewContainer("")}
-}
-
 // connection creates a new AMQP connection for a net.Conn.
 func (b *broker) connection(conn net.Conn) error {
 	c, err := b.container.Connection(conn)


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


[29/50] [abbrv] qpid-proton git commit: NO-JIRA: Remove a test dependency version constraint that no longer works

Posted by ac...@apache.org.
NO-JIRA: Remove a test dependency version constraint that no longer works


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

Branch: refs/heads/go1
Commit: 52dd42d83843203507953a55efc2955da7b36ed9
Parents: 2057d03
Author: Justin Ross <jr...@redhat.com>
Authored: Sat Oct 17 09:31:45 2015 -0400
Committer: Justin Ross <jr...@redhat.com>
Committed: Sat Oct 17 09:32:15 2015 -0400

----------------------------------------------------------------------
 tests/ruby/proton-test | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/52dd42d8/tests/ruby/proton-test
----------------------------------------------------------------------
diff --git a/tests/ruby/proton-test b/tests/ruby/proton-test
index cc35ab7..04aee1c 100755
--- a/tests/ruby/proton-test
+++ b/tests/ruby/proton-test
@@ -4,7 +4,6 @@ if RUBY_VERSION < "1.9"
 require 'rubygems'
 end
 
-gem 'minitest', '= 4.7.0', '< 5.0'
 require 'test/unit'
 require 'proton_tests/interop.rb'
 require 'proton_tests/smoke.rb'


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


[05/50] [abbrv] qpid-proton git commit: PROTON-1008: Updated README and added simple sasl config file

Posted by ac...@apache.org.
PROTON-1008: Updated README and added simple sasl config file


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

Branch: refs/heads/go1
Commit: 2789615a1acee688ebcee580ff755d7d694873df
Parents: baaf74a
Author: Gordon Sim <gs...@redhat.com>
Authored: Mon Oct 5 11:08:43 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Mon Oct 5 11:08:43 2015 +0100

----------------------------------------------------------------------
 examples/python/README             | 14 ++++++++++++++
 examples/python/proton-server.conf |  1 +
 2 files changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2789615a/examples/python/README
----------------------------------------------------------------------
diff --git a/examples/python/README b/examples/python/README
index 40e7910..9051187 100644
--- a/examples/python/README
+++ b/examples/python/README
@@ -5,6 +5,10 @@ anonymous connections and accepts links to and from a node named
 provided against which the examples can also be run (transactions are
 not yet supported in this script).
 
+Note: For builds that include SASL support via the cyrus sasl library,
+those examples that accept incoming connections may require some SASL
+configuration which is described below.
+
 ------------------------------------------------------------------
 
 helloworld.py
@@ -171,3 +175,13 @@ A variant of the above that uses the tornado eventloop instead.
 
 -------------------------------------------------------------------
 
+SASL configuration
+
+If your build includes extra SASL support (provided via the cyrus SASL
+library), you may need to provide some configuration to enable
+examples that accept incoming connections (i.e. those with 'direct' in
+the name). This is done by supplying a config file name
+proton-server.conf. The directory in which it is in can be specified
+via the PN_SASL_CONFIG_PATH environment variable. A simple example
+config file is included along with these examples, enabling only the
+EXTERNAL and ANONYMOUS mechanisms by default.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2789615a/examples/python/proton-server.conf
----------------------------------------------------------------------
diff --git a/examples/python/proton-server.conf b/examples/python/proton-server.conf
new file mode 100644
index 0000000..6d236fe
--- /dev/null
+++ b/examples/python/proton-server.conf
@@ -0,0 +1 @@
+mech_list: EXTERNAL ANONYMOUS


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


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

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/container.go
----------------------------------------------------------------------
diff --cc electron/container.go
index 0000000,0000000..7bbc4b0
new file mode 100644
--- /dev/null
+++ b/electron/container.go
@@@ -1,0 -1,0 +1,71 @@@
++/*
++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
++
++import (
++	"net"
++	"qpid.apache.org/internal"
++)
++
++// Container is an AMQP container, it represents a single AMQP "application".It
++// provides functions to create new Connections to remote containers.
++//
++// Create with NewContainer()
++//
++type Container interface {
++	// Id is a unique identifier for the container in your distributed application.
++	Id() string
++
++	// Create a new AMQP Connection over the supplied net.Conn connection.
++	//
++	// You must call Connection.Open() on the returned Connection, after
++	// setting any Connection properties you need to set. Note the net.Conn
++	// can be an outgoing connection (e.g. made with net.Dial) or an incoming
++	// connection (e.g. made with net.Listener.Accept())
++	Connection(net.Conn, ...ConnectionSetting) (Connection, error)
++}
++
++type container struct {
++	id        string
++	linkNames internal.IdCounter
++}
++
++// NewContainer creates a new container. The id must be unique in your
++// distributed application, all connections created by the container
++// will have this container-id.
++//
++// If id == "" a random UUID will be generated for the id.
++func NewContainer(id string) Container {
++	if id == "" {
++		id = internal.UUID4().String()
++	}
++	cont := &container{id: id}
++	return cont
++}
++
++func (cont *container) Id() string { return cont.id }
++
++func (cont *container) nextLinkName() string {
++	return cont.id + "@" + cont.linkNames.Next()
++}
++
++func (cont *container) Connection(conn net.Conn, setting ...ConnectionSetting) (Connection, error) {
++	return newConnection(conn, cont, setting...)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/doc.go
----------------------------------------------------------------------
diff --cc electron/doc.go
index 0000000,0000000..eaa6e7a
new file mode 100644
--- /dev/null
+++ b/electron/doc.go
@@@ -1,0 -1,0 +1,57 @@@
++/*
++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 is a procedural, concurrent-safe Go library for AMQP messaging.
++You can write clients and servers using this library.
++
++Start by creating a Container with NewContainer. A Container represents a client
++or server application that can contain many incoming or outgoing connections.
++
++Create connections with the standard Go 'net' package using net.Dial or
++net.Listen. Create an AMQP connection over a net.Conn with
++Container.Connection() and open it with Connection.Open().
++
++AMQP sends messages over "links". Each link has a Sender end and a Receiver
++end. Connection.Sender() and Connection.Receiver() allow you to create links to
++Send() and Receive() messages.
++
++You can create an AMQP server connection by calling Connection.Server() and
++Connection.Listen() before calling Connection.Open(). A server connection can
++negotiate protocol security details and can accept incoming links opened from
++the remote end of the connection
++*/
++package electron
++
++//#cgo LDFLAGS: -lqpid-proton
++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.
++
++The handler sets up channels as needed to get or send data from user goroutines
++using electron types like Sender or Receiver. We also use Engine.Inject to inject
++actions into the event loop from user goroutines.
++
++*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/endpoint.go
----------------------------------------------------------------------
diff --cc electron/endpoint.go
index 0000000,0000000..745fd04
new file mode 100644
--- /dev/null
+++ b/electron/endpoint.go
@@@ -1,0 -1,0 +1,68 @@@
++/*
++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
++
++import (
++	"io"
++	"qpid.apache.org/internal"
++	"qpid.apache.org/proton"
++)
++
++// Closed is an alias for io.EOF. It is returned as an error when an endpoint
++// was closed cleanly.
++var Closed = io.EOF
++
++// Endpoint is the common interface for Connection, Session, Link, Sender and Receiver.
++//
++// Endpoints can be created locally or by the remote peer. You must Open() an
++// endpoint before you can use it. Some endpoints have additional Set*() methods
++// that must be called before Open() to take effect, see Connection, Session,
++// Link, Sender and Receiver for details.
++//
++type Endpoint interface {
++	// Close an endpoint and signal an error to the remote end if error != nil.
++	Close(error)
++
++	// String is a human readable identifier, useful for debugging and logging.
++	String() string
++
++	// Error returns nil if the endpoint is open, otherwise returns an error.
++	// Error() == Closed means the endpoint was closed without error.
++	Error() error
++
++	// Connection containing the endpoint
++	Connection() Connection
++}
++
++type endpoint struct {
++	err internal.ErrorHolder
++	str string // Must be set by the value that embeds endpoint.
++}
++
++func (e *endpoint) String() string { return e.str }
++func (e *endpoint) Error() error   { return e.err.Get() }
++
++// Call in proton goroutine to close an endpoint locally
++// handler will complete the close when remote end closes.
++func localClose(ep proton.Endpoint, err error) {
++	if ep.State().LocalActive() {
++		proton.CloseError(ep, err)
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/handler.go
----------------------------------------------------------------------
diff --cc electron/handler.go
index 0000000,0000000..b518e42
new file mode 100644
--- /dev/null
+++ b/electron/handler.go
@@@ -1,0 -1,0 +1,158 @@@
++/*
++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
++
++import (
++	"qpid.apache.org/amqp"
++	"qpid.apache.org/proton"
++)
++
++// NOTE: methods in this file are called only in the proton goroutine unless otherwise indicated.
++
++type handler struct {
++	delegator    *proton.MessagingAdapter
++	connection   *connection
++	links        map[proton.Link]Link
++	sentMessages map[proton.Delivery]*sentMessage
++	sessions     map[proton.Session]*session
++}
++
++func newHandler(c *connection) *handler {
++	h := &handler{
++		connection:   c,
++		links:        make(map[proton.Link]Link),
++		sentMessages: make(map[proton.Delivery]*sentMessage),
++		sessions:     make(map[proton.Session]*session),
++	}
++	h.delegator = proton.NewMessagingAdapter(h)
++	// Disable auto features of MessagingAdapter, we do these ourselves.
++	h.delegator.Prefetch = 0
++	h.delegator.AutoAccept = false
++	h.delegator.AutoSettle = false
++	h.delegator.AutoOpen = false
++	return h
++}
++
++func (h *handler) internalError(fmt string, arg ...interface{}) {
++	proton.CloseError(h.connection.eConnection, amqp.Errorf(amqp.InternalError, fmt, arg...))
++}
++
++func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
++	switch t {
++
++	case proton.MMessage:
++		if r, ok := h.links[e.Link()].(*receiver); ok {
++			r.message(e.Delivery())
++		} else {
++			h.internalError("no receiver for link %s", e.Link())
++		}
++
++	case proton.MSettled:
++		if sm := h.sentMessages[e.Delivery()]; sm != nil {
++			sm.settled(nil)
++		}
++
++	case proton.MSendable:
++		if s, ok := h.links[e.Link()].(*sender); ok {
++			s.sendable()
++		} else {
++			h.internalError("no receiver for link %s", e.Link())
++		}
++
++	case proton.MSessionOpening:
++		if e.Session().State().LocalUninit() { // Remotely opened
++			incoming := &IncomingSession{h: h, pSession: e.Session()}
++			h.connection.accept(incoming)
++			if err := incoming.error(); err != nil {
++				proton.CloseError(e.Session(), err)
++			}
++		}
++
++	case proton.MSessionClosed:
++		err := proton.EndpointError(e.Session())
++		for l, _ := range h.links {
++			if l.Session() == e.Session() {
++				h.linkClosed(l, err)
++			}
++		}
++		delete(h.sessions, e.Session())
++
++	case proton.MLinkOpening:
++		l := e.Link()
++		if l.State().LocalActive() { // Already opened locally.
++			break
++		}
++		ss := h.sessions[l.Session()]
++		if ss == nil {
++			h.internalError("no session for link %s", e.Link())
++			break
++		}
++		var incoming Incoming
++		if l.IsReceiver() {
++			incoming = &IncomingReceiver{makeIncomingLink(ss, l)}
++		} else {
++			incoming = &IncomingSender{makeIncomingLink(ss, l)}
++		}
++		h.connection.accept(incoming)
++		if err := incoming.error(); err != nil {
++			proton.CloseError(l, err)
++			break
++		}
++
++	case proton.MLinkClosing:
++		e.Link().Close()
++
++	case proton.MLinkClosed:
++		h.linkClosed(e.Link(), proton.EndpointError(e.Link()))
++
++	case proton.MConnectionClosing:
++		h.connection.err.Set(e.Connection().RemoteCondition().Error())
++
++	case proton.MConnectionClosed:
++		h.connection.err.Set(Closed) // If no error already set, this is an orderly close.
++
++	case proton.MDisconnected:
++		h.connection.err.Set(e.Transport().Condition().Error())
++		// If err not set at this point (e.g. to Closed) then this is unexpected.
++		h.connection.err.Set(amqp.Errorf(amqp.IllegalState, "unexpected disconnect on %s", h.connection))
++
++		err := h.connection.Error()
++		for l, _ := range h.links {
++			h.linkClosed(l, err)
++		}
++		for _, s := range h.sessions {
++			s.closed(err)
++		}
++		for _, sm := range h.sentMessages {
++			sm.settled(err)
++		}
++	}
++}
++
++func (h *handler) linkClosed(l proton.Link, err error) {
++	if link := h.links[l]; link != nil {
++		link.closed(err)
++		delete(h.links, l)
++	}
++}
++
++func (h *handler) addLink(rl proton.Link, ll Link) {
++	h.links[rl] = ll
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/link.go
----------------------------------------------------------------------
diff --cc electron/link.go
index 0000000,0000000..4bef53b
new file mode 100644
--- /dev/null
+++ b/electron/link.go
@@@ -1,0 -1,0 +1,247 @@@
++/*
++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
++
++import (
++	"qpid.apache.org/internal"
++	"qpid.apache.org/proton"
++)
++
++// Link is the common interface for AMQP links. Sender and Receiver provide
++// more methods for the sending or receiving end of a link respectively.
++type Link interface {
++	Endpoint
++
++	// Source address that messages are coming from.
++	Source() string
++
++	// Target address that messages are going to.
++	Target() string
++
++	// Name is a unique name for the link among links between the same
++	// containers in the same direction. By default generated automatically.
++	LinkName() string
++
++	// IsSender is true if this is the sending end of the link.
++	IsSender() bool
++
++	// IsReceiver is true if this is the receiving end of the link.
++	IsReceiver() bool
++
++	// SndSettle defines when the sending end of the link settles message delivery.
++	SndSettle() SndSettleMode
++
++	// RcvSettle defines when the sending end of the link settles message delivery.
++	RcvSettle() RcvSettleMode
++
++	// Session containing the Link
++	Session() Session
++
++	// Called in event loop on closed event.
++	closed(err error)
++	// Called to open a link (local or accepted incoming link)
++	open()
++}
++
++// LinkSetting can be passed when creating a sender or receiver.
++// See functions that return LinkSetting for details
++type LinkSetting func(*link)
++
++// Source sets address that messages are coming from.
++func Source(s string) LinkSetting { return func(l *link) { l.source = s } }
++
++// Target sets address that messages are going to.
++func Target(s string) LinkSetting { return func(l *link) { l.target = s } }
++
++// LinkName sets the link name.
++func LinkName(s string) LinkSetting { return func(l *link) { l.target = s } }
++
++// SndSettle sets the send settle mode
++func SndSettle(m SndSettleMode) LinkSetting { return func(l *link) { l.sndSettle = m } }
++
++// RcvSettle sets the send settle mode
++func RcvSettle(m RcvSettleMode) LinkSetting { return func(l *link) { l.rcvSettle = m } }
++
++// SndSettleMode defines when the sending end of the link settles message delivery.
++type SndSettleMode proton.SndSettleMode
++
++// Capacity sets the link capacity
++func Capacity(n int) LinkSetting { return func(l *link) { l.capacity = n } }
++
++// Prefetch sets a receivers pre-fetch flag. Not relevant for a sender.
++func Prefetch(p bool) LinkSetting { return func(l *link) { l.prefetch = p } }
++
++// AtMostOnce sets "fire and forget" mode, messages are sent but no
++// acknowledgment is received, messages can be lost if there is a network
++// failure. Sets SndSettleMode=SendSettled and RcvSettleMode=RcvFirst
++func AtMostOnce() LinkSetting {
++	return func(l *link) {
++		SndSettle(SndSettled)(l)
++		RcvSettle(RcvFirst)(l)
++	}
++}
++
++// AtLeastOnce requests acknowledgment for every message, acknowledgment
++// indicates the message was definitely received. In the event of a
++// failure, unacknowledged messages can be re-sent but there is a chance
++// that the message will be received twice in this case.
++// Sets SndSettleMode=SndUnsettled and RcvSettleMode=RcvFirst
++func AtLeastOnce() LinkSetting {
++	return func(l *link) {
++		SndSettle(SndUnsettled)(l)
++		RcvSettle(RcvFirst)(l)
++	}
++}
++
++const (
++	// Messages are sent unsettled
++	SndUnsettled = SndSettleMode(proton.SndUnsettled)
++	// Messages are sent already settled
++	SndSettled = SndSettleMode(proton.SndSettled)
++	// Sender can send either unsettled or settled messages.
++	SendMixed = SndSettleMode(proton.SndMixed)
++)
++
++// RcvSettleMode defines when the receiving end of the link settles message delivery.
++type RcvSettleMode proton.RcvSettleMode
++
++const (
++	// Receiver settles first.
++	RcvFirst = RcvSettleMode(proton.RcvFirst)
++	// Receiver waits for sender to settle before settling.
++	RcvSecond = RcvSettleMode(proton.RcvSecond)
++)
++
++type link struct {
++	endpoint
++
++	// Link settings.
++	source    string
++	target    string
++	linkName  string
++	isSender  bool
++	sndSettle SndSettleMode
++	rcvSettle RcvSettleMode
++	capacity  int
++	prefetch  bool
++
++	session *session
++	eLink   proton.Link
++	done    chan struct{} // Closed when link is closed
++}
++
++func (l *link) Source() string           { return l.source }
++func (l *link) Target() string           { return l.target }
++func (l *link) LinkName() string         { return l.linkName }
++func (l *link) IsSender() bool           { return l.isSender }
++func (l *link) IsReceiver() bool         { return !l.isSender }
++func (l *link) SndSettle() SndSettleMode { return l.sndSettle }
++func (l *link) RcvSettle() RcvSettleMode { return l.rcvSettle }
++func (l *link) Session() Session         { return l.session }
++func (l *link) Connection() Connection   { return l.session.Connection() }
++
++func (l *link) engine() *proton.Engine { return l.session.connection.engine }
++func (l *link) handler() *handler      { return l.session.connection.handler }
++
++// Set up link fields and open the proton.Link
++func localLink(sn *session, isSender bool, setting ...LinkSetting) (link, error) {
++	l := link{
++		session:  sn,
++		isSender: isSender,
++		capacity: 1,
++		prefetch: false,
++		done:     make(chan struct{}),
++	}
++	for _, set := range setting {
++		set(&l)
++	}
++	if l.linkName == "" {
++		l.linkName = l.session.connection.container.nextLinkName()
++	}
++	if l.IsSender() {
++		l.eLink = l.session.eSession.Sender(l.linkName)
++	} else {
++		l.eLink = l.session.eSession.Receiver(l.linkName)
++	}
++	if l.eLink.IsNil() {
++		l.err.Set(internal.Errorf("cannot create link %s", l))
++		return l, l.err.Get()
++	}
++	l.eLink.Source().SetAddress(l.source)
++	l.eLink.Target().SetAddress(l.target)
++	l.eLink.SetSndSettleMode(proton.SndSettleMode(l.sndSettle))
++	l.eLink.SetRcvSettleMode(proton.RcvSettleMode(l.rcvSettle))
++	l.str = l.eLink.String()
++	l.eLink.Open()
++	return l, nil
++}
++
++type incomingLink struct {
++	incoming
++	link
++}
++
++// Set up a link from an incoming proton.Link.
++func makeIncomingLink(sn *session, eLink proton.Link) incomingLink {
++	l := incomingLink{
++		link: link{
++			session:   sn,
++			isSender:  eLink.IsSender(),
++			eLink:     eLink,
++			source:    eLink.RemoteSource().Address(),
++			target:    eLink.RemoteTarget().Address(),
++			linkName:  eLink.Name(),
++			sndSettle: SndSettleMode(eLink.RemoteSndSettleMode()),
++			rcvSettle: RcvSettleMode(eLink.RemoteRcvSettleMode()),
++			capacity:  1,
++			prefetch:  false,
++			done:      make(chan struct{}),
++		},
++	}
++	l.str = eLink.String()
++	return l
++}
++
++// Called in proton goroutine on closed or disconnected
++func (l *link) closed(err error) {
++	l.err.Set(err)
++	l.err.Set(Closed) // If no error set, mark as closed.
++	close(l.done)
++}
++
++// Not part of Link interface but use by Sender and Receiver.
++func (l *link) Credit() (credit int, err error) {
++	err = l.engine().InjectWait(func() error {
++		credit = l.eLink.Credit()
++		return nil
++	})
++	return
++}
++
++// Not part of Link interface but use by Sender and Receiver.
++func (l *link) Capacity() int { return l.capacity }
++
++func (l *link) Close(err error) {
++	l.engine().Inject(func() { localClose(l.eLink, err) })
++}
++
++func (l *link) open() {
++	l.eLink.Open()
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/messaging_test.go
----------------------------------------------------------------------
diff --cc electron/messaging_test.go
index 0000000,0000000..36b0c24
new file mode 100644
--- /dev/null
+++ b/electron/messaging_test.go
@@@ -1,0 -1,0 +1,416 @@@
++/*
++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
++
++import (
++	"fmt"
++	"net"
++	"path"
++	"qpid.apache.org/amqp"
++	"runtime"
++	"testing"
++	"time"
++)
++
++func fatalIf(t *testing.T, err error) {
++	if err != nil {
++		_, file, line, ok := runtime.Caller(1) // annotate with location of caller.
++		if ok {
++			_, file = path.Split(file)
++		}
++		t.Fatalf("(from %s:%d) %v", file, line, err)
++	}
++}
++
++// Start a server, return listening addr and channel for incoming Connection.
++func newServer(t *testing.T, cont Container, accept func(Endpoint) error) (net.Addr, <-chan Connection) {
++	listener, err := net.Listen("tcp", "")
++	fatalIf(t, err)
++	addr := listener.Addr()
++	ch := make(chan Connection)
++	go func() {
++		conn, err := listener.Accept()
++		c, err := cont.Connection(conn)
++		fatalIf(t, err)
++		c.Server()
++		c.Listen(accept)
++		fatalIf(t, c.Open())
++		ch <- c
++	}()
++	return addr, ch
++}
++
++// Return open an client connection and session, return the session.
++func newClient(t *testing.T, cont Container, addr net.Addr) Session {
++	conn, err := net.Dial(addr.Network(), addr.String())
++	fatalIf(t, err)
++	c, err := cont.Connection(conn)
++	fatalIf(t, err)
++	c.Open()
++	sn, err := c.Session()
++	fatalIf(t, err)
++	return sn
++}
++
++// Return client and server ends of the same connection.
++func newClientServer(t *testing.T, accept func(Endpoint) error) (client Session, server Connection) {
++	addr, ch := newServer(t, NewContainer(""), accept)
++	client = newClient(t, NewContainer(""), addr)
++	return client, <-ch
++}
++
++// Close client and server
++func closeClientServer(client Session, server Connection) {
++	client.Connection().Close(nil)
++	server.Close(nil)
++}
++
++// Send a message one way with a client sender and server receiver, verify ack.
++func TestClientSendServerReceive(t *testing.T) {
++	timeout := time.Second * 2
++	nLinks := 3
++	nMessages := 3
++
++	rchan := make(chan Receiver, nLinks)
++	client, server := newClientServer(t, func(ep Endpoint) error {
++		if r, ok := ep.(Receiver); ok {
++			r.SetCapacity(1, false)
++			rchan <- r
++		}
++		return nil
++	})
++
++	defer func() {
++		closeClientServer(client, server)
++	}()
++
++	s := make([]Sender, nLinks)
++	for i := 0; i < nLinks; i++ {
++		var err error
++		s[i], err = client.Sender(Target(fmt.Sprintf("foo%d", i)))
++		if err != nil {
++			t.Fatal(err)
++		}
++	}
++	r := make([]Receiver, nLinks)
++	for i := 0; i < nLinks; i++ {
++		r[i] = <-rchan
++	}
++
++	for i := 0; i < nLinks; i++ {
++		for j := 0; j < nMessages; j++ {
++			var sm SentMessage
++
++			// Client send
++			sendDone := make(chan struct{})
++			go func() {
++				defer close(sendDone)
++				m := amqp.NewMessageWith(fmt.Sprintf("foobar%v-%v", i, j))
++				var err error
++				sm, err = s[i].Send(m)
++				if err != nil {
++					t.Fatal(err)
++				}
++			}()
++
++			// Server recieve
++			rm, err := r[i].Receive()
++			if err != nil {
++				t.Fatal(err)
++			}
++			if want, got := interface{}(fmt.Sprintf("foobar%v-%v", i, j)), rm.Message.Body(); want != got {
++				t.Errorf("%#v != %#v", want, got)
++			}
++
++			// Should not be acknowledged on client yet
++			<-sendDone
++			if d, err := sm.DispositionTimeout(0); err != Timeout || NoDisposition != d {
++				t.Errorf("want [no-disposition/timeout] got [%v/%v]", d, err)
++			}
++			// Server ack
++			if err := rm.Acknowledge(Rejected); err != nil {
++				t.Error(err)
++			}
++			// Client get ack.
++			if d, err := sm.DispositionTimeout(timeout); err != nil || Rejected != d {
++				t.Errorf("want [rejected/nil] got [%v/%v]", d, err)
++			}
++		}
++	}
++}
++
++func TestClientReceiver(t *testing.T) {
++	nMessages := 3
++	client, server := newClientServer(t, func(ep Endpoint) error {
++		if s, ok := ep.(Sender); ok {
++			go func() {
++				for i := int32(0); i < int32(nMessages); i++ {
++					sm, err := s.Send(amqp.NewMessageWith(i))
++					if err != nil {
++						t.Error(err)
++						return
++					} else {
++						sm.Disposition() // Sync send.
++					}
++				}
++				s.Close(nil)
++			}()
++		}
++		return nil
++	})
++
++	r, err := client.Receiver(Source("foo"))
++	if err != nil {
++		t.Fatal(err)
++	}
++	for i := int32(0); i < int32(nMessages); i++ {
++		rm, err := r.Receive()
++		if err != nil {
++			if err != Closed {
++				t.Error(err)
++			}
++			break
++		}
++		if err := rm.Accept(); err != nil {
++			t.Error(err)
++		}
++		if b, ok := rm.Message.Body().(int32); !ok || b != i {
++			t.Errorf("want %v, true got %v, %v", i, b, ok)
++		}
++	}
++	server.Close(nil)
++	client.Connection().Close(nil)
++}
++
++// Test timeout versions of waiting functions.
++func TestTimeouts(t *testing.T) {
++	var err error
++	rchan := make(chan Receiver, 1)
++	client, server := newClientServer(t, func(ep Endpoint) error {
++		if r, ok := ep.(Receiver); ok {
++			r.SetCapacity(1, false) // Issue credit only on receive
++			rchan <- r
++		}
++		return nil
++	})
++	defer func() { closeClientServer(client, server) }()
++
++	// Open client sender
++	snd, err := client.Sender(Target("test"))
++	if err != nil {
++		t.Fatal(err)
++	}
++	rcv := <-rchan
++
++	// Test send with timeout
++	short := time.Millisecond
++	long := time.Second
++	m := amqp.NewMessage()
++	if _, err = snd.SendTimeout(m, 0); err != Timeout { // No credit, expect timeout.
++		t.Error("want Timeout got", err)
++	}
++	if _, err = snd.SendTimeout(m, short); err != Timeout { // No credit, expect timeout.
++		t.Error("want Timeout got", err)
++	}
++	// Test receive with timeout
++	if _, err = rcv.ReceiveTimeout(0); err != Timeout { // No credit, expect timeout.
++		t.Error("want Timeout got", err)
++	}
++	// Test receive with timeout
++	if _, err = rcv.ReceiveTimeout(short); err != Timeout { // No credit, expect timeout.
++		t.Error("want Timeout got", err)
++	}
++	// There is now a credit on the link due to receive
++	sm, err := snd.SendTimeout(m, long)
++	if err != nil {
++		t.Fatal(err)
++	}
++	// Disposition should timeout
++	if _, err = sm.DispositionTimeout(long); err != Timeout {
++		t.Error("want Timeout got", err)
++	}
++	if _, err = sm.DispositionTimeout(short); err != Timeout {
++		t.Error("want Timeout got", err)
++	}
++	// Receive and accept
++	rm, err := rcv.ReceiveTimeout(long)
++	if err != nil {
++		t.Fatal(err)
++	}
++	rm.Accept()
++	// Sender get ack
++	d, err := sm.DispositionTimeout(long)
++	if err != nil || d != Accepted {
++		t.Errorf("want (rejected, nil) got (%v, %v)", d, err)
++	}
++}
++
++// clientServer that returns sender/receiver pairs at opposite ends of link.
++type pairs struct {
++	t      *testing.T
++	client Session
++	server Connection
++	rchan  chan Receiver
++	schan  chan Sender
++}
++
++func newPairs(t *testing.T) *pairs {
++	p := &pairs{t: t, rchan: make(chan Receiver, 1), schan: make(chan Sender, 1)}
++	p.client, p.server = newClientServer(t, func(ep Endpoint) error {
++		switch ep := ep.(type) {
++		case Receiver:
++			ep.SetCapacity(1, false)
++			p.rchan <- ep
++		case Sender:
++			p.schan <- ep
++		}
++		return nil
++	})
++	return p
++}
++
++func (p *pairs) close() {
++	closeClientServer(p.client, p.server)
++}
++
++func (p *pairs) senderReceiver() (Sender, Receiver) {
++	snd, err := p.client.Sender()
++	fatalIf(p.t, err)
++	rcv := <-p.rchan
++	return snd, rcv
++}
++
++func (p *pairs) receiverSender() (Receiver, Sender) {
++	rcv, err := p.client.Receiver()
++	fatalIf(p.t, err)
++	snd := <-p.schan
++	return rcv, snd
++}
++
++type result struct {
++	label string
++	err   error
++}
++
++func (r result) String() string { return fmt.Sprintf("%s(%s)", r.err, r.label) }
++
++func doSend(snd Sender, results chan result) {
++	_, err := snd.Send(amqp.NewMessage())
++	results <- result{"send", err}
++}
++
++func doReceive(rcv Receiver, results chan result) {
++	_, err := rcv.Receive()
++	results <- result{"receive", err}
++}
++
++func doDisposition(sm SentMessage, results chan result) {
++	_, err := sm.Disposition()
++	results <- result{"disposition", err}
++}
++
++// Test that closing Links interrupts blocked link functions.
++func TestLinkCloseInterrupt(t *testing.T) {
++	want := amqp.Errorf("x", "all bad")
++	pairs := newPairs(t)
++	results := make(chan result) // Collect expected errors
++
++	// Sender.Close() interrupts Send()
++	snd, rcv := pairs.senderReceiver()
++	go doSend(snd, results)
++	snd.Close(want)
++	if r := <-results; want != r.err {
++		t.Errorf("want %#v got %#v", want, r)
++	}
++
++	// Remote Receiver.Close() interrupts Send()
++	snd, rcv = pairs.senderReceiver()
++	go doSend(snd, results)
++	rcv.Close(want)
++	if r := <-results; want != r.err {
++		t.Errorf("want %#v got %#v", want, r)
++	}
++
++	// Receiver.Close() interrupts Receive()
++	snd, rcv = pairs.senderReceiver()
++	go doReceive(rcv, results)
++	rcv.Close(want)
++	if r := <-results; want != r.err {
++		t.Errorf("want %#v got %#v", want, r)
++	}
++
++	// Remote Sender.Close() interrupts Receive()
++	snd, rcv = pairs.senderReceiver()
++	go doReceive(rcv, results)
++	snd.Close(want)
++	if r := <-results; want != r.err {
++		t.Errorf("want %#v got %#v", want, r)
++	}
++}
++
++// Test closing the server end of a connection.
++func TestConnectionCloseInterrupt1(t *testing.T) {
++	want := amqp.Errorf("x", "bad")
++	pairs := newPairs(t)
++	results := make(chan result) // Collect expected errors
++
++	// Connection.Close() interrupts Send, Receive, Disposition.
++	snd, rcv := pairs.senderReceiver()
++	go doReceive(rcv, results)
++	sm, err := snd.Send(amqp.NewMessage())
++	fatalIf(t, err)
++	go doDisposition(sm, results)
++	snd, rcv = pairs.senderReceiver()
++	go doSend(snd, results)
++	rcv, snd = pairs.receiverSender()
++	go doReceive(rcv, results)
++	pairs.server.Close(want)
++	for i := 0; i < 3; i++ {
++		if r := <-results; want != r.err {
++			// TODO aconway 2015-10-06: Not propagating the correct error, seeing nil and EOF.
++			t.Logf("want %v got %v", want, r)
++		}
++	}
++}
++
++// Test closing the client end of the connection.
++func TestConnectionCloseInterrupt2(t *testing.T) {
++	want := amqp.Errorf("x", "bad")
++	pairs := newPairs(t)
++	results := make(chan result) // Collect expected errors
++
++	// Connection.Close() interrupts Send, Receive, Disposition.
++	snd, rcv := pairs.senderReceiver()
++	go doReceive(rcv, results)
++	sm, err := snd.Send(amqp.NewMessage())
++	fatalIf(t, err)
++	go doDisposition(sm, results)
++	snd, rcv = pairs.senderReceiver()
++	go doSend(snd, results)
++	rcv, snd = pairs.receiverSender()
++	go doReceive(rcv, results)
++	pairs.client.Close(want)
++	for i := 0; i < 3; i++ {
++		if r := <-results; want != r.err {
++			// TODO aconway 2015-10-06: Not propagating the correct error, seeing nil.
++			t.Logf("want %v got %v", want, r)
++		}
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/receiver.go
----------------------------------------------------------------------
diff --cc electron/receiver.go
index 0000000,0000000..59ac018
new file mode 100644
--- /dev/null
+++ b/electron/receiver.go
@@@ -1,0 -1,0 +1,238 @@@
++/*
++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
++
++import (
++	"qpid.apache.org/amqp"
++	"qpid.apache.org/internal"
++	"qpid.apache.org/proton"
++	"time"
++)
++
++// Receiver is a Link that receives messages.
++//
++type Receiver interface {
++	Link
++
++	// Receive blocks until a message is available or until the Receiver is closed
++	// and has no more buffered messages.
++	Receive() (ReceivedMessage, error)
++
++	// ReceiveTimeout is like Receive but gives up after timeout, see Timeout.
++	//
++	// Note that that if Prefetch is false, after a Timeout the credit issued by
++	// Receive remains on the link. It will be used by the next call to Receive.
++	ReceiveTimeout(timeout time.Duration) (ReceivedMessage, error)
++
++	// Prefetch==true means the Receiver will automatically issue credit to the
++	// remote sender to keep its buffer as full as possible, i.e. it will
++	// "pre-fetch" messages independently of the application calling
++	// Receive(). This gives good throughput for applications that handle a
++	// continuous stream of messages. Larger capacity may improve throughput, the
++	// optimal value depends on the characteristics of your application.
++	//
++	// Prefetch==false means the Receiver will issue only issue credit when you
++	// call Receive(), and will only issue enough credit to satisfy the calls
++	// actually made. This gives lower throughput but will not fetch any messages
++	// in advance. It is good for synchronous applications that need to evaluate
++	// each message before deciding whether to receive another. The
++	// request-response pattern is a typical example.  If you make concurrent
++	// calls to Receive with pre-fetch disabled, you can improve performance by
++	// setting the capacity close to the expected number of concurrent calls.
++	//
++	Prefetch() bool
++
++	// Capacity is the size (number of messages) of the local message buffer
++	// These are messages received but not yet returned to the application by a call to Receive()
++	Capacity() int
++}
++
++// Flow control policy for a receiver.
++type policy interface {
++	// Called at the start of Receive() to adjust credit before fetching a message.
++	Pre(*receiver)
++	// Called after Receive() has received a message from Buffer() before it returns.
++	// Non-nil error means no message was received because of an error.
++	Post(*receiver, error)
++}
++
++type prefetchPolicy struct{}
++
++func (p prefetchPolicy) Flow(r *receiver) {
++	r.engine().Inject(func() {
++		_, _, max := r.credit()
++		if max > 0 {
++			r.eLink.Flow(max)
++		}
++	})
++}
++func (p prefetchPolicy) Pre(r *receiver) { p.Flow(r) }
++func (p prefetchPolicy) Post(r *receiver, err error) {
++	if err == nil {
++		p.Flow(r)
++	}
++}
++
++type noPrefetchPolicy struct{ waiting int }
++
++func (p noPrefetchPolicy) Flow(r *receiver) { // Not called in proton goroutine
++	r.engine().Inject(func() {
++		len, credit, max := r.credit()
++		add := p.waiting - (len + credit)
++		if add > max {
++			add = max // Don't overflow
++		}
++		if add > 0 {
++			r.eLink.Flow(add)
++		}
++	})
++}
++func (p noPrefetchPolicy) Pre(r *receiver) { p.waiting++; p.Flow(r) }
++func (p noPrefetchPolicy) Post(r *receiver, err error) {
++	p.waiting--
++	if err == nil {
++		p.Flow(r)
++	}
++}
++
++// Receiver implementation
++type receiver struct {
++	link
++	buffer chan ReceivedMessage
++	policy policy
++}
++
++func newReceiver(l link) *receiver {
++	r := &receiver{link: l}
++	if r.capacity < 1 {
++		r.capacity = 1
++	}
++	if r.prefetch {
++		r.policy = &prefetchPolicy{}
++	} else {
++		r.policy = &noPrefetchPolicy{}
++	}
++	r.buffer = make(chan ReceivedMessage, r.capacity)
++	r.handler().addLink(r.eLink, r)
++	r.link.open()
++	return r
++}
++
++// call in proton goroutine.
++func (r *receiver) credit() (buffered, credit, max int) {
++	return len(r.buffer), r.eLink.Credit(), cap(r.buffer) - len(r.buffer)
++}
++
++func (r *receiver) Capacity() int  { return cap(r.buffer) }
++func (r *receiver) Prefetch() bool { return r.prefetch }
++
++func (r *receiver) Receive() (rm ReceivedMessage, err error) {
++	return r.ReceiveTimeout(Forever)
++}
++
++func (r *receiver) ReceiveTimeout(timeout time.Duration) (rm ReceivedMessage, err error) {
++	internal.Assert(r.buffer != nil, "Receiver is not open: %s", r)
++	r.policy.Pre(r)
++	defer func() { r.policy.Post(r, err) }()
++	rmi, err := timedReceive(r.buffer, timeout)
++	switch err {
++	case Timeout:
++		return ReceivedMessage{}, Timeout
++	case Closed:
++		return ReceivedMessage{}, r.Error()
++	default:
++		return rmi.(ReceivedMessage), nil
++	}
++}
++
++// Called in proton goroutine on MMessage event.
++func (r *receiver) message(delivery proton.Delivery) {
++	if r.eLink.State().RemoteClosed() {
++		localClose(r.eLink, r.eLink.RemoteCondition().Error())
++		return
++	}
++	if delivery.HasMessage() {
++		m, err := delivery.Message()
++		if err != nil {
++			localClose(r.eLink, err)
++			return
++		}
++		internal.Assert(m != nil)
++		r.eLink.Advance()
++		if r.eLink.Credit() < 0 {
++			localClose(r.eLink, internal.Errorf("received message in excess of credit limit"))
++		} else {
++			// We never issue more credit than cap(buffer) so this will not block.
++			r.buffer <- ReceivedMessage{m, delivery, r}
++		}
++	}
++}
++
++func (r *receiver) closed(err error) {
++	r.link.closed(err)
++	if r.buffer != nil {
++		close(r.buffer)
++	}
++}
++
++// ReceivedMessage contains an amqp.Message and allows the message to be acknowledged.
++type ReceivedMessage struct {
++	// Message is the received message.
++	Message amqp.Message
++
++	eDelivery proton.Delivery
++	receiver  Receiver
++}
++
++// Acknowledge a ReceivedMessage with the given disposition code.
++func (rm *ReceivedMessage) Acknowledge(disposition Disposition) error {
++	return rm.receiver.(*receiver).engine().InjectWait(func() error {
++		// Settle doesn't return an error but if the receiver is broken the settlement won't happen.
++		rm.eDelivery.SettleAs(uint64(disposition))
++		return rm.receiver.Error()
++	})
++}
++
++// Accept is short for Acknowledge(Accpeted)
++func (rm *ReceivedMessage) Accept() error { return rm.Acknowledge(Accepted) }
++
++// Reject is short for Acknowledge(Rejected)
++func (rm *ReceivedMessage) Reject() error { return rm.Acknowledge(Rejected) }
++
++// IncomingReceiver is passed to the accept() function given to Connection.Listen()
++// when there is an incoming request for a receiver link.
++type IncomingReceiver struct {
++	incomingLink
++}
++
++// Link provides information about the incoming link.
++func (i *IncomingReceiver) Link() Link { return i }
++
++// AcceptReceiver sets Capacity and Prefetch of the accepted Receiver.
++func (i *IncomingReceiver) AcceptReceiver(capacity int, prefetch bool) Receiver {
++	i.capacity = capacity
++	i.prefetch = prefetch
++	return i.Accept().(Receiver)
++}
++
++func (i *IncomingReceiver) Accept() Endpoint {
++	i.accepted = true
++	return newReceiver(i.link)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/sender.go
----------------------------------------------------------------------
diff --cc electron/sender.go
index 0000000,0000000..68cfbb3
new file mode 100644
--- /dev/null
+++ b/electron/sender.go
@@@ -1,0 -1,0 +1,315 @@@
++/*
++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
++
++// #include <proton/disposition.h>
++import "C"
++
++import (
++	"qpid.apache.org/amqp"
++	"qpid.apache.org/internal"
++	"qpid.apache.org/proton"
++	"reflect"
++	"time"
++)
++
++// Sender is a Link that sends messages.
++type Sender interface {
++	Link
++
++	// Send a message without waiting for acknowledgement. Returns a SentMessage.
++	// use SentMessage.Disposition() to wait for acknowledgement and get the
++	// disposition code.
++	//
++	// If the send buffer is full, send blocks until there is space in the buffer.
++	Send(m amqp.Message) (sm SentMessage, err error)
++
++	// SendTimeout is like send but only waits up to timeout for buffer space.
++	//
++	// Returns Timeout error if the timeout expires and the message has not been sent.
++	SendTimeout(m amqp.Message, timeout time.Duration) (sm SentMessage, err error)
++
++	// Send a message and forget it, there will be no acknowledgement.
++	// If the send buffer is full, send blocks until there is space in the buffer.
++	SendForget(m amqp.Message) error
++
++	// SendForgetTimeout is like send but only waits up to timeout for buffer space.
++	// Returns Timeout error if the timeout expires and the message has not been sent.
++	SendForgetTimeout(m amqp.Message, timeout time.Duration) error
++
++	// Credit indicates how many messages the receiving end of the link can accept.
++	//
++	// On a Sender credit can be negative, meaning that messages in excess of the
++	// receiver's credit limit have been buffered locally till credit is available.
++	Credit() (int, error)
++}
++
++type sendMessage struct {
++	m  amqp.Message
++	sm SentMessage
++}
++
++type sender struct {
++	link
++	credit chan struct{} // Signal available credit.
++}
++
++// Disposition indicates the outcome of a settled message delivery.
++type Disposition uint64
++
++const (
++	// No disposition available: pre-settled, not yet acknowledged or an error occurred
++	NoDisposition Disposition = 0
++	// Message was accepted by the receiver
++	Accepted = proton.Accepted
++	// Message was rejected as invalid by the receiver
++	Rejected = proton.Rejected
++	// Message was not processed by the receiver but may be processed by some other receiver.
++	Released = proton.Released
++)
++
++// String human readable name for a Disposition.
++func (d Disposition) String() string {
++	switch d {
++	case NoDisposition:
++		return "no-disposition"
++	case Accepted:
++		return "accepted"
++	case Rejected:
++		return "rejected"
++	case Released:
++		return "released"
++	default:
++		return "unknown"
++	}
++}
++
++func (s *sender) Send(m amqp.Message) (SentMessage, error) {
++	return s.SendTimeout(m, Forever)
++}
++
++func (s *sender) SendTimeout(m amqp.Message, timeout time.Duration) (SentMessage, error) {
++	var sm SentMessage
++	if s.sndSettle == SndSettled {
++		sm = nil
++	} else {
++		sm = newSentMessage(s.session.connection)
++	}
++	return s.sendInternal(sendMessage{m, sm}, timeout)
++}
++
++func (s *sender) SendForget(m amqp.Message) error {
++	return s.SendForgetTimeout(m, Forever)
++}
++
++func (s *sender) SendForgetTimeout(m amqp.Message, timeout time.Duration) error {
++	snd := sendMessage{m, nil}
++	_, err := s.sendInternal(snd, timeout)
++	return err
++}
++
++func (s *sender) sendInternal(snd sendMessage, timeout time.Duration) (SentMessage, error) {
++	if _, err := timedReceive(s.credit, timeout); err != nil { // Wait for credit
++		if err == Closed {
++			err = s.Error()
++			internal.Assert(err != nil)
++		}
++		return nil, err
++	}
++	if err := s.engine().Inject(func() { s.doSend(snd) }); err != nil {
++		return nil, err
++	}
++	return snd.sm, nil
++}
++
++// Send a message. Handler goroutine
++func (s *sender) doSend(snd sendMessage) {
++	delivery, err := s.eLink.Send(snd.m)
++	switch sm := snd.sm.(type) {
++	case nil:
++		delivery.Settle()
++	case *sentMessage:
++		sm.delivery = delivery
++		if err != nil {
++			sm.settled(err)
++		} else {
++			s.handler().sentMessages[delivery] = sm
++		}
++	default:
++		internal.Assert(false, "bad SentMessage type %T", snd.sm)
++	}
++	if s.eLink.Credit() > 0 {
++		s.sendable() // Signal credit.
++	}
++}
++
++// Signal the sender has credit. Any goroutine.
++func (s *sender) sendable() {
++	select { // Non-blocking
++	case s.credit <- struct{}{}: // Set the flag if not already set.
++	default:
++	}
++}
++
++func (s *sender) closed(err error) {
++	s.link.closed(err)
++	close(s.credit)
++}
++
++func newSender(l link) *sender {
++	s := &sender{link: l, credit: make(chan struct{}, 1)}
++	s.handler().addLink(s.eLink, s)
++	s.link.open()
++	return s
++}
++
++// SentMessage represents a previously sent message. It allows you to wait for acknowledgement.
++type SentMessage interface {
++
++	// Disposition blocks till the message is acknowledged and returns the
++	// disposition state.
++	//
++	// NoDisposition with Error() != nil means the Connection was closed before
++	// the message was acknowledged.
++	//
++	// NoDisposition with Error() == nil means the message was pre-settled or
++	// Forget() was called.
++	Disposition() (Disposition, error)
++
++	// DispositionTimeout is like Disposition but gives up after timeout, see Timeout.
++	DispositionTimeout(time.Duration) (Disposition, error)
++
++	// Forget interrupts any call to Disposition on this SentMessage and tells the
++	// peer we are no longer interested in the disposition of this message.
++	Forget()
++
++	// Error returns the error that closed the disposition, or nil if there was no error.
++	// If the disposition closed because the connection closed, it will return Closed.
++	Error() error
++
++	// Value is an optional value you wish to associate with the SentMessage. It
++	// can be the message itself or some form of identifier.
++	Value() interface{}
++	SetValue(interface{})
++}
++
++// SentMessageSet is a concurrent-safe set of sent messages that can be checked
++// to get the next completed sent message
++type SentMessageSet struct {
++	cases []reflect.SelectCase
++	sm    []SentMessage
++	done  chan SentMessage
++}
++
++func (s *SentMessageSet) Add(sm SentMessage) {
++	s.sm = append(s.sm, sm)
++	s.cases = append(s.cases, reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sm.(*sentMessage).done)})
++}
++
++// Wait waits up to timeout and returns the next SentMessage that has a valid dispositionb
++// or an error.
++func (s *SentMessageSet) Wait(sm SentMessage, timeout time.Duration) (SentMessage, error) {
++	s.cases = s.cases[:len(s.sm)] // Remove previous timeout cases
++	if timeout == 0 {             // Non-blocking
++		s.cases = append(s.cases, reflect.SelectCase{Dir: reflect.SelectDefault})
++	} else {
++		s.cases = append(s.cases,
++			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(After(timeout))})
++	}
++	chosen, _, _ := reflect.Select(s.cases)
++	if chosen > len(s.sm) {
++		return nil, Timeout
++	} else {
++		sm := s.sm[chosen]
++		s.sm = append(s.sm[:chosen], s.sm[chosen+1:]...)
++		return sm, nil
++	}
++}
++
++// SentMessage implementation
++type sentMessage struct {
++	connection  *connection
++	done        chan struct{}
++	delivery    proton.Delivery
++	disposition Disposition
++	err         error
++	value       interface{}
++}
++
++func newSentMessage(c *connection) *sentMessage {
++	return &sentMessage{connection: c, done: make(chan struct{})}
++}
++
++func (sm *sentMessage) SetValue(v interface{}) { sm.value = v }
++func (sm *sentMessage) Value() interface{}     { return sm.value }
++func (sm *sentMessage) Disposition() (Disposition, error) {
++	<-sm.done
++	return sm.disposition, sm.err
++}
++
++func (sm *sentMessage) DispositionTimeout(timeout time.Duration) (Disposition, error) {
++	if _, err := timedReceive(sm.done, timeout); err == Timeout {
++		return sm.disposition, Timeout
++	} else {
++		return sm.disposition, sm.err
++	}
++}
++
++func (sm *sentMessage) Forget() {
++	sm.connection.engine.Inject(func() {
++		sm.delivery.Settle()
++		delete(sm.connection.handler.sentMessages, sm.delivery)
++	})
++	sm.finish()
++}
++
++func (sm *sentMessage) settled(err error) {
++	if sm.delivery.Settled() {
++		sm.disposition = Disposition(sm.delivery.Remote().Type())
++	}
++	sm.err = err
++	sm.finish()
++}
++
++func (sm *sentMessage) finish() {
++	select {
++	case <-sm.done: // No-op if already closed
++	default:
++		close(sm.done)
++	}
++}
++
++func (sm *sentMessage) Error() error { return sm.err }
++
++// IncomingSender is passed to the accept() function given to Connection.Listen()
++// when there is an incoming request for a sender link.
++type IncomingSender struct {
++	incomingLink
++}
++
++// Link provides information about the incoming link.
++func (i *IncomingSender) Link() Link { return i }
++
++func (i *IncomingSender) AcceptSender() Sender { return i.Accept().(Sender) }
++
++func (i *IncomingSender) Accept() Endpoint {
++	i.accepted = true
++	return newSender(i.link)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/session.go
----------------------------------------------------------------------
diff --cc electron/session.go
index 0000000,0000000..3531da6
new file mode 100644
--- /dev/null
+++ b/electron/session.go
@@@ -1,0 -1,0 +1,125 @@@
++/*
++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
++
++import (
++	"qpid.apache.org/proton"
++)
++
++// Session is an AMQP session, it contains Senders and Receivers.
++type Session interface {
++	Endpoint
++
++	// Sender opens a new sender. v can be a string, which is used as the Target
++	// address, or a SenderSettings struct containing more details settings.
++	Sender(...LinkSetting) (Sender, error)
++
++	// Receiver opens a new Receiver. v can be a string, which is used as the
++	// Source address, or a ReceiverSettings struct containing more details
++	// settings.
++	Receiver(...LinkSetting) (Receiver, error)
++}
++
++type session struct {
++	endpoint
++	eSession   proton.Session
++	connection *connection
++	capacity   uint
++}
++
++// SessionSetting can be passed when creating a sender or receiver.
++// See functions that return SessionSetting for details
++type SessionSetting func(*session)
++
++// IncomingCapacity sets the size (in bytes) of the sessions incoming data buffer..
++func IncomingCapacity(cap uint) SessionSetting { return func(s *session) { s.capacity = cap } }
++
++// in proton goroutine
++func newSession(c *connection, es proton.Session, setting ...SessionSetting) *session {
++	s := &session{
++		connection: c,
++		eSession:   es,
++		endpoint:   endpoint{str: es.String()},
++	}
++	for _, set := range setting {
++		set(s)
++	}
++	c.handler.sessions[s.eSession] = s
++	s.eSession.SetIncomingCapacity(s.capacity)
++	s.eSession.Open()
++	return s
++}
++
++func (s *session) Connection() Connection     { return s.connection }
++func (s *session) eEndpoint() proton.Endpoint { return s.eSession }
++func (s *session) engine() *proton.Engine     { return s.connection.engine }
++func (s *session) Close(err error) {
++	s.engine().Inject(func() { localClose(s.eSession, err) })
++}
++
++func (s *session) SetCapacity(bytes uint) { s.capacity = bytes }
++
++func (s *session) Sender(setting ...LinkSetting) (snd Sender, err error) {
++	err = s.engine().InjectWait(func() error {
++		l, err := localLink(s, true, setting...)
++		if err == nil {
++			snd = newSender(l)
++		}
++		return err
++	})
++	return
++}
++
++func (s *session) Receiver(setting ...LinkSetting) (rcv Receiver, err error) {
++	err = s.engine().InjectWait(func() error {
++		l, err := localLink(s, false, setting...)
++		if err == nil {
++			rcv = newReceiver(l)
++		}
++		return err
++	})
++	return
++}
++
++// Called from handler on closed.
++func (s *session) closed(err error) {
++	s.err.Set(err)
++	s.err.Set(Closed)
++}
++
++// IncomingSession is passed to the accept() function given to Connection.Listen()
++// when there is an incoming session request.
++type IncomingSession struct {
++	incoming
++	h        *handler
++	pSession proton.Session
++	capacity uint
++}
++
++// AcceptCapacity sets the session buffer capacity of an incoming session in bytes.
++func (i *IncomingSession) AcceptSession(bytes uint) Session {
++	i.capacity = bytes
++	return i.Accept().(Session)
++}
++
++func (i *IncomingSession) Accept() Endpoint {
++	i.accepted = true
++	return newSession(i.h.connection, i.pSession, IncomingCapacity(i.capacity))
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/time.go
----------------------------------------------------------------------
diff --cc electron/time.go
index 0000000,0000000..3407b82
new file mode 100644
--- /dev/null
+++ b/electron/time.go
@@@ -1,0 -1,0 +1,82 @@@
++/*
++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
++
++import (
++	"qpid.apache.org/internal"
++	"reflect"
++	"time"
++)
++
++// Timeout is the error returned if an operation does not complete on time.
++//
++// Methods named *Timeout in this package take time.Duration timeout parameter.
++//
++// If timeout > 0 and there is no result available before the timeout, they
++// return a zero or nil value and Timeout as an error.
++//
++// If timeout == 0 they will return a result if one is immediatley available or
++// nil/zero and Timeout as an error if not.
++//
++// If timeout == Forever the function will return only when there is a result or
++// some non-timeout error occurs.
++//
++var Timeout = internal.Errorf("timeout")
++
++// Forever can be used as a timeout parameter to indicate wait forever.
++const Forever time.Duration = -1
++
++// timedReceive receives on channel (which can be a chan of any type), waiting
++// up to timeout.
++//
++// timeout==0 means do a non-blocking receive attempt. timeout < 0 means block
++// forever. Other values mean block up to the timeout.
++//
++// Returns error Timeout on timeout, Closed on channel close.
++func timedReceive(channel interface{}, timeout time.Duration) (interface{}, error) {
++	cases := []reflect.SelectCase{
++		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(channel)},
++	}
++	if timeout == 0 { // Non-blocking
++		cases = append(cases, reflect.SelectCase{Dir: reflect.SelectDefault})
++	} else { // Block up to timeout
++		cases = append(cases,
++			reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(After(timeout))})
++	}
++	chosen, value, ok := reflect.Select(cases)
++	switch {
++	case !ok:
++		return nil, Closed
++	case chosen == 0:
++		return value.Interface(), nil
++	default:
++		return nil, Timeout
++	}
++}
++
++// After is like time.After but returns a nil channel if timeout == Forever
++// since selecting on a nil channel will never return.
++func After(timeout time.Duration) <-chan time.Time {
++	if timeout == Forever {
++		return nil
++	} else {
++		return time.After(timeout)
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/internal/error.go
----------------------------------------------------------------------
diff --cc internal/error.go
index 0000000,0000000..1b108e6
new file mode 100644
--- /dev/null
+++ b/internal/error.go
@@@ -1,0 -1,0 +1,118 @@@
++/*
++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 internal
++
++// #cgo LDFLAGS: -lqpid-proton
++// #include <proton/error.h>
++// #include <proton/codec.h>
++import "C"
++
++import (
++	"fmt"
++	"sync"
++	"sync/atomic"
++	"unsafe"
++)
++
++// Error type for proton runtime errors returned as error values.
++type Error string
++
++// Error prefixes error message with proton:
++func (e Error) Error() string {
++	return "proton: " + string(e)
++}
++
++// Errorf creates an Error with a formatted message
++func Errorf(format string, a ...interface{}) Error {
++	return Error(fmt.Sprintf(format, a...))
++}
++
++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(p unsafe.Pointer) error {
++	e := (*C.pn_error_t)(p)
++	if e == nil || C.pn_error_code(e) == 0 {
++		return nil
++	}
++	return Errorf("%s: %s", PnErrorCode(C.pn_error_code(e)), C.GoString(C.pn_error_text(e)))
++}
++
++// panicIf panics if condition is true, the panic value is Errorf(fmt, args...)
++func panicIf(condition bool, fmt string, args ...interface{}) {
++	if condition {
++		panic(Errorf(fmt, args...))
++	}
++}
++
++// 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(Errorf(format[0].(string), format[1:]...))
++		} else {
++			panic(Errorf("assertion failed"))
++		}
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/internal/flexchannel.go
----------------------------------------------------------------------
diff --cc internal/flexchannel.go
index 0000000,0000000..77b524c
new file mode 100644
--- /dev/null
+++ b/internal/flexchannel.go
@@@ -1,0 -1,0 +1,82 @@@
++/*
++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 internal
++
++// FlexChannel acts like a channel with an automatically sized buffer, see NewFlexChannel().
++type FlexChannel struct {
++	// In channel to send to. close(In) will close the FlexChannel once buffer has drained.
++	In chan<- interface{}
++	// Out channel to receive from. Out closes when In has closed and the buffer is empty.
++	Out <-chan interface{}
++
++	in, out chan interface{}
++	buffer  []interface{}
++	limit   int
++}
++
++// NewFlexChannel creates a FlexChannel, a channel with an automatically-sized buffer.
++//
++// Initially the buffer size is 0, the buffer grows as needed up to limit. limit < 0 means
++// there is no limit.
++//
++func NewFlexChannel(limit int) *FlexChannel {
++	fc := &FlexChannel{
++		in:     make(chan interface{}),
++		out:    make(chan interface{}),
++		buffer: make([]interface{}, 0),
++		limit:  limit,
++	}
++	fc.In = fc.in
++	fc.Out = fc.out
++	go fc.run()
++	return fc
++}
++
++func (fc *FlexChannel) run() {
++	defer func() { // Flush the channel on exit
++		for _, data := range fc.buffer {
++			fc.out <- data
++		}
++		close(fc.out)
++	}()
++
++	for {
++		var usein, useout chan interface{}
++		var outvalue interface{}
++		if len(fc.buffer) > 0 {
++			useout = fc.out
++			outvalue = fc.buffer[0]
++		}
++		if len(fc.buffer) < fc.limit || fc.limit < 0 {
++			usein = fc.in
++		}
++		Assert(usein != nil || useout != nil)
++		select {
++		case useout <- outvalue:
++			fc.buffer = fc.buffer[1:]
++		case data, ok := <-usein:
++			if ok {
++				fc.buffer = append(fc.buffer, data)
++			} else {
++				return
++			}
++		}
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/internal/flexchannel_test.go
----------------------------------------------------------------------
diff --cc internal/flexchannel_test.go
index 0000000,0000000..d0e1a44
new file mode 100644
--- /dev/null
+++ b/internal/flexchannel_test.go
@@@ -1,0 -1,0 +1,89 @@@
++/*
++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 internal
++
++import (
++	"testing"
++)
++
++func recvall(ch <-chan interface{}) (result []interface{}) {
++	for {
++		select {
++		case x := <-ch:
++			result = append(result, x)
++		default:
++			return
++		}
++	}
++}
++
++func sendall(data []interface{}, ch chan<- interface{}) {
++}
++
++func TestFlex(t *testing.T) {
++	fc := NewFlexChannel(5)
++
++	// Test send/receve
++	go func() {
++		for i := 0; i < 4; i++ {
++			fc.In <- i
++		}
++	}()
++
++	for i := 0; i < 4; i++ {
++		j := <-fc.Out
++		if i != j {
++			t.Error("%v != %v", i, j)
++		}
++	}
++	select {
++	case x, ok := <-fc.Out:
++		t.Error("receive empty channel got", x, ok)
++	default:
++	}
++
++	// Test buffer limit
++	for i := 10; i < 15; i++ {
++		fc.In <- i
++	}
++	select {
++	case fc.In <- 0:
++		t.Error("send to full channel did not block")
++	default:
++	}
++	i := <-fc.Out
++	if i != 10 {
++		t.Error("%v != %v", i, 10)
++	}
++	fc.In <- 15
++	close(fc.In)
++
++	for i := 11; i < 16; i++ {
++		j := <-fc.Out
++		if i != j {
++			t.Error("%v != %v", i, j)
++		}
++	}
++
++	x, ok := <-fc.Out
++	if ok {
++		t.Error("Unexpected value on Out", x)
++	}
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/internal/safemap.go
----------------------------------------------------------------------
diff --cc internal/safemap.go
index 0000000,0000000..3a1fe2b
new file mode 100644
--- /dev/null
+++ b/internal/safemap.go
@@@ -1,0 -1,0 +1,57 @@@
++/*
++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 internal
++
++import (
++	"sync"
++)
++
++// SafeMap is a goroutine-safe map of interface{} to interface{}.
++type SafeMap struct {
++	m    map[interface{}]interface{}
++	lock sync.Mutex
++}
++
++func MakeSafeMap() SafeMap { return SafeMap{m: make(map[interface{}]interface{})} }
++
++func (m *SafeMap) Get(key interface{}) interface{} {
++	m.lock.Lock()
++	defer m.lock.Unlock()
++	return m.m[key]
++}
++
++func (m *SafeMap) GetOk(key interface{}) (interface{}, bool) {
++	m.lock.Lock()
++	defer m.lock.Unlock()
++	v, ok := m.m[key]
++	return v, ok
++}
++
++func (m *SafeMap) Put(key, value interface{}) {
++	m.lock.Lock()
++	defer m.lock.Unlock()
++	m.m[key] = value
++}
++
++func (m *SafeMap) Delete(key interface{}) {
++	m.lock.Lock()
++	defer m.lock.Unlock()
++	delete(m.m, key)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/internal/uuid.go
----------------------------------------------------------------------
diff --cc internal/uuid.go
index 0000000,0000000..ef941a1
new file mode 100644
--- /dev/null
+++ b/internal/uuid.go
@@@ -1,0 -1,0 +1,70 @@@
++/*
++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 internal
++
++import (
++	"fmt"
++	"math/rand"
++	"strconv"
++	"sync"
++	"sync/atomic"
++	"time"
++)
++
++type UUID [16]byte
++
++func (u UUID) String() string {
++	return fmt.Sprintf("%X-%X-%X-%X-%X", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
++}
++
++// Don't mess with the default random source.
++var randomSource = rand.NewSource(time.Now().UnixNano())
++var randomLock sync.Mutex
++
++func random() byte {
++	randomLock.Lock()
++	defer randomLock.Unlock()
++	return byte(randomSource.Int63())
++}
++
++func UUID4() UUID {
++	var u UUID
++	for i := 0; i < len(u); i++ {
++		u[i] = random()
++	}
++	// See /https://tools.ietf.org/html/rfc4122#section-4.4
++	u[6] = (u[6] & 0x0F) | 0x40 // Version bits to 4
++	u[8] = (u[8] & 0x3F) | 0x80 // Reserved bits (top two) set to 01
++	return u
++}
++
++// A simple atomic counter to generate unique 64 bit IDs.
++type IdCounter struct{ count uint64 }
++
++// NextInt gets the next uint64 value from the atomic counter.
++func (uc *IdCounter) NextInt() uint64 {
++	return atomic.AddUint64(&uc.count, 1)
++}
++
++// Next gets the next integer value encoded as a base32 string, safe for NUL
++// terminated C strings.
++func (uc *IdCounter) Next() string {
++	return strconv.FormatUint(uc.NextInt(), 32)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/doc.go
----------------------------------------------------------------------
diff --cc proton/doc.go
index 34f85fe,0000000..51f70f8
mode 100644,000000..100644
--- a/proton/doc.go
+++ b/proton/doc.go
@@@ -1,33 -1,0 +1,70 @@@
 +/*
 +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 is a Go binding for the proton AMQP protocol engine.
++Package proton is an event-driven, concurrent-unsafe Go library for AMQP messaging.
++You can write clients and servers using this library.
 +
- It alows you to construct and parse AMQP messages, and to implement AMQP
- clients, servers and intermediaries that can exchange messages with any
- AMQP 1.0 compliant endpoint.
++This package is a port of the Proton C API into Go (see
++http://qpid.apache.org/proton) Go programmers may find the 'electron' package
++more convenient. qpid.apache.org/electron provides a concurrent-safe API that
++allows you to run procedural loops in arbitrary goroutines rather than
++implementing event handlers that must run in a single goroutine.
++
++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.
 +
- Encoding and decoding AMQP data follows the pattern of the standard
- encoding/json and encoding/xml packages.The mapping between AMQP and Go types is
- described in the documentation of the Marshal and Unmarshal functions.
 +*/
 +package proton
 +
++// #cgo LDFLAGS: -lqpid-proton
++import "C"
++
 +// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/proton/engine.go
----------------------------------------------------------------------
diff --cc proton/engine.go
index 0000000,0000000..2cebb49
new file mode 100644
--- /dev/null
+++ b/proton/engine.go
@@@ -1,0 -1,0 +1,402 @@@
++/*
++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
++
++// #include <proton/connection.h>
++// #include <proton/event.h>
++// #include <proton/handlers.h>
++// #include <proton/session.h>
++// #include <proton/transport.h>
++// #include <memory.h>
++// #include <stdlib.h>
++//
++// PN_HANDLE(REMOTE_ADDR)
++import "C"
++
++import (
++	"fmt"
++	"io"
++	"net"
++	"qpid.apache.org/internal"
++	"sync"
++	"unsafe"
++)
++
++// Injecter allows functions to be "injected" into the event-processing loop, to
++// be called in the same goroutine as event handlers.
++type Injecter interface {
++	// Inject a function into the engine goroutine.
++	//
++	// f() will be called in the same goroutine as event handlers, so it can safely
++	// use values belonging to event handlers without synchronization. f() should
++	// not block, no further events or injected functions can be processed until
++	// f() returns.
++	//
++	// Returns a non-nil error if the function could not be injected and will
++	// never be called. Otherwise the function will eventually be called.
++	//
++	// Note that proton values (Link, Session, Connection etc.) that existed when
++	// Inject(f) was called may have become invalid by the time f() is executed.
++	// Handlers should handle keep track of Closed events to ensure proton values
++	// are not used after they become invalid. One technique is to have map from
++	// proton values to application values. Check that the map has the correct
++	// proton/application value pair at the start of the injected function and
++	// delete the value from the map when handling a Closed event.
++	Inject(f func()) error
++
++	// InjectWait is like Inject but does not return till f() has completed.
++	// If f() cannot be injected it returns the error from Inject(), otherwise
++	// it returns the error from f()
++	InjectWait(f func() error) error
++}
++
++// bufferChan manages a pair of ping-pong buffers to pass bytes through a channel.
++type bufferChan struct {
++	buffers    chan []byte
++	buf1, buf2 []byte
++}
++
++func newBufferChan(size int) *bufferChan {
++	return &bufferChan{make(chan []byte), make([]byte, size), make([]byte, size)}
++}
++
++func (b *bufferChan) buffer() []byte {
++	b.buf1, b.buf2 = b.buf2, b.buf1 // Alternate buffers.
++	return b.buf1[:cap(b.buf1)]
++}
++
++// Engine reads from a net.Conn, decodes AMQP events and calls the appropriate
++// Handler functions sequentially in a single goroutine. Actions taken by
++// Handler functions (such as sending messages) are encoded and written to the
++// net.Conn. You can create multiple Engines to handle multiple connections
++// concurrently.
++//
++// You implement the EventHandler and/or MessagingHandler interfaces and provide
++// those values to NewEngine(). Their HandleEvent method will be called in the
++// event-handling goroutine.
++//
++// Handlers can pass values from an event (Connections, Links, Deliveries etc.) to
++// other goroutines, store them, or use them as map indexes. Effectively they are
++// just pointers.  Other goroutines cannot call their methods directly but they can
++// can create a function closure to call such methods and pass it to Engine.Inject()
++// to have it evaluated in the engine goroutine.
++//
++// You are responsible for ensuring you don't use an event value after it is
++// invalid. The handler methods will tell you when a value is no longer valid. For
++// example after a LinkClosed event, that link is no longer valid. If you do
++// Link.Close() yourself (in a handler or injected function) the link remains valid
++// until the corresponing LinkClosed event is received by the handler.
++//
++// Engine.Close() will take care of cleaning up any remaining values when you are
++// done with the Engine. All values associated with a engine become invalid when you
++// call Engine.Close()
++//
++// The qpid.apache.org/proton/concurrent package will do all this for you, so it
++// may be a better choice for some applications.
++//
++type Engine struct {
++	// Error is set on exit from Run() if there was an error.
++	err    internal.ErrorHolder
++	inject chan func()
++
++	conn       net.Conn
++	connection Connection
++	transport  Transport
++	collector  *C.pn_collector_t
++	read       *bufferChan    // Read buffers channel.
++	write      *bufferChan    // Write buffers channel.
++	handlers   []EventHandler // Handlers for proton events.
++	running    chan struct{}  // This channel will be closed when the goroutines are done.
++	closeOnce  sync.Once
++}
++
++const bufferSize = 4096
++
++// Map of Connection to *Engine
++var engines = internal.MakeSafeMap()
++
++// NewEngine initializes a engine with a connection and handlers. To start it running:
++//    eng := NewEngine(...)
++//    go run eng.Run()
++// The goroutine will exit when the engine is closed or disconnected.
++// You can check for errors on Engine.Error.
++//
++func NewEngine(conn net.Conn, handlers ...EventHandler) (*Engine, error) {
++	// Save the connection ID for Connection.String()
++	eng := &Engine{
++		inject:     make(chan func()),
++		conn:       conn,
++		transport:  Transport{C.pn_transport()},
++		connection: Connection{C.pn_connection()},
++		collector:  C.pn_collector(),
++		handlers:   handlers,
++		read:       newBufferChan(bufferSize),
++		write:      newBufferChan(bufferSize),
++		running:    make(chan struct{}),
++	}
++	if eng.transport.IsNil() || eng.connection.IsNil() || eng.collector == nil {
++		return nil, internal.Errorf("failed to allocate engine")
++	}
++
++	// TODO aconway 2015-06-25: connection settings for user, password, container etc.
++	// before transport.Bind() Set up connection before Engine, allow Engine or Reactor
++	// to run connection.
++
++	// Unique container-id by default.
++	eng.connection.SetContainer(internal.UUID4().String())
++	pnErr := eng.transport.Bind(eng.connection)
++	if pnErr != 0 {
++		return nil, internal.Errorf("cannot setup engine: %s", internal.PnErrorCode(pnErr))
++	}
++	C.pn_connection_collect(eng.connection.pn, eng.collector)
++	eng.connection.Open()
++	connectionContexts.Put(eng.connection, connectionContext{eng.String()})
++	return eng, nil
++}
++
++func (eng *Engine) String() string {
++	return fmt.Sprintf("%s-%s", eng.conn.LocalAddr(), eng.conn.RemoteAddr())
++}
++
++func (eng *Engine) Id() string {
++	return fmt.Sprintf("%eng", &eng)
++}
++
++func (eng *Engine) Error() error {
++	return eng.err.Get()
++}
++
++// Inject a function into the Engine's event loop.
++//
++// f() will be called in the same event-processing goroutine that calls Handler
++// methods. f() can safely call methods on values that belong to this engine
++// (Sessions, Links etc)
++//
++// The injected function has no parameters or return values. It is normally a
++// closure and can use channels to communicate with the injecting goroutine if
++// necessary.
++//
++// Returns a non-nil error if the engine is closed before the function could be
++// injected.
++func (eng *Engine) Inject(f func()) error {
++	select {
++	case eng.inject <- f:
++		return nil
++	case <-eng.running:
++		return eng.Error()
++	}
++}
++
++// InjectWait is like Inject but does not return till f() has completed or the
++// engine is closed, and returns an error value from f()
++func (eng *Engine) InjectWait(f func() error) error {
++	done := make(chan error)
++	defer close(done)
++	err := eng.Inject(func() { done <- f() })
++	if err != nil {
++		return err
++	}
++	select {
++	case <-eng.running:
++		return eng.Error()
++	case err := <-done:
++		return err
++	}
++}
++
++// Server puts the Engine in server mode, meaning it will auto-detect security settings on
++// the incoming connnection such as use of SASL and SSL.
++// Must be called before Run()
++//
++func (eng *Engine) Server() { eng.transport.SetServer() }
++
++// Close the engine's connection, returns when the engine has exited.
++func (eng *Engine) Close(err error) {
++	eng.err.Set(err)
++	eng.Inject(func() {
++		CloseError(eng.connection, err)
++	})
++	<-eng.running
++}
++
++// Disconnect the engine's connection without and AMQP close, returns when the engine has exited.
++func (eng *Engine) Disconnect(err error) {
++	eng.err.Set(err)
++	eng.conn.Close()
++	<-eng.running
++}
++
++// Run the engine. Engine.Run() will exit when the engine is closed or
++// disconnected.  You can check for errors after exit with Engine.Error().
++//
++func (eng *Engine) Run() error {
++	wait := sync.WaitGroup{}
++	wait.Add(2) // Read and write goroutines
++
++	readErr := make(chan error, 1) // Don't block
++	go func() {                    // Read goroutine
++		defer wait.Done()
++		for {
++			rbuf := eng.read.buffer()
++			n, err := eng.conn.Read(rbuf)
++			if n > 0 {
++				eng.read.buffers <- rbuf[:n]
++			}
++			if err != nil {
++				readErr <- err
++				close(readErr)
++				close(eng.read.buffers)
++				return
++			}
++		}
++	}()
++
++	writeErr := make(chan error, 1) // Don't block
++	go func() {                     // Write goroutine
++		defer wait.Done()
++		for {
++			wbuf, ok := <-eng.write.buffers
++			if !ok {
++				return
++			}
++			_, err := eng.conn.Write(wbuf)
++			if err != nil {
++				writeErr <- err
++				close(writeErr)
++				return
++			}
++		}
++	}()
++
++	wbuf := eng.write.buffer()[:0]
++
++	for eng.err.Get() == nil {
++		if len(wbuf) == 0 {
++			eng.pop(&wbuf)
++		}
++		// Don't set wchan unless there is something to write.
++		var wchan chan []byte
++		if len(wbuf) > 0 {
++			wchan = eng.write.buffers
++		}
++
++		select {
++		case buf, ok := <-eng.read.buffers: // Read a buffer
++			if ok {
++				eng.push(buf)
++			}
++		case wchan <- wbuf: // Write a buffer
++			wbuf = eng.write.buffer()[:0]
++		case f, ok := <-eng.inject: // Function injected from another goroutine
++			if ok {
++				f()
++			}
++		case err := <-readErr:
++			eng.netError(err)
++		case err := <-writeErr:
++			eng.netError(err)
++		}
++		eng.process()
++	}
++	close(eng.write.buffers)
++	eng.conn.Close() // Make sure connection is closed
++	wait.Wait()
++	close(eng.running) // Signal goroutines have exited and Error is set.
++
++	connectionContexts.Delete(eng.connection)
++	if !eng.connection.IsNil() {
++		eng.connection.Free()
++	}
++	if !eng.transport.IsNil() {
++		eng.transport.Free()
++	}
++	if eng.collector != nil {
++		C.pn_collector_free(eng.collector)
++	}
++	for _, h := range eng.handlers {
++		switch h := h.(type) {
++		case cHandler:
++			C.pn_handler_free(h.pn)
++		}
++	}
++	return eng.err.Get()
++}
++
++func (eng *Engine) netError(err error) {
++	eng.err.Set(err)
++	eng.transport.CloseHead()
++	eng.transport.CloseTail()
++}
++
++func minInt(a, b int) int {
++	if a < b {
++		return a
++	} else {
++		return b
++	}
++}
++
++func (eng *Engine) pop(buf *[]byte) {
++	pending := int(eng.transport.Pending())
++	switch {
++	case pending == int(C.PN_EOS):
++		*buf = (*buf)[:]
++		return
++	case pending < 0:
++		panic(internal.Errorf("%s", internal.PnErrorCode(pending)))
++	}
++	size := minInt(pending, cap(*buf))
++	*buf = (*buf)[:size]
++	if size == 0 {
++		return
++	}
++	C.memcpy(unsafe.Pointer(&(*buf)[0]), eng.transport.Head(), C.size_t(size))
++	internal.Assert(size > 0)
++	eng.transport.Pop(uint(size))
++}
++
++func (eng *Engine) push(buf []byte) {
++	buf2 := buf
++	for len(buf2) > 0 {
++		n := eng.transport.Push(buf2)
++		if n <= 0 {
++			panic(internal.Errorf("error in transport: %s", internal.PnErrorCode(n)))
++		}
++		buf2 = buf2[n:]
++	}
++}
++
++func (eng *Engine) handle(e Event) {
++	for _, h := range eng.handlers {
++		h.HandleEvent(e)
++	}
++	if e.Type() == ETransportClosed {
++		eng.err.Set(io.EOF)
++	}
++}
++
++func (eng *Engine) process() {
++	for ce := C.pn_collector_peek(eng.collector); ce != nil; ce = C.pn_collector_peek(eng.collector) {
++		eng.handle(makeEvent(ce, eng))
++		C.pn_collector_pop(eng.collector)
++	}
++}
++
++func (eng *Engine) Connection() Connection { return eng.connection }


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


[39/50] [abbrv] qpid-proton git commit: NO-JIRA: c++: fix compile error on older c++ compilers (noticed on gcc 4.7)

Posted by ac...@apache.org.
NO-JIRA: c++: fix compile error on older c++ compilers (noticed on gcc 4.7)


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

Branch: refs/heads/go1
Commit: a16c58a59c2a5504ecd556dd397b7d28cc68dbd4
Parents: 6192c55
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Oct 21 10:03:02 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Oct 21 10:03:02 2015 -0400

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a16c58a5/proton-c/bindings/cpp/include/proton/endpoint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp
index e31fce6..5ed2646 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -98,7 +98,8 @@ template<class I> class range {
 ///@ An iterator for a range of sessions.
 class session_iterator : public iter_base<session, session_iterator> {
  public:
-    explicit session_iterator(session* p = 0, endpoint::state s = 0) : iter_base(p, s) {}
+    explicit session_iterator(session* p = 0, endpoint::state s = 0) :
+        iter_base<session, session_iterator>(p, s) {}
   private:
     PN_CPP_EXTERN void advance();
   friend class iter_base<session, session_iterator>;


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


[27/50] [abbrv] qpid-proton git commit: NO-JIRA: fix up poms to allow the engine demo bits to allow them to build and run

Posted by ac...@apache.org.
NO-JIRA: fix up poms to allow the engine demo bits to allow them to build and 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/6f977fa0
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/6f977fa0
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/6f977fa0

Branch: refs/heads/go1
Commit: 6f977fa0b16666d512c2eab0e5f81a0c531c414b
Parents: aceb43d
Author: Robert Gemmell <ro...@apache.org>
Authored: Fri Oct 16 15:17:16 2015 +0100
Committer: Robert Gemmell <ro...@apache.org>
Committed: Fri Oct 16 15:17:16 2015 +0100

----------------------------------------------------------------------
 examples/engine/java/pom.xml | 11 ++++-------
 pom.xml                      |  1 +
 2 files changed, 5 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6f977fa0/examples/engine/java/pom.xml
----------------------------------------------------------------------
diff --git a/examples/engine/java/pom.xml b/examples/engine/java/pom.xml
index c904212..5c51a0e 100644
--- a/examples/engine/java/pom.xml
+++ b/examples/engine/java/pom.xml
@@ -19,12 +19,13 @@
   <parent>
     <groupId>org.apache.qpid</groupId>
     <artifactId>proton-project</artifactId>
-    <version>0.10-SNAPSHOT</version>
+    <version>0.11.0-SNAPSHOT</version>
+    <relativePath>../../../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>proton-j-demo</artifactId>
-  <name>proton-j-demo</name>
+  <artifactId>proton-j-engine-demo</artifactId>
+  <name>proton-j-engine-demo</name>
 
   <dependencies>
     <dependency>
@@ -33,8 +34,4 @@
       <version>${project.parent.version}</version>
     </dependency>
   </dependencies>
-
-  <scm>
-    <url>http://svn.apache.org/viewvc/qpid/proton/</url>
-  </scm>
 </project>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6f977fa0/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bbca796..8ca3a8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,7 @@
     <module>contrib/proton-jms</module>
     <module>contrib/proton-hawtdispatch</module>
     <module>tests</module>
+    <module>examples/engine/java</module>
     <module>examples/java/messenger</module>
     <module>examples/java/reactor</module>
   </modules>


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


[09/50] [abbrv] qpid-proton git commit: PROTON-1011: Go example of event driven broker. Package renaming and some new features.

Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/message.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/message.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/message.go
new file mode 100644
index 0000000..5ba4f4f
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/message.go
@@ -0,0 +1,347 @@
+/*
+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
+
+// #include <proton/types.h>
+// #include <proton/message.h>
+// #include <proton/codec.h>
+// #include <stdlib.h>
+//
+// /* Helper for setting message string fields */
+// typedef int (*set_fn)(pn_message_t*, const char*);
+// int msg_set_str(pn_message_t* m, char* s, set_fn set) {
+//     int result = set(m, s);
+//     free(s);
+//     return result;
+// }
+//
+import "C"
+
+import (
+	"qpid.apache.org/internal"
+	"runtime"
+	"time"
+	"unsafe"
+)
+
+// Message is the interface to an AMQP message.
+type Message interface {
+	// Durable indicates that any parties taking responsibility
+	// for the message must durably store the content.
+	Durable() bool
+	SetDurable(bool)
+
+	// Priority impacts ordering guarantees. Within a
+	// given ordered context, higher priority messages may jump ahead of
+	// lower priority messages.
+	Priority() uint8
+	SetPriority(uint8)
+
+	// TTL or Time To Live, a message it may be dropped after this duration
+	TTL() time.Duration
+	SetTTL(time.Duration)
+
+	// FirstAcquirer indicates
+	// that the recipient of the message is the first recipient to acquire
+	// the message, i.e. there have been no failed delivery attempts to
+	// other acquirers. Note that this does not mean the message has not
+	// been delivered to, but not acquired, by other recipients.
+	FirstAcquirer() bool
+	SetFirstAcquirer(bool)
+
+	// DeliveryCount tracks how many attempts have been made to
+	// delivery a message.
+	DeliveryCount() uint32
+	SetDeliveryCount(uint32)
+
+	// MessageId provides a unique identifier for a message.
+	// it can be an a string, an unsigned long, a uuid or a
+	// binary value.
+	MessageId() interface{}
+	SetMessageId(interface{})
+
+	UserId() string
+	SetUserId(string)
+
+	Address() string
+	SetAddress(string)
+
+	Subject() string
+	SetSubject(string)
+
+	ReplyTo() string
+	SetReplyTo(string)
+
+	// CorrelationId is set on correlated request and response messages. It can be
+	// an a string, an unsigned long, a uuid or a binary value.
+	CorrelationId() interface{}
+	SetCorrelationId(interface{})
+
+	ContentType() string
+	SetContentType(string)
+
+	ContentEncoding() string
+	SetContentEncoding(string)
+
+	// ExpiryTime indicates an absoulte time when the message may be dropped.
+	// A Zero time (i.e. t.isZero() == true) indicates a message never expires.
+	ExpiryTime() time.Time
+	SetExpiryTime(time.Time)
+
+	CreationTime() time.Time
+	SetCreationTime(time.Time)
+
+	GroupId() string
+	SetGroupId(string)
+
+	GroupSequence() int32
+	SetGroupSequence(int32)
+
+	ReplyToGroupId() string
+	SetReplyToGroupId(string)
+
+	// Instructions - AMQP delivery instructions.
+	Instructions() map[string]interface{}
+	SetInstructions(v map[string]interface{})
+
+	// Annotations - AMQP annotations.
+	Annotations() map[string]interface{}
+	SetAnnotations(v map[string]interface{})
+
+	// Properties - Application properties.
+	Properties() map[string]interface{}
+	SetProperties(v map[string]interface{})
+
+	// Inferred indicates how the message content
+	// is encoded into AMQP sections. If inferred is true then binary and
+	// list values in the body of the message will be encoded as AMQP DATA
+	// and AMQP SEQUENCE sections, respectively. If inferred is false,
+	// then all values in the body of the message will be encoded as AMQP
+	// VALUE sections regardless of their type.
+	Inferred() bool
+	SetInferred(bool)
+
+	// Marshal a Go value into the message body. See amqp.Marshal() for details.
+	Marshal(interface{})
+
+	// Unmarshal the message body into the value pointed to by v. See amqp.Unmarshal() for details.
+	Unmarshal(interface{})
+
+	// Body value resulting from the default unmarshalling of message body as interface{}
+	Body() interface{}
+
+	// Encode encodes the message as AMQP data. If buffer is non-nil and is large enough
+	// the message is encoded into it, otherwise a new buffer is created.
+	// Returns the buffer containing the message.
+	Encode(buffer []byte) ([]byte, error)
+
+	// Decode data into this message. Overwrites an existing message content.
+	Decode(buffer []byte) error
+
+	// Clear the message contents.
+	Clear()
+
+	// Copy the contents of another message to this one.
+	Copy(m Message) error
+}
+
+type message struct{ pn *C.pn_message_t }
+
+func freeMessage(m *message) {
+	C.pn_message_free(m.pn)
+	m.pn = nil
+}
+
+// NewMessage creates a new message instance.
+func NewMessage() Message {
+	m := &message{C.pn_message()}
+	runtime.SetFinalizer(m, freeMessage)
+	return m
+}
+
+// NewMessageWith creates a message with value as the body. Equivalent to
+//     m := NewMessage(); m.Marshal(body)
+func NewMessageWith(value interface{}) Message {
+	m := NewMessage()
+	m.Marshal(value)
+	return m
+}
+
+func (m *message) Clear() { C.pn_message_clear(m.pn) }
+
+func (m *message) Copy(x Message) error {
+	if data, err := x.Encode(nil); err == nil {
+		return m.Decode(data)
+	} else {
+		return err
+	}
+}
+
+// ==== message get functions
+
+func rewindGet(data *C.pn_data_t) (v interface{}) {
+	C.pn_data_rewind(data)
+	C.pn_data_next(data)
+	unmarshal(&v, data)
+	return v
+}
+
+func rewindMap(data *C.pn_data_t) (v map[string]interface{}) {
+	C.pn_data_rewind(data)
+	C.pn_data_next(data)
+	unmarshal(&v, data)
+	return v
+}
+
+func (m *message) Inferred() bool  { return bool(C.pn_message_is_inferred(m.pn)) }
+func (m *message) Durable() bool   { return bool(C.pn_message_is_durable(m.pn)) }
+func (m *message) Priority() uint8 { return uint8(C.pn_message_get_priority(m.pn)) }
+func (m *message) TTL() time.Duration {
+	return time.Duration(C.pn_message_get_ttl(m.pn)) * time.Millisecond
+}
+func (m *message) FirstAcquirer() bool        { return bool(C.pn_message_is_first_acquirer(m.pn)) }
+func (m *message) DeliveryCount() uint32      { return uint32(C.pn_message_get_delivery_count(m.pn)) }
+func (m *message) MessageId() interface{}     { return rewindGet(C.pn_message_id(m.pn)) }
+func (m *message) UserId() string             { return goString(C.pn_message_get_user_id(m.pn)) }
+func (m *message) Address() string            { return C.GoString(C.pn_message_get_address(m.pn)) }
+func (m *message) Subject() string            { return C.GoString(C.pn_message_get_subject(m.pn)) }
+func (m *message) ReplyTo() string            { return C.GoString(C.pn_message_get_reply_to(m.pn)) }
+func (m *message) CorrelationId() interface{} { return rewindGet(C.pn_message_correlation_id(m.pn)) }
+func (m *message) ContentType() string        { return C.GoString(C.pn_message_get_content_type(m.pn)) }
+func (m *message) ContentEncoding() string    { return C.GoString(C.pn_message_get_content_encoding(m.pn)) }
+
+func (m *message) ExpiryTime() time.Time {
+	return time.Unix(0, int64(time.Millisecond*time.Duration(C.pn_message_get_expiry_time(m.pn))))
+}
+func (m *message) CreationTime() time.Time {
+	return time.Unix(0, int64(time.Millisecond)*int64(C.pn_message_get_creation_time(m.pn)))
+}
+func (m *message) GroupId() string        { return C.GoString(C.pn_message_get_group_id(m.pn)) }
+func (m *message) GroupSequence() int32   { return int32(C.pn_message_get_group_sequence(m.pn)) }
+func (m *message) ReplyToGroupId() string { return C.GoString(C.pn_message_get_reply_to_group_id(m.pn)) }
+
+func (m *message) Instructions() map[string]interface{} {
+	return rewindMap(C.pn_message_instructions(m.pn))
+}
+func (m *message) Annotations() map[string]interface{} {
+	return rewindMap(C.pn_message_annotations(m.pn))
+}
+func (m *message) Properties() map[string]interface{} {
+	return rewindMap(C.pn_message_properties(m.pn))
+}
+
+// ==== message set methods
+
+func setData(v interface{}, data *C.pn_data_t) {
+	C.pn_data_clear(data)
+	marshal(v, data)
+}
+
+func dataString(data *C.pn_data_t) string {
+	str := C.pn_string(C.CString(""))
+	defer C.pn_free(unsafe.Pointer(str))
+	C.pn_inspect(unsafe.Pointer(data), str)
+	return C.GoString(C.pn_string_get(str))
+}
+
+func (m *message) SetInferred(b bool)  { C.pn_message_set_inferred(m.pn, C.bool(m.Inferred())) }
+func (m *message) SetDurable(b bool)   { C.pn_message_set_durable(m.pn, C.bool(b)) }
+func (m *message) SetPriority(b uint8) { C.pn_message_set_priority(m.pn, C.uint8_t(b)) }
+func (m *message) SetTTL(d time.Duration) {
+	C.pn_message_set_ttl(m.pn, C.pn_millis_t(d/time.Millisecond))
+}
+func (m *message) SetFirstAcquirer(b bool)     { C.pn_message_set_first_acquirer(m.pn, C.bool(b)) }
+func (m *message) SetDeliveryCount(c uint32)   { C.pn_message_set_delivery_count(m.pn, C.uint32_t(c)) }
+func (m *message) SetMessageId(id interface{}) { setData(id, C.pn_message_id(m.pn)) }
+func (m *message) SetUserId(s string)          { C.pn_message_set_user_id(m.pn, pnBytes(([]byte)(s))) }
+func (m *message) SetAddress(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_address))
+}
+func (m *message) SetSubject(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_subject))
+}
+func (m *message) SetReplyTo(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to))
+}
+func (m *message) SetCorrelationId(c interface{}) { setData(c, C.pn_message_correlation_id(m.pn)) }
+func (m *message) SetContentType(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_type))
+}
+func (m *message) SetContentEncoding(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_encoding))
+}
+func (m *message) SetExpiryTime(t time.Time)   { C.pn_message_set_expiry_time(m.pn, pnTime(t)) }
+func (m *message) SetCreationTime(t time.Time) { C.pn_message_set_creation_time(m.pn, pnTime(t)) }
+func (m *message) SetGroupId(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_group_id))
+}
+func (m *message) SetGroupSequence(s int32) {
+	C.pn_message_set_group_sequence(m.pn, C.pn_sequence_t(s))
+}
+func (m *message) SetReplyToGroupId(s string) {
+	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to_group_id))
+}
+
+func (m *message) SetInstructions(v map[string]interface{}) {
+	setData(v, C.pn_message_instructions(m.pn))
+}
+func (m *message) SetAnnotations(v map[string]interface{}) { setData(v, C.pn_message_annotations(m.pn)) }
+func (m *message) SetProperties(v map[string]interface{})  { setData(v, C.pn_message_properties(m.pn)) }
+
+// Marshal/Unmarshal body
+func (m *message) Marshal(v interface{})   { clearMarshal(v, C.pn_message_body(m.pn)) }
+func (m *message) Unmarshal(v interface{}) { rewindUnmarshal(v, C.pn_message_body(m.pn)) }
+func (m *message) Body() (v interface{})   { m.Unmarshal(&v); return }
+
+func (m *message) Decode(data []byte) error {
+	m.Clear()
+	if len(data) == 0 {
+		return internal.Errorf("empty buffer for decode")
+	}
+	if C.pn_message_decode(m.pn, cPtr(data), cLen(data)) < 0 {
+		return internal.Errorf("decoding message: %s",
+			internal.PnError(unsafe.Pointer(C.pn_message_error(m.pn))))
+	}
+	return nil
+}
+
+func DecodeMessage(data []byte) (m Message, err error) {
+	m = NewMessage()
+	err = m.Decode(data)
+	return
+}
+
+func (m *message) Encode(buffer []byte) ([]byte, error) {
+	encode := func(buf []byte) ([]byte, error) {
+		len := cLen(buf)
+		result := C.pn_message_encode(m.pn, cPtr(buf), &len)
+		switch {
+		case result == C.PN_OVERFLOW:
+			return buf, overflow
+		case result < 0:
+			return buf, internal.Errorf("cannot encode message: %s", internal.PnErrorCode(result))
+		default:
+			return buf[:len], nil
+		}
+	}
+	return encodeGrow(buffer, encode)
+}
+
+// TODO aconway 2015-09-14: Multi-section messages.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/message_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/message_test.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/message_test.go
new file mode 100644
index 0000000..7a6e5a8
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/message_test.go
@@ -0,0 +1,166 @@
+/*
+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
+
+import (
+	"testing"
+	"time"
+)
+
+func roundTrip(m Message) error {
+	buffer, err := m.Encode(nil)
+	if err != nil {
+		return err
+	}
+	m2, err := DecodeMessage(buffer)
+	if err != nil {
+		return err
+	}
+	return checkEqual(m, m2)
+}
+
+func TestDefaultMessage(t *testing.T) {
+	m := NewMessage()
+	// Check defaults
+	for _, data := range [][]interface{}{
+		{m.Inferred(), false},
+		{m.Durable(), false},
+		{m.Priority(), uint8(4)},
+		{m.TTL(), time.Duration(0)},
+		{m.UserId(), ""},
+		{m.Address(), ""},
+		{m.Subject(), ""},
+		{m.ReplyTo(), ""},
+		{m.ContentType(), ""},
+		{m.ContentEncoding(), ""},
+		{m.GroupId(), ""},
+		{m.GroupSequence(), int32(0)},
+		{m.ReplyToGroupId(), ""},
+		{m.MessageId(), nil},
+		{m.CorrelationId(), nil},
+		{m.Instructions(), map[string]interface{}{}},
+		{m.Annotations(), map[string]interface{}{}},
+		{m.Properties(), map[string]interface{}{}},
+		{m.Body(), nil},
+	} {
+		if err := checkEqual(data[0], data[1]); err != nil {
+			t.Error(err)
+		}
+	}
+	if err := roundTrip(m); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMessageRoundTrip(t *testing.T) {
+	m := NewMessage()
+	m.SetInferred(false)
+	m.SetDurable(true)
+	m.SetPriority(42)
+	m.SetTTL(0)
+	m.SetUserId("user")
+	m.SetAddress("address")
+	m.SetSubject("subject")
+	m.SetReplyTo("replyto")
+	m.SetContentType("content")
+	m.SetContentEncoding("encoding")
+	m.SetGroupId("group")
+	m.SetGroupSequence(42)
+	m.SetReplyToGroupId("replytogroup")
+	m.SetMessageId("id")
+	m.SetCorrelationId("correlation")
+	m.SetInstructions(map[string]interface{}{"instructions": "foo"})
+	m.SetAnnotations(map[string]interface{}{"annotations": "foo"})
+	m.SetProperties(map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"})
+	m.Marshal("hello")
+
+	for _, data := range [][]interface{}{
+		{m.Inferred(), false},
+		{m.Durable(), true},
+		{m.Priority(), uint8(42)},
+		{m.TTL(), time.Duration(0)},
+		{m.UserId(), "user"},
+		{m.Address(), "address"},
+		{m.Subject(), "subject"},
+		{m.ReplyTo(), "replyto"},
+		{m.ContentType(), "content"},
+		{m.ContentEncoding(), "encoding"},
+		{m.GroupId(), "group"},
+		{m.GroupSequence(), int32(42)},
+		{m.ReplyToGroupId(), "replytogroup"},
+		{m.MessageId(), "id"},
+		{m.CorrelationId(), "correlation"},
+		{m.Instructions(), map[string]interface{}{"instructions": "foo"}},
+		{m.Annotations(), map[string]interface{}{"annotations": "foo"}},
+		{m.Properties(), map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"}},
+		{m.Body(), "hello"},
+	} {
+		if err := checkEqual(data[0], data[1]); err != nil {
+			t.Error(err)
+		}
+	}
+	if err := roundTrip(m); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMessageBodyTypes(t *testing.T) {
+	var s string
+	var body interface{}
+	var i int64
+
+	m := NewMessageWith(int64(42))
+	m.Unmarshal(&body)
+	m.Unmarshal(&i)
+	if err := checkEqual(body.(int64), int64(42)); err != nil {
+		t.Error(err)
+	}
+	if err := checkEqual(i, int64(42)); err != nil {
+		t.Error(err)
+	}
+
+	m = NewMessageWith("hello")
+	m.Unmarshal(&s)
+	m.Unmarshal(&body)
+	if err := checkEqual(s, "hello"); err != nil {
+		t.Error(err)
+	}
+	if err := checkEqual(body.(string), "hello"); err != nil {
+		t.Error(err)
+	}
+	if err := roundTrip(m); err != nil {
+		t.Error(err)
+	}
+
+	m = NewMessageWith(Binary("bin"))
+	m.Unmarshal(&s)
+	m.Unmarshal(&body)
+	if err := checkEqual(body.(Binary), Binary("bin")); err != nil {
+		t.Error(err)
+	}
+	if err := checkEqual(s, "bin"); err != nil {
+		t.Error(err)
+	}
+	if err := roundTrip(m); err != nil {
+		t.Error(err)
+	}
+
+	// TODO aconway 2015-09-08: array etc.
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
new file mode 100644
index 0000000..131c974
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
@@ -0,0 +1,198 @@
+/*
+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
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"time"
+	"unsafe"
+)
+
+type Type C.pn_type_t
+
+func (t Type) String() string {
+	switch C.pn_type_t(t) {
+	case C.PN_NULL:
+		return "null"
+	case C.PN_BOOL:
+		return "bool"
+	case C.PN_UBYTE:
+		return "ubyte"
+	case C.PN_BYTE:
+		return "byte"
+	case C.PN_USHORT:
+		return "ushort"
+	case C.PN_SHORT:
+		return "short"
+	case C.PN_CHAR:
+		return "char"
+	case C.PN_UINT:
+		return "uint"
+	case C.PN_INT:
+		return "int"
+	case C.PN_ULONG:
+		return "ulong"
+	case C.PN_LONG:
+		return "long"
+	case C.PN_TIMESTAMP:
+		return "timestamp"
+	case C.PN_FLOAT:
+		return "float"
+	case C.PN_DOUBLE:
+		return "double"
+	case C.PN_DECIMAL32:
+		return "decimal32"
+	case C.PN_DECIMAL64:
+		return "decimal64"
+	case C.PN_DECIMAL128:
+		return "decimal128"
+	case C.PN_UUID:
+		return "uuid"
+	case C.PN_BINARY:
+		return "binary"
+	case C.PN_STRING:
+		return "string"
+	case C.PN_SYMBOL:
+		return "symbol"
+	case C.PN_DESCRIBED:
+		return "described"
+	case C.PN_ARRAY:
+		return "array"
+	case C.PN_LIST:
+		return "list"
+	case C.PN_MAP:
+		return "map"
+	case C.PN_INVALID:
+		return "no-data"
+	default:
+		return fmt.Sprintf("unknown-type(%d)", t)
+	}
+}
+
+// Go types
+var (
+	bytesType = reflect.TypeOf([]byte{})
+	valueType = reflect.TypeOf(reflect.Value{})
+)
+
+// TODO aconway 2015-04-08: can't handle AMQP maps with key types that are not valid Go map keys.
+
+// Map is a generic map that can have mixed key and value types and so can represent any AMQP map
+type Map map[interface{}]interface{}
+
+// List is a generic list that can hold mixed values and can represent any AMQP list.
+//
+type List []interface{}
+
+// Symbol is a string that is encoded as an AMQP symbol
+type Symbol string
+
+func (s Symbol) GoString() string { return fmt.Sprintf("s\"%s\"", s) }
+
+// Binary is a string that is encoded as an AMQP binary.
+// It is a string rather than a byte[] because byte[] is not hashable and can't be used as
+// a map key, AMQP frequently uses binary types as map keys. It can convert to and from []byte
+type Binary string
+
+func (b Binary) GoString() string { return fmt.Sprintf("b\"%s\"", b) }
+
+// GoString for Map prints values with their types, useful for debugging.
+func (m Map) GoString() string {
+	out := &bytes.Buffer{}
+	fmt.Fprintf(out, "%T{", m)
+	i := len(m)
+	for k, v := range m {
+		fmt.Fprintf(out, "%T(%#v): %T(%#v)", k, k, v, v)
+		i--
+		if i > 0 {
+			fmt.Fprint(out, ", ")
+		}
+	}
+	fmt.Fprint(out, "}")
+	return out.String()
+}
+
+// GoString for List prints values with their types, useful for debugging.
+func (l List) GoString() string {
+	out := &bytes.Buffer{}
+	fmt.Fprintf(out, "%T{", l)
+	for i := 0; i < len(l); i++ {
+		fmt.Fprintf(out, "%T(%#v)", l[i], l[i])
+		if i == len(l)-1 {
+			fmt.Fprint(out, ", ")
+		}
+	}
+	fmt.Fprint(out, "}")
+	return out.String()
+}
+
+// pnTime converts Go time.Time to Proton millisecond Unix time.
+func pnTime(t time.Time) C.pn_timestamp_t {
+	secs := t.Unix()
+	// Note: sub-second accuracy is not guaraunteed if the Unix time in
+	// nanoseconds cannot be represented by an int64 (sometime around year 2260)
+	msecs := (t.UnixNano() % int64(time.Second)) / int64(time.Millisecond)
+	return C.pn_timestamp_t(secs*1000 + msecs)
+}
+
+// goTime converts a pn_timestamp_t to a Go time.Time.
+func goTime(t C.pn_timestamp_t) time.Time {
+	secs := int64(t) / 1000
+	nsecs := (int64(t) % 1000) * int64(time.Millisecond)
+	return time.Unix(secs, nsecs)
+}
+
+func goBytes(cBytes C.pn_bytes_t) (bytes []byte) {
+	if cBytes.start != nil {
+		bytes = C.GoBytes(unsafe.Pointer(cBytes.start), C.int(cBytes.size))
+	}
+	return
+}
+
+func goString(cBytes C.pn_bytes_t) (str string) {
+	if cBytes.start != nil {
+		str = C.GoStringN(cBytes.start, C.int(cBytes.size))
+	}
+	return
+}
+
+func pnBytes(b []byte) C.pn_bytes_t {
+	if len(b) == 0 {
+		return C.pn_bytes_t{0, nil}
+	} else {
+		return C.pn_bytes_t{C.size_t(len(b)), (*C.char)(unsafe.Pointer(&b[0]))}
+	}
+}
+
+func cPtr(b []byte) *C.char {
+	if len(b) == 0 {
+		return nil
+	}
+	return (*C.char)(unsafe.Pointer(&b[0]))
+}
+
+func cLen(b []byte) C.size_t {
+	return C.size_t(len(b))
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
new file mode 100644
index 0000000..61c6d3f
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
@@ -0,0 +1,556 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+oor 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
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"qpid.apache.org/internal"
+	"reflect"
+	"unsafe"
+)
+
+const minDecode = 1024
+
+// Error returned if AMQP data cannot be unmarshaled as the desired Go type.
+type UnmarshalError struct {
+	// The name of the AMQP type.
+	AMQPType string
+	// The Go type.
+	GoType reflect.Type
+}
+
+func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError {
+	return &UnmarshalError{Type(pnType).String(), reflect.TypeOf(v)}
+}
+
+func (e UnmarshalError) Error() string {
+	if e.GoType.Kind() != reflect.Ptr {
+		return fmt.Sprintf("proton: cannot unmarshal to type %s, not a pointer", e.GoType)
+	} else {
+		return fmt.Sprintf("proton: cannot unmarshal AMQP %s to %s", e.AMQPType, e.GoType)
+	}
+}
+
+func doRecover(err *error) {
+	r := recover()
+	switch r := r.(type) {
+	case nil:
+	case *UnmarshalError, internal.Error:
+		*err = r.(error)
+	default:
+		panic(r)
+	}
+}
+
+//
+// Decoding from a pn_data_t
+//
+// NOTE: we use panic() to signal a decoding error, simplifies decoding logic.
+// We recover() at the highest possible level - i.e. in the exported Unmarshal or Decode.
+//
+
+// Decoder decodes AMQP values from an io.Reader.
+//
+type Decoder struct {
+	reader io.Reader
+	buffer bytes.Buffer
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder has it's own buffer and may read more data than required for the
+// AMQP values requested.  Use Buffered to see if there is data left in the
+// buffer.
+//
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{r, bytes.Buffer{}}
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's buffer. The
+// reader is valid until the next call to Decode.
+//
+func (d *Decoder) Buffered() io.Reader {
+	return bytes.NewReader(d.buffer.Bytes())
+}
+
+// Decode reads the next AMQP value from the Reader and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
+//
+func (d *Decoder) Decode(v interface{}) (err error) {
+	defer doRecover(&err)
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	var n int
+	for n == 0 && err == nil {
+		n = decode(data, d.buffer.Bytes())
+		if n == 0 { // n == 0 means not enough data, read more
+			err = d.more()
+		} else {
+			unmarshal(v, data)
+		}
+	}
+	d.buffer.Next(n)
+	return
+}
+
+/*
+Unmarshal decodes AMQP-encoded bytes and stores the result in the value pointed to by v.
+Types are converted as follows:
+
+ +---------------------------+----------------------------------------------------------------------+
+ |To Go types                |From AMQP types                                                       |
+ +===========================+======================================================================+
+ |bool                       |bool                                                                  |
+ +---------------------------+----------------------------------------------------------------------+
+ |int, int8, int16,          |Equivalent or smaller signed integer type: byte, short, int, long.    |
+ |int32, int64               |                                                                      |
+ +---------------------------+----------------------------------------------------------------------+
+ |uint, uint8, uint16,       |Equivalent or smaller unsigned integer type: ubyte, ushort, uint,     |
+ |uint32, uint64 types       |ulong                                                                 |
+ +---------------------------+----------------------------------------------------------------------+
+ |float32, float64           |Equivalent or smaller float or double.                                |
+ +---------------------------+----------------------------------------------------------------------+
+ |string, []byte             |string, symbol or binary.                                             |
+ +---------------------------+----------------------------------------------------------------------+
+ |Symbol                     |symbol                                                                |
+ +---------------------------+----------------------------------------------------------------------+
+ |map[K]T                    |map, provided all keys and values can unmarshal to types K, T         |
+ +---------------------------+----------------------------------------------------------------------+
+ |Map                        |map, any AMQP map                                                     |
+ +---------------------------+----------------------------------------------------------------------+
+ |interface{}                |Any AMQP value can be unmarshaled to an interface{} as follows:       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |AMQP Type               |Go Type in interface{}                       |
+ |                           +========================+=============================================+
+ |                           |bool                    |bool                                         |
+ |                           +------------------------+---------------------------------------------+
+ |                           |byte,short,int,long     |int8,int16,int32,int64                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |ubyte,ushort,uint,ulong |uint8,uint16,uint32,uint64                   |
+ |                           +------------------------+---------------------------------------------+
+ |                           |float, double           |float32, float64                             |
+ |                           +------------------------+---------------------------------------------+
+ |                           |string                  |string                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |symbol                  |Symbol                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |binary                  |Binary                                       |
+ |                           +------------------------+---------------------------------------------+
+ |                           |nulll                   |nil                                          |
+ |                           +------------------------+---------------------------------------------+
+ |                           |map                     |Map                                          |
+ |                           +------------------------+---------------------------------------------+
+ |                           |list                    |List                                         |
+ +---------------------------+------------------------+---------------------------------------------+
+
+The following Go types cannot be unmarshaled: uintptr, function, interface, channel.
+
+TODO
+
+Go types: array, struct.
+
+AMQP types: decimal32/64/128, char (round trip), timestamp, uuid, array, multi-section message bodies.
+
+AMQP maps with mixed/unhashable key types need an alternate representation.
+
+Described types.
+*/
+func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
+	defer doRecover(&err)
+
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	n = decode(data, bytes)
+	if n == 0 {
+		err = internal.Errorf("not enough data")
+	} else {
+		unmarshal(v, data)
+	}
+	return
+}
+
+// more reads more data when we can't parse a complete AMQP type
+func (d *Decoder) more() error {
+	var readSize int64 = minDecode
+	if int64(d.buffer.Len()) > readSize { // Grow by doubling
+		readSize = int64(d.buffer.Len())
+	}
+	var n int64
+	n, err := d.buffer.ReadFrom(io.LimitReader(d.reader, readSize))
+	if n == 0 && err == nil { // ReadFrom won't report io.EOF, just returns 0
+		err = io.EOF
+	}
+	return err
+}
+
+// Unmarshal from data into value pointed at by v.
+func unmarshal(v interface{}, data *C.pn_data_t) {
+	pnType := C.pn_data_type(data)
+	switch v := v.(type) {
+	case *bool:
+		switch pnType {
+		case C.PN_BOOL:
+			*v = bool(C.pn_data_get_bool(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *int8:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int8(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int8(C.pn_data_get_byte(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *uint8:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint8(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint8(C.pn_data_get_ubyte(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *int16:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int16(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int16(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int16(C.pn_data_get_short(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *uint16:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint16(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint16(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint16(C.pn_data_get_ushort(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *int32:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int32(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int32(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int32(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int32(C.pn_data_get_int(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	case *uint32:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint32(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint32(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint32(C.pn_data_get_ushort(data))
+		case C.PN_UINT:
+			*v = uint32(C.pn_data_get_uint(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *int64:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int64(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int64(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int64(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int64(C.pn_data_get_int(data))
+		case C.PN_LONG:
+			*v = int64(C.pn_data_get_long(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *uint64:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint64(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint64(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint64(C.pn_data_get_ushort(data))
+		case C.PN_ULONG:
+			*v = uint64(C.pn_data_get_ulong(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *int:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = int(C.pn_data_get_char(data))
+		case C.PN_BYTE:
+			*v = int(C.pn_data_get_byte(data))
+		case C.PN_SHORT:
+			*v = int(C.pn_data_get_short(data))
+		case C.PN_INT:
+			*v = int(C.pn_data_get_int(data))
+		case C.PN_LONG:
+			if unsafe.Sizeof(0) == 8 {
+				*v = int(C.pn_data_get_long(data))
+			} else {
+				panic(newUnmarshalError(pnType, v))
+			}
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *uint:
+		switch pnType {
+		case C.PN_CHAR:
+			*v = uint(C.pn_data_get_char(data))
+		case C.PN_UBYTE:
+			*v = uint(C.pn_data_get_ubyte(data))
+		case C.PN_USHORT:
+			*v = uint(C.pn_data_get_ushort(data))
+		case C.PN_UINT:
+			*v = uint(C.pn_data_get_uint(data))
+		case C.PN_ULONG:
+			if unsafe.Sizeof(0) == 8 {
+				*v = uint(C.pn_data_get_ulong(data))
+			} else {
+				panic(newUnmarshalError(pnType, v))
+			}
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *float32:
+		switch pnType {
+		case C.PN_FLOAT:
+			*v = float32(C.pn_data_get_float(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *float64:
+		switch pnType {
+		case C.PN_FLOAT:
+			*v = float64(C.pn_data_get_float(data))
+		case C.PN_DOUBLE:
+			*v = float64(C.pn_data_get_double(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *string:
+		switch pnType {
+		case C.PN_STRING:
+			*v = goString(C.pn_data_get_string(data))
+		case C.PN_SYMBOL:
+			*v = goString(C.pn_data_get_symbol(data))
+		case C.PN_BINARY:
+			*v = goString(C.pn_data_get_binary(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *[]byte:
+		switch pnType {
+		case C.PN_STRING:
+			*v = goBytes(C.pn_data_get_string(data))
+		case C.PN_SYMBOL:
+			*v = goBytes(C.pn_data_get_symbol(data))
+		case C.PN_BINARY:
+			*v = goBytes(C.pn_data_get_binary(data))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *Binary:
+		switch pnType {
+		case C.PN_BINARY:
+			*v = Binary(goBytes(C.pn_data_get_binary(data)))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *Symbol:
+		switch pnType {
+		case C.PN_SYMBOL:
+			*v = Symbol(goBytes(C.pn_data_get_symbol(data)))
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+
+	case *interface{}:
+		getInterface(data, v)
+
+	default:
+		if reflect.TypeOf(v).Kind() != reflect.Ptr {
+			panic(newUnmarshalError(pnType, v))
+		}
+		switch reflect.TypeOf(v).Elem().Kind() {
+		case reflect.Map:
+			getMap(data, v)
+		case reflect.Slice:
+			getList(data, v)
+		default:
+			panic(newUnmarshalError(pnType, v))
+		}
+	}
+	err := dataError("unmarshaling", data)
+	if err != nil {
+		panic(err)
+	}
+	return
+}
+
+func rewindUnmarshal(v interface{}, data *C.pn_data_t) {
+	C.pn_data_rewind(data)
+	C.pn_data_next(data)
+	unmarshal(v, data)
+}
+
+// Getting into an interface is driven completely by the AMQP type, since the interface{}
+// target is type-neutral.
+func getInterface(data *C.pn_data_t, v *interface{}) {
+	pnType := C.pn_data_type(data)
+	switch pnType {
+	case C.PN_NULL, C.PN_INVALID: // No data.
+		*v = nil
+	case C.PN_BOOL:
+		*v = bool(C.pn_data_get_bool(data))
+	case C.PN_UBYTE:
+		*v = uint8(C.pn_data_get_ubyte(data))
+	case C.PN_BYTE:
+		*v = int8(C.pn_data_get_byte(data))
+	case C.PN_USHORT:
+		*v = uint16(C.pn_data_get_ushort(data))
+	case C.PN_SHORT:
+		*v = int16(C.pn_data_get_short(data))
+	case C.PN_UINT:
+		*v = uint32(C.pn_data_get_uint(data))
+	case C.PN_INT:
+		*v = int32(C.pn_data_get_int(data))
+	case C.PN_CHAR:
+		*v = uint8(C.pn_data_get_char(data))
+	case C.PN_ULONG:
+		*v = uint64(C.pn_data_get_ulong(data))
+	case C.PN_LONG:
+		*v = int64(C.pn_data_get_long(data))
+	case C.PN_FLOAT:
+		*v = float32(C.pn_data_get_float(data))
+	case C.PN_DOUBLE:
+		*v = float64(C.pn_data_get_double(data))
+	case C.PN_BINARY:
+		*v = Binary(goBytes(C.pn_data_get_binary(data)))
+	case C.PN_STRING:
+		*v = goString(C.pn_data_get_string(data))
+	case C.PN_SYMBOL:
+		*v = Symbol(goString(C.pn_data_get_symbol(data)))
+	case C.PN_MAP:
+		m := make(Map)
+		unmarshal(&m, data)
+		*v = m
+	case C.PN_LIST:
+		l := make(List, 0)
+		unmarshal(&l, data)
+		*v = l
+	default:
+		panic(newUnmarshalError(pnType, v))
+	}
+}
+
+// get into map pointed at by v
+func getMap(data *C.pn_data_t, v interface{}) {
+	mapValue := reflect.ValueOf(v).Elem()
+	mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map
+	switch pnType := C.pn_data_type(data); pnType {
+	case C.PN_MAP:
+		count := int(C.pn_data_get_map(data))
+		if bool(C.pn_data_enter(data)) {
+			defer C.pn_data_exit(data)
+			for i := 0; i < count/2; i++ {
+				if bool(C.pn_data_next(data)) {
+					key := reflect.New(mapValue.Type().Key())
+					unmarshal(key.Interface(), data)
+					if bool(C.pn_data_next(data)) {
+						val := reflect.New(mapValue.Type().Elem())
+						unmarshal(val.Interface(), data)
+						mapValue.SetMapIndex(key.Elem(), val.Elem())
+					}
+				}
+			}
+		}
+	case C.PN_INVALID: // Leave the map empty
+	default:
+		panic(newUnmarshalError(pnType, v))
+	}
+}
+
+func getList(data *C.pn_data_t, v interface{}) {
+	pnType := C.pn_data_type(data)
+	if pnType != C.PN_LIST {
+		panic(newUnmarshalError(pnType, v))
+	}
+	count := int(C.pn_data_get_list(data))
+	listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count)
+	if bool(C.pn_data_enter(data)) {
+		for i := 0; i < count; i++ {
+			if bool(C.pn_data_next(data)) {
+				val := reflect.New(listValue.Type().Elem())
+				unmarshal(val.Interface(), data)
+				listValue.Index(i).Set(val.Elem())
+			}
+		}
+		C.pn_data_exit(data)
+	}
+	reflect.ValueOf(v).Elem().Set(listValue)
+}
+
+// decode from bytes.
+// Return bytes decoded or 0 if we could not decode a complete object.
+//
+func decode(data *C.pn_data_t, bytes []byte) int {
+	if len(bytes) == 0 {
+		return 0
+	}
+	n := int(C.pn_data_decode(data, cPtr(bytes), cLen(bytes)))
+	if n == int(C.PN_UNDERFLOW) {
+		C.pn_error_clear(C.pn_data_error(data))
+		return 0
+	} else if n <= 0 {
+		panic(internal.Errorf("unmarshal %s", internal.PnErrorCode(n)))
+	}
+	return n
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/url.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/url.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/url.go
new file mode 100644
index 0000000..0d0c662
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/url.go
@@ -0,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.
+*/
+
+package amqp
+
+/*
+#include <stdlib.h>
+#include <string.h>
+#include <proton/url.h>
+
+// Helper function for setting URL fields.
+typedef void (*setter_fn)(pn_url_t* url, const char* value);
+inline void	set(pn_url_t *url, setter_fn s, const char* value) {
+  s(url, value);
+}
+*/
+import "C"
+
+import (
+	"net"
+	"net/url"
+	"qpid.apache.org/internal"
+	"unsafe"
+)
+
+const (
+	amqp  string = "amqp"
+	amqps        = "amqps"
+)
+
+// ParseUrl parses an AMQP URL string and returns a net/url.Url.
+//
+// It is more forgiving than net/url.Parse and allows most of the parts of the
+// URL to be missing, assuming AMQP defaults.
+//
+func ParseURL(s string) (u *url.URL, err error) {
+	cstr := C.CString(s)
+	defer C.free(unsafe.Pointer(cstr))
+	pnUrl := C.pn_url_parse(cstr)
+	if pnUrl == nil {
+		return nil, internal.Errorf("bad URL %#v", s)
+	}
+	defer C.pn_url_free(pnUrl)
+
+	scheme := C.GoString(C.pn_url_get_scheme(pnUrl))
+	username := C.GoString(C.pn_url_get_username(pnUrl))
+	password := C.GoString(C.pn_url_get_password(pnUrl))
+	host := C.GoString(C.pn_url_get_host(pnUrl))
+	port := C.GoString(C.pn_url_get_port(pnUrl))
+	path := C.GoString(C.pn_url_get_path(pnUrl))
+
+	if err != nil {
+		return nil, internal.Errorf("bad URL %#v: %s", s, err)
+	}
+	if scheme == "" {
+		scheme = amqp
+	}
+	if port == "" {
+		if scheme == amqps {
+			port = amqps
+		} else {
+			port = amqp
+		}
+	}
+	var user *url.Userinfo
+	if password != "" {
+		user = url.UserPassword(username, password)
+	} else if username != "" {
+		user = url.User(username)
+	}
+
+	u = &url.URL{
+		Scheme: scheme,
+		User:   user,
+		Host:   net.JoinHostPort(host, port),
+		Path:   path,
+	}
+
+	return u, nil
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/url_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/url_test.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/url_test.go
new file mode 100644
index 0000000..f80f1c4
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/url_test.go
@@ -0,0 +1,51 @@
+/*
+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
+
+import (
+	"fmt"
+)
+
+func ExampleParseURL() {
+	for _, s := range []string{
+		"amqp://username:password@host:1234/path",
+		"host:1234",
+		"host",
+		":1234",
+		"host/path",
+		"amqps://host",
+		"",
+	} {
+		u, err := ParseURL(s)
+		if err != nil {
+			fmt.Println(err)
+		} else {
+			fmt.Println(u)
+		}
+	}
+	// Output:
+	// amqp://username:password@host:1234/path
+	// amqp://host:1234
+	// amqp://host:amqp
+	// amqp://:1234
+	// amqp://host:amqp/path
+	// amqps://host:amqps
+	// proton: bad URL ""
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
new file mode 100644
index 0000000..7c8024b
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
@@ -0,0 +1,192 @@
+/*
+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
+
+// #include <proton/disposition.h>
+import "C"
+
+import (
+	"net"
+	"qpid.apache.org/internal"
+	"qpid.apache.org/proton"
+	"qpid.apache.org/amqp"
+	"sync"
+)
+
+// Connection is an AMQP connection, created by a Container.
+type Connection interface {
+	Endpoint
+
+	// Server puts the connection in server mode, must be called before Open().
+	//
+	// A server connection will do protocol negotiation to accept a incoming AMQP
+	// connection. Normally you would call this for a connection created by
+	// net.Listener.Accept()
+	//
+	Server()
+
+	// Listen arranges for endpoints opened by the remote peer to be passed to accept().
+	// Listen() must be called before Connection.Open().
+	//
+	// accept() is passed a Session, Sender or Receiver.  It can examine endpoint
+	// properties and set some properties (e.g. Receiver.SetCapacity()) Returning nil
+	// will accept the endpoint, returning an error will reject it.
+	//
+	// accept() must not block or use the endpoint other than to examine or set
+	// properties.  It can start a goroutine to process the Endpoint, or pass the
+	// Endpoint to another goroutine via a channel, and that goroutine can use
+	// the endpoint as normal.
+	//
+	// The default Listen function is RejectEndpoint which rejects all endpoints.
+	// You can call Listen(AcceptEndpoint) to accept all endpoints
+	Listen(accept func(Endpoint) error)
+
+	// Open the connection, ready for use.
+	Open() error
+
+	// Sender opens a new sender on the DefaultSession.
+	//
+	// v can be a string, which is used as the Target address, or a SenderSettings
+	// struct containing more details settings.
+	Sender(setting ...LinkSetting) (Sender, error)
+
+	// Receiver opens a new Receiver on the DefaultSession().
+	//
+	// v can be a string, which is used as the
+	// Source address, or a ReceiverSettings struct containing more details
+	// settings.
+	Receiver(setting ...LinkSetting) (Receiver, error)
+
+	// DefaultSession() returns a default session for the connection. It is opened
+	// on the first call to DefaultSession and returned on subsequent calls.
+	DefaultSession() (Session, error)
+
+	// Session opens a new session.
+	Session() (Session, error)
+
+	// Container for the connection.
+	Container() Container
+
+	// Disconnect the connection abruptly with an error.
+	Disconnect(error)
+}
+
+// AcceptEndpoint pass to Connection.Listen to accept all endpoints
+func AcceptEndpoint(Endpoint) error { return nil }
+
+// RejectEndpoint pass to Connection.Listen to reject all endpoints
+func RejectEndpoint(Endpoint) error {
+	return amqp.Errorf(amqp.NotAllowed, "remote open rejected")
+}
+
+type connection struct {
+	endpoint
+	listenOnce, defaultSessionOnce, closeOnce sync.Once
+
+	// Set before Open()
+	container *container
+	conn      net.Conn
+	accept    func(Endpoint) error
+
+	// Set by Open()
+	handler     *handler
+	engine      *proton.Engine
+	err         internal.ErrorHolder
+	eConnection proton.Connection
+
+	defaultSession Session
+}
+
+func newConnection(conn net.Conn, cont *container) (*connection, error) {
+	c := &connection{container: cont, conn: conn, accept: RejectEndpoint}
+	c.handler = newHandler(c)
+	var err error
+	c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
+	if err != nil {
+		return nil, err
+	}
+	c.str = c.engine.String()
+	c.eConnection = c.engine.Connection()
+	return c, nil
+}
+
+func (c *connection) Server() { c.engine.Server() }
+
+func (c *connection) Listen(accept func(Endpoint) error) { c.accept = accept }
+
+func (c *connection) Open() error {
+	go c.engine.Run()
+	return nil
+}
+
+func (c *connection) Close(err error) { c.engine.Close(err) }
+
+func (c *connection) Disconnect(err error) { c.engine.Disconnect(err) }
+
+// FIXME aconway 2015-10-07:
+func (c *connection) closed(err error) {
+	// Call from another goroutine to initiate close without deadlock.
+	go c.Close(err)
+}
+
+func (c *connection) Session() (Session, error) {
+	var s Session
+	err := c.engine.InjectWait(func() error {
+		eSession, err := c.engine.Connection().Session()
+		if err == nil {
+			eSession.Open()
+			if err == nil {
+				s = newSession(c, eSession)
+			}
+		}
+		return err
+	})
+	return s, err
+}
+
+func (c *connection) Container() Container { return c.container }
+
+func (c *connection) DefaultSession() (s Session, err error) {
+	c.defaultSessionOnce.Do(func() {
+		c.defaultSession, err = c.Session()
+	})
+	if err == nil {
+		err = c.Error()
+	}
+	return c.defaultSession, err
+}
+
+func (c *connection) Sender(setting ...LinkSetting) (Sender, error) {
+	if s, err := c.DefaultSession(); err == nil {
+		return s.Sender(setting...)
+	} else {
+		return nil, err
+	}
+}
+
+func (c *connection) Receiver(setting ...LinkSetting) (Receiver, error) {
+	if s, err := c.DefaultSession(); err == nil {
+		return s.Receiver(setting...)
+	} else {
+		return nil, err
+	}
+}
+
+func (c *connection) Connection() Connection { return c }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/container.go b/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
new file mode 100644
index 0000000..06a9a14
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/container.go
@@ -0,0 +1,71 @@
+/*
+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
+
+import (
+	"net"
+	"qpid.apache.org/internal"
+)
+
+// Container is an AMQP container, it represents a single AMQP "application".It
+// provides functions to create new Connections to remote containers.
+//
+// Create with NewContainer()
+//
+type Container interface {
+	// Id is a unique identifier for the container in your distributed application.
+	Id() string
+
+	// Create a new AMQP Connection over the supplied net.Conn connection.
+	//
+	// You must call Connection.Open() on the returned Connection, after
+	// setting any Connection properties you need to set. Note the net.Conn
+	// can be an outgoing connection (e.g. made with net.Dial) or an incoming
+	// connection (e.g. made with net.Listener.Accept())
+	Connection(conn net.Conn) (Connection, error)
+}
+
+type container struct {
+	id        string
+	linkNames internal.IdCounter
+}
+
+// NewContainer creates a new container. The id must be unique in your
+// distributed application, all connections created by the container
+// will have this container-id.
+//
+// If id == "" a random UUID will be generated for the id.
+func NewContainer(id string) Container {
+	if id == "" {
+		id = internal.UUID4().String()
+	}
+	cont := &container{id: id}
+	return cont
+}
+
+func (cont *container) Id() string { return cont.id }
+
+func (cont *container) nextLinkName() string {
+	return cont.id + "@" + cont.linkNames.Next()
+}
+
+func (cont *container) Connection(conn net.Conn) (Connection, error) {
+	return newConnection(conn, cont)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/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
new file mode 100644
index 0000000..eaa6e7a
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/doc.go
@@ -0,0 +1,57 @@
+/*
+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 is a procedural, concurrent-safe Go library for AMQP messaging.
+You can write clients and servers using this library.
+
+Start by creating a Container with NewContainer. A Container represents a client
+or server application that can contain many incoming or outgoing connections.
+
+Create connections with the standard Go 'net' package using net.Dial or
+net.Listen. Create an AMQP connection over a net.Conn with
+Container.Connection() and open it with Connection.Open().
+
+AMQP sends messages over "links". Each link has a Sender end and a Receiver
+end. Connection.Sender() and Connection.Receiver() allow you to create links to
+Send() and Receive() messages.
+
+You can create an AMQP server connection by calling Connection.Server() and
+Connection.Listen() before calling Connection.Open(). A server connection can
+negotiate protocol security details and can accept incoming links opened from
+the remote end of the connection
+*/
+package electron
+
+//#cgo LDFLAGS: -lqpid-proton
+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.
+
+The handler sets up channels as needed to get or send data from user goroutines
+using electron types like Sender or Receiver. We also use Engine.Inject to inject
+actions into the event loop from user goroutines.
+
+*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/endpoint.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/endpoint.go b/proton-c/bindings/go/src/qpid.apache.org/electron/endpoint.go
new file mode 100644
index 0000000..745fd04
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/endpoint.go
@@ -0,0 +1,68 @@
+/*
+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
+
+import (
+	"io"
+	"qpid.apache.org/internal"
+	"qpid.apache.org/proton"
+)
+
+// Closed is an alias for io.EOF. It is returned as an error when an endpoint
+// was closed cleanly.
+var Closed = io.EOF
+
+// Endpoint is the common interface for Connection, Session, Link, Sender and Receiver.
+//
+// Endpoints can be created locally or by the remote peer. You must Open() an
+// endpoint before you can use it. Some endpoints have additional Set*() methods
+// that must be called before Open() to take effect, see Connection, Session,
+// Link, Sender and Receiver for details.
+//
+type Endpoint interface {
+	// Close an endpoint and signal an error to the remote end if error != nil.
+	Close(error)
+
+	// String is a human readable identifier, useful for debugging and logging.
+	String() string
+
+	// Error returns nil if the endpoint is open, otherwise returns an error.
+	// Error() == Closed means the endpoint was closed without error.
+	Error() error
+
+	// Connection containing the endpoint
+	Connection() Connection
+}
+
+type endpoint struct {
+	err internal.ErrorHolder
+	str string // Must be set by the value that embeds endpoint.
+}
+
+func (e *endpoint) String() string { return e.str }
+func (e *endpoint) Error() error   { return e.err.Get() }
+
+// Call in proton goroutine to close an endpoint locally
+// handler will complete the close when remote end closes.
+func localClose(ep proton.Endpoint, err error) {
+	if ep.State().LocalActive() {
+		proton.CloseError(ep, err)
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
new file mode 100644
index 0000000..f6065a1
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/handler.go
@@ -0,0 +1,176 @@
+/*
+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.
+*/
+
+// FIXME aconway 2015-10-07: move to amqp or split into sub packages?
+// proton.core
+// proton.msg
+
+package electron
+
+import (
+	"qpid.apache.org/proton"
+	"qpid.apache.org/amqp"
+)
+
+// NOTE: methods in this file are called only in the proton goroutine unless otherwise indicated.
+
+type handler struct {
+	delegator    *proton.MessagingDelegator
+	connection   *connection
+	links        map[proton.Link]Link
+	sentMessages map[proton.Delivery]*sentMessage
+	sessions     map[proton.Session]*session
+}
+
+func newHandler(c *connection) *handler {
+	h := &handler{
+		connection:   c,
+		links:        make(map[proton.Link]Link),
+		sentMessages: make(map[proton.Delivery]*sentMessage),
+		sessions:     make(map[proton.Session]*session),
+	}
+	h.delegator = proton.NewMessagingDelegator(h)
+	// Disable auto features of MessagingDelegator, we do these ourselves.
+	h.delegator.Prefetch = 0
+	h.delegator.AutoAccept = false
+	h.delegator.AutoSettle = false
+	h.delegator.AutoOpen = false
+	return h
+}
+
+func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
+	switch t {
+
+	case proton.MMessage:
+		if r, ok := h.links[e.Link()].(*receiver); ok {
+			r.message(e.Delivery())
+		} else {
+			proton.CloseError(
+				h.connection.eConnection,
+				amqp.Errorf(amqp.InternalError, "no receiver for link %s", e.Link()))
+		}
+
+	case proton.MSettled:
+		if sm := h.sentMessages[e.Delivery()]; sm != nil {
+			sm.settled(nil)
+		}
+
+	case proton.MSendable:
+		h.trySend(e.Link())
+
+	case proton.MSessionOpening:
+		if e.Session().State().LocalUninit() { // Remotely opened
+			s := newSession(h.connection, e.Session())
+			if err := h.connection.accept(s); err != nil {
+				proton.CloseError(e.Session(), (err))
+			} else {
+				h.sessions[e.Session()] = s
+				if s.capacity > 0 {
+					e.Session().SetIncomingCapacity(s.capacity)
+				}
+				e.Session().Open()
+			}
+		}
+
+	case proton.MSessionClosed:
+		err := proton.EndpointError(e.Session())
+		for l, _ := range h.links {
+			if l.Session() == e.Session() {
+				h.linkClosed(l, err)
+			}
+		}
+		delete(h.sessions, e.Session())
+
+	case proton.MLinkOpening:
+		l := e.Link()
+		if l.State().LocalUninit() { // Remotely opened
+			ss := h.sessions[l.Session()]
+			if ss == nil {
+				proton.CloseError(
+					l, amqp.Errorf(amqp.InternalError, ("no session for link")))
+				break
+			}
+			var link Link
+			if l.IsReceiver() {
+				r := &receiver{link: incomingLink(ss, l)}
+				link = r
+				r.inAccept = true
+				defer func() { r.inAccept = false }()
+			} else {
+				link = &sender{link: incomingLink(ss, l)}
+			}
+			if err := h.connection.accept(link); err != nil {
+				proton.CloseError(l, err)
+				break
+			}
+			link.open()
+		}
+
+	case proton.MLinkOpened:
+		l := e.Link()
+		if l.IsSender() {
+			h.trySend(l)
+		}
+
+	case proton.MLinkClosing:
+		e.Link().Close()
+
+	case proton.MLinkClosed:
+		h.linkClosed(e.Link(), proton.EndpointError(e.Link()))
+
+	case proton.MDisconnected:
+		err := h.connection.Error()
+		for l, _ := range h.links {
+			h.linkClosed(l, err)
+		}
+		for _, s := range h.sessions {
+			s.closed(err)
+		}
+		for _, sm := range h.sentMessages {
+			sm.settled(err)
+		}
+	}
+}
+
+func (h *handler) linkClosed(l proton.Link, err error) {
+	if link := h.links[l]; link != nil {
+		link.closed(err)
+		delete(h.links, l)
+	}
+}
+
+func (h *handler) addLink(rl proton.Link, ll Link) {
+	h.links[rl] = ll
+}
+
+func (h *handler) trySend(l proton.Link) {
+	if l.Credit() <= 0 {
+		return
+	}
+	if s, ok := h.links[l].(*sender); ok {
+		for ch := s.popBlocked(); l.Credit() > 0 && ch != nil; ch = s.popBlocked() {
+			if snd, ok := <-ch; ok {
+				s.doSend(snd)
+			}
+		}
+	} else {
+		h.connection.closed(
+			amqp.Errorf(amqp.InternalError, "cannot find sender for link %s", l))
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/link.go b/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
new file mode 100644
index 0000000..abc8431
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/link.go
@@ -0,0 +1,242 @@
+/*
+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
+
+import (
+	"qpid.apache.org/internal"
+	"qpid.apache.org/proton"
+)
+
+// Link is the common interface for AMQP links. Sender and Receiver provide
+// more methods for the sending or receiving end of a link respectively.
+type Link interface {
+	Endpoint
+
+	// Source address that messages are coming from.
+	Source() string
+
+	// Target address that messages are going to.
+	Target() string
+
+	// Name is a unique name for the link among links between the same
+	// containers in the same direction. By default generated automatically.
+	LinkName() string
+
+	// IsSender is true if this is the sending end of the link.
+	IsSender() bool
+
+	// IsReceiver is true if this is the receiving end of the link.
+	IsReceiver() bool
+
+	// SndSettle defines when the sending end of the link settles message delivery.
+	SndSettle() SndSettleMode
+
+	// RcvSettle defines when the sending end of the link settles message delivery.
+	RcvSettle() RcvSettleMode
+
+	// Session containing the Link
+	Session() Session
+
+	// Called in event loop on closed event.
+	closed(err error)
+	// Called to open a link (local or accepted incoming link)
+	open()
+}
+
+// LinkSetting is a function that sets a link property. Passed when creating
+// a Sender or Receiver, do not use at any other time.
+type LinkSetting func(Link)
+
+// Source sets address that messages are coming from.
+func Source(s string) LinkSetting { return func(l Link) { l.(*link).source = s } }
+
+// Target sets address that messages are going to.
+func Target(s string) LinkSetting { return func(l Link) { l.(*link).target = s } }
+
+// LinkName sets the link name.
+func LinkName(s string) LinkSetting { return func(l Link) { l.(*link).target = s } }
+
+// SndSettle sets the send settle mode
+func SndSettle(m SndSettleMode) LinkSetting { return func(l Link) { l.(*link).sndSettle = m } }
+
+// RcvSettle sets the send settle mode
+func RcvSettle(m RcvSettleMode) LinkSetting { return func(l Link) { l.(*link).rcvSettle = m } }
+
+// SndSettleMode defines when the sending end of the link settles message delivery.
+type SndSettleMode proton.SndSettleMode
+
+// Capacity sets the link capacity
+func Capacity(n int) LinkSetting { return func(l Link) { l.(*link).capacity = n } }
+
+// Prefetch sets a receivers pre-fetch flag. Not relevant for a sender.
+func Prefetch(p bool) LinkSetting { return func(l Link) { l.(*link).prefetch = p } }
+
+// AtMostOnce sets "fire and forget" mode, messages are sent but no
+// acknowledgment is received, messages can be lost if there is a network
+// failure. Sets SndSettleMode=SendSettled and RcvSettleMode=RcvFirst
+func AtMostOnce() LinkSetting {
+	return func(l Link) {
+		SndSettle(SndSettled)(l)
+		RcvSettle(RcvFirst)(l)
+	}
+}
+
+// AtLeastOnce requests acknowledgment for every message, acknowledgment
+// indicates the message was definitely received. In the event of a
+// failure, unacknowledged messages can be re-sent but there is a chance
+// that the message will be received twice in this case.
+// Sets SndSettleMode=SndUnsettled and RcvSettleMode=RcvFirst
+func AtLeastOnce() LinkSetting {
+	return func(l Link) {
+		SndSettle(SndUnsettled)(l)
+		RcvSettle(RcvFirst)(l)
+	}
+}
+
+const (
+	// Messages are sent unsettled
+	SndUnsettled = SndSettleMode(proton.SndUnsettled)
+	// Messages are sent already settled
+	SndSettled = SndSettleMode(proton.SndSettled)
+	// Sender can send either unsettled or settled messages.
+	SendMixed = SndSettleMode(proton.SndMixed)
+)
+
+// RcvSettleMode defines when the receiving end of the link settles message delivery.
+type RcvSettleMode proton.RcvSettleMode
+
+const (
+	// Receiver settles first.
+	RcvFirst = RcvSettleMode(proton.RcvFirst)
+	// Receiver waits for sender to settle before settling.
+	RcvSecond = RcvSettleMode(proton.RcvSecond)
+)
+
+type link struct {
+	endpoint
+
+	// Link settings.
+	source    string
+	target    string
+	linkName  string
+	isSender  bool
+	sndSettle SndSettleMode
+	rcvSettle RcvSettleMode
+	capacity  int
+	prefetch  bool
+
+	session *session
+	eLink   proton.Link
+	done    chan struct{} // Closed when link is closed
+
+	inAccept bool
+}
+
+func (l *link) Source() string           { return l.source }
+func (l *link) Target() string           { return l.target }
+func (l *link) LinkName() string         { return l.linkName }
+func (l *link) IsSender() bool           { return l.isSender }
+func (l *link) IsReceiver() bool         { return !l.isSender }
+func (l *link) SndSettle() SndSettleMode { return l.sndSettle }
+func (l *link) RcvSettle() RcvSettleMode { return l.rcvSettle }
+func (l *link) Session() Session         { return l.session }
+func (l *link) Connection() Connection   { return l.session.Connection() }
+
+func (l *link) engine() *proton.Engine { return l.session.connection.engine }
+func (l *link) handler() *handler      { return l.session.connection.handler }
+
+// Set up link fields and open the proton.Link
+func localLink(sn *session, isSender bool, setting ...LinkSetting) (*link, error) {
+	l := &link{
+		session:  sn,
+		isSender: isSender,
+		capacity: 1,
+		prefetch: false,
+		done:     make(chan struct{}),
+	}
+	for _, set := range setting {
+		set(l)
+	}
+	if l.linkName == "" {
+		l.linkName = l.session.connection.container.nextLinkName()
+	}
+	if l.IsSender() {
+		l.eLink = l.session.eSession.Sender(l.linkName)
+	} else {
+		l.eLink = l.session.eSession.Receiver(l.linkName)
+	}
+	if l.eLink.IsNil() {
+		l.err.Set(internal.Errorf("cannot create link %s", l))
+		return nil, l.err.Get()
+	}
+	l.eLink.Source().SetAddress(l.source)
+	l.eLink.Target().SetAddress(l.target)
+	l.eLink.SetSndSettleMode(proton.SndSettleMode(l.sndSettle))
+	l.eLink.SetRcvSettleMode(proton.RcvSettleMode(l.rcvSettle))
+	l.str = l.eLink.String()
+	l.eLink.Open()
+	return l, nil
+}
+
+// Set up a link from an incoming proton.Link.
+func incomingLink(sn *session, eLink proton.Link) link {
+	l := link{
+		session:   sn,
+		isSender:  eLink.IsSender(),
+		eLink:     eLink,
+		source:    eLink.RemoteSource().Address(),
+		target:    eLink.RemoteTarget().Address(),
+		linkName:  eLink.Name(),
+		sndSettle: SndSettleMode(eLink.RemoteSndSettleMode()),
+		rcvSettle: RcvSettleMode(eLink.RemoteRcvSettleMode()),
+		capacity:  1,
+		prefetch:  false,
+		done:      make(chan struct{}),
+	}
+	l.str = eLink.String()
+	return l
+}
+
+// Called in proton goroutine on closed or disconnected
+func (l *link) closed(err error) {
+	l.err.Set(err)
+	l.err.Set(Closed) // If no error set, mark as closed.
+	close(l.done)
+}
+
+// Not part of Link interface but use by Sender and Receiver.
+func (l *link) Credit() (credit int, err error) {
+	err = l.engine().InjectWait(func() error {
+		credit = l.eLink.Credit()
+		return nil
+	})
+	return
+}
+
+// Not part of Link interface but use by Sender and Receiver.
+func (l *link) Capacity() int { return l.capacity }
+
+func (l *link) Close(err error) {
+	l.engine().Inject(func() { localClose(l.eLink, err) })
+}
+
+func (l *link) open() {
+	l.eLink.Open()
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
new file mode 100644
index 0000000..474bad7
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
@@ -0,0 +1,412 @@
+/*
+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
+
+import (
+	"fmt"
+	"net"
+	"path"
+	"qpid.apache.org/amqp"
+	"runtime"
+	"testing"
+	"time"
+)
+
+func fatalIf(t *testing.T, err error) {
+	if err != nil { // FIXME aconway 2015-10-07:
+		_, file, line, ok := runtime.Caller(1) // annotate with location of caller.
+		if ok {
+			_, file = path.Split(file)
+		}
+		t.Fatalf("(from %s:%d) %v", file, line, err)
+	}
+}
+
+// Start a server, return listening addr and channel for incoming Connection.
+func newServer(t *testing.T, cont Container, accept func(Endpoint) error) (net.Addr, <-chan Connection) {
+	listener, err := net.Listen("tcp", "")
+	fatalIf(t, err)
+	addr := listener.Addr()
+	ch := make(chan Connection)
+	go func() {
+		conn, err := listener.Accept()
+		c, err := cont.Connection(conn)
+		fatalIf(t, err)
+		c.Server()
+		c.Listen(accept)
+		fatalIf(t, c.Open())
+		ch <- c
+	}()
+	return addr, ch
+}
+
+// Return open an client connection and session, return the session.
+func newClient(t *testing.T, cont Container, addr net.Addr) Session {
+	conn, err := net.Dial(addr.Network(), addr.String())
+	fatalIf(t, err)
+	c, err := cont.Connection(conn)
+	fatalIf(t, err)
+	c.Open()
+	sn, err := c.Session()
+	fatalIf(t, err)
+	return sn
+}
+
+// Return client and server ends of the same connection.
+func newClientServer(t *testing.T, accept func(Endpoint) error) (client Session, server Connection) {
+	addr, ch := newServer(t, NewContainer(""), accept)
+	client = newClient(t, NewContainer(""), addr)
+	return client, <-ch
+}
+
+// Close client and server
+func closeClientServer(client Session, server Connection) {
+	client.Connection().Close(nil)
+	server.Close(nil)
+}
+
+// Send a message one way with a client sender and server receiver, verify ack.
+func TestClientSendServerReceive(t *testing.T) {
+	timeout := time.Second * 2
+	nLinks := 3
+	nMessages := 3
+
+	rchan := make(chan Receiver, nLinks)
+	client, server := newClientServer(t, func(ep Endpoint) error {
+		if r, ok := ep.(Receiver); ok {
+			r.SetCapacity(1, false)
+			rchan <- r
+		}
+		return nil
+	})
+
+	defer func() {
+		closeClientServer(client, server)
+	}()
+
+	s := make([]Sender, nLinks)
+	for i := 0; i < nLinks; i++ {
+		var err error
+		s[i], err = client.Sender(Target(fmt.Sprintf("foo%d", i)))
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+	r := make([]Receiver, nLinks)
+	for i := 0; i < nLinks; i++ {
+		r[i] = <-rchan
+	}
+
+	for i := 0; i < nLinks; i++ {
+		for j := 0; j < nMessages; j++ {
+			var sm SentMessage
+			// Client send
+			go func() {
+				m := amqp.NewMessageWith(fmt.Sprintf("foobar%v-%v", i, j))
+				var err error
+				sm, err = s[i].Send(m)
+				if err != nil {
+					t.Fatal(err)
+				}
+			}()
+
+			// Server recieve
+			rm, err := r[i].Receive()
+			if err != nil {
+				t.Fatal(err)
+			}
+			if want, got := interface{}(fmt.Sprintf("foobar%v-%v", i, j)), rm.Message.Body(); want != got {
+				t.Errorf("%#v != %#v", want, got)
+			}
+
+			// Should not be acknowledged on client yet
+			if d, err := sm.DispositionTimeout(0); err != Timeout || NoDisposition != d {
+				t.Errorf("want [no-disposition/timeout] got [%v/%v]", d, err)
+			}
+			// Server ack
+			if err := rm.Acknowledge(Rejected); err != nil {
+				t.Error(err)
+			}
+			// Client get ack.
+			if d, err := sm.DispositionTimeout(timeout); err != nil || Rejected != d {
+				t.Errorf("want [rejected/nil] got [%v/%v]", d, err)
+			}
+		}
+	}
+}
+
+func TestClientReceiver(t *testing.T) {
+	nMessages := 3
+	client, server := newClientServer(t, func(ep Endpoint) error {
+		if s, ok := ep.(Sender); ok {
+			go func() {
+				for i := int32(0); i < int32(nMessages); i++ {
+					sm, err := s.Send(amqp.NewMessageWith(i))
+					if err != nil {
+						t.Error(err)
+						return
+					} else {
+						sm.Disposition() // Sync send.
+					}
+				}
+				s.Close(nil)
+			}()
+		}
+		return nil
+	})
+
+	r, err := client.Receiver(Source("foo"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i := int32(0); i < int32(nMessages); i++ {
+		rm, err := r.Receive()
+		if err != nil {
+			if err != Closed {
+				t.Error(err)
+			}
+			break
+		}
+		if err := rm.Accept(); err != nil {
+			t.Error(err)
+		}
+		if b, ok := rm.Message.Body().(int32); !ok || b != i {
+			t.Errorf("want %v, true got %v, %v", i, b, ok)
+		}
+	}
+	server.Close(nil)
+	client.Connection().Close(nil)
+}
+
+// Test timeout versions of waiting functions.
+func TestTimeouts(t *testing.T) {
+	var err error
+	rchan := make(chan Receiver, 1)
+	client, server := newClientServer(t, func(ep Endpoint) error {
+		if r, ok := ep.(Receiver); ok {
+			r.SetCapacity(1, false) // Issue credit only on receive
+			rchan <- r
+		}
+		return nil
+	})
+	defer func() { closeClientServer(client, server) }()
+
+	// Open client sender
+	snd, err := client.Sender(Target("test"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	rcv := <-rchan
+
+	// Test send with timeout
+	short := time.Millisecond
+	long := time.Second
+	m := amqp.NewMessage()
+	if _, err = snd.SendTimeout(m, 0); err != Timeout { // No credit, expect timeout.
+		t.Error("want Timeout got", err)
+	}
+	if _, err = snd.SendTimeout(m, short); err != Timeout { // No credit, expect timeout.
+		t.Error("want Timeout got", err)
+	}
+	// Test receive with timeout
+	if _, err = rcv.ReceiveTimeout(0); err != Timeout { // No credit, expect timeout.
+		t.Error("want Timeout got", err)
+	}
+	// Test receive with timeout
+	if _, err = rcv.ReceiveTimeout(short); err != Timeout { // No credit, expect timeout.
+		t.Error("want Timeout got", err)
+	}
+	// There is now a credit on the link due to receive
+	sm, err := snd.SendTimeout(m, long)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Disposition should timeout
+	if _, err = sm.DispositionTimeout(long); err != Timeout {
+		t.Error("want Timeout got", err)
+	}
+	if _, err = sm.DispositionTimeout(short); err != Timeout {
+		t.Error("want Timeout got", err)
+	}
+	// Receive and accept
+	rm, err := rcv.ReceiveTimeout(long)
+	if err != nil {
+		t.Fatal(err)
+	}
+	rm.Accept()
+	// Sender get ack
+	d, err := sm.DispositionTimeout(long)
+	if err != nil || d != Accepted {
+		t.Errorf("want (rejected, nil) got (%v, %v)", d, err)
+	}
+}
+
+// clientServer that returns sender/receiver pairs at opposite ends of link.
+type pairs struct {
+	t      *testing.T
+	client Session
+	server Connection
+	rchan  chan Receiver
+	schan  chan Sender
+}
+
+func newPairs(t *testing.T) *pairs {
+	p := &pairs{t: t, rchan: make(chan Receiver, 1), schan: make(chan Sender, 1)}
+	p.client, p.server = newClientServer(t, func(ep Endpoint) error {
+		switch ep := ep.(type) {
+		case Receiver:
+			ep.SetCapacity(1, false)
+			p.rchan <- ep
+		case Sender:
+			p.schan <- ep
+		}
+		return nil
+	})
+	return p
+}
+
+func (p *pairs) close() {
+	closeClientServer(p.client, p.server)
+}
+
+func (p *pairs) senderReceiver() (Sender, Receiver) {
+	snd, err := p.client.Sender()
+	fatalIf(p.t, err)
+	rcv := <-p.rchan
+	return snd, rcv
+}
+
+func (p *pairs) receiverSender() (Receiver, Sender) {
+	rcv, err := p.client.Receiver()
+	fatalIf(p.t, err)
+	snd := <-p.schan
+	return rcv, snd
+}
+
+type result struct {
+	label string
+	err   error
+}
+
+func (r result) String() string { return fmt.Sprintf("%s(%s)", r.err, r.label) }
+
+func doSend(snd Sender, results chan result) {
+	_, err := snd.Send(amqp.NewMessage())
+	results <- result{"send", err}
+}
+
+func doReceive(rcv Receiver, results chan result) {
+	_, err := rcv.Receive()
+	results <- result{"receive", err}
+}
+
+func doDisposition(sm SentMessage, results chan result) {
+	_, err := sm.Disposition()
+	results <- result{"disposition", err}
+}
+
+// Test that closing Links interrupts blocked link functions.
+func TestLinkCloseInterrupt(t *testing.T) {
+	want := amqp.Errorf("x", "all bad")
+	pairs := newPairs(t)
+	results := make(chan result) // Collect expected errors
+
+	// Sender.Close() interrupts Send()
+	snd, rcv := pairs.senderReceiver()
+	go doSend(snd, results)
+	snd.Close(want)
+	if r := <-results; want != r.err {
+		t.Errorf("want %#v got %#v", want, r)
+	}
+
+	// Remote Receiver.Close() interrupts Send()
+	snd, rcv = pairs.senderReceiver()
+	go doSend(snd, results)
+	rcv.Close(want)
+	if r := <-results; want != r.err {
+		t.Errorf("want %#v got %#v", want, r)
+	}
+
+	// Receiver.Close() interrupts Receive()
+	snd, rcv = pairs.senderReceiver()
+	go doReceive(rcv, results)
+	rcv.Close(want)
+	if r := <-results; want != r.err {
+		t.Errorf("want %#v got %#v", want, r)
+	}
+
+	// Remote Sender.Close() interrupts Receive()
+	snd, rcv = pairs.senderReceiver()
+	go doReceive(rcv, results)
+	snd.Close(want)
+	if r := <-results; want != r.err {
+		t.Errorf("want %#v got %#v", want, r)
+	}
+}
+
+// Test closing the server end of a connection.
+func TestConnectionCloseInterrupt1(t *testing.T) {
+	want := amqp.Errorf("x", "bad")
+	pairs := newPairs(t)
+	results := make(chan result) // Collect expected errors
+
+	// Connection.Close() interrupts Send, Receive, Disposition.
+	snd, rcv := pairs.senderReceiver()
+	go doReceive(rcv, results)
+	sm, err := snd.Send(amqp.NewMessage())
+	fatalIf(t, err)
+	go doDisposition(sm, results)
+	snd, rcv = pairs.senderReceiver()
+	go doSend(snd, results)
+	rcv, snd = pairs.receiverSender()
+	go doReceive(rcv, results)
+	pairs.server.Close(want)
+	for i := 0; i < 3; i++ {
+		if r := <-results; want != r.err {
+			// TODO aconway 2015-10-06: Not propagating the correct error, seeing nil and EOF.
+			t.Logf("want %v got %v", want, r)
+		}
+	}
+}
+
+// Test closing the client end of the connection.
+func TestConnectionCloseInterrupt2(t *testing.T) {
+	want := amqp.Errorf("x", "bad")
+	pairs := newPairs(t)
+	results := make(chan result) // Collect expected errors
+
+	// Connection.Close() interrupts Send, Receive, Disposition.
+	snd, rcv := pairs.senderReceiver()
+	go doReceive(rcv, results)
+	sm, err := snd.Send(amqp.NewMessage())
+	fatalIf(t, err)
+	go doDisposition(sm, results)
+	snd, rcv = pairs.senderReceiver()
+	go doSend(snd, results)
+	rcv, snd = pairs.receiverSender()
+	go doReceive(rcv, results)
+	pairs.client.Close(want)
+	for i := 0; i < 3; i++ {
+		if r := <-results; want != r.err {
+			// TODO aconway 2015-10-06: Not propagating the correct error, seeing nil.
+			t.Logf("want %v got %v", want, r)
+		}
+	}
+}


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


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

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


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

Branch: refs/heads/go1
Commit: 8dc93cd08c786b30fc1e76312e6761739a791d5a
Parents: 581841f f70afb6
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 23 10:22:12 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 23 10:22:12 2015 -0400

----------------------------------------------------------------------
 README.md                    |  96 +++++
 amqp/doc.go                  |  34 ++
 amqp/error.go                |  66 +++
 amqp/interop                 |   1 +
 amqp/interop_test.go         | 381 +++++++++++++++++
 amqp/marshal.go              | 250 +++++++++++
 amqp/message.go              | 347 +++++++++++++++
 amqp/message_test.go         | 166 ++++++++
 amqp/types.go                | 199 +++++++++
 amqp/unmarshal.go            | 558 ++++++++++++++++++++++++
 amqp/url.go                  |  96 +++++
 amqp/url_test.go             |  51 +++
 electron/connection.go       | 218 ++++++++++
 electron/container.go        |  71 ++++
 electron/doc.go              |  57 +++
 electron/endpoint.go         |  68 +++
 electron/handler.go          | 158 +++++++
 electron/link.go             | 247 +++++++++++
 electron/messaging_test.go   | 416 ++++++++++++++++++
 electron/receiver.go         | 238 +++++++++++
 electron/sender.go           | 315 ++++++++++++++
 electron/session.go          | 125 ++++++
 electron/time.go             |  82 ++++
 internal/error.go            | 118 +++++
 internal/flexchannel.go      |  82 ++++
 internal/flexchannel_test.go |  89 ++++
 internal/safemap.go          |  57 +++
 internal/uuid.go             |  70 +++
 proton/doc.go                |  51 ++-
 proton/engine.go             | 402 ++++++++++++++++++
 proton/handlers.go           | 391 +++++++++++++++++
 proton/message.go            |  86 ++++
 proton/proton_test.go        |  27 ++
 proton/wrappers.go           | 384 +++++++++++++++++
 proton/wrappers_gen.go       | 874 ++++++++++++++++++++++++++++++++++++++
 readme-branch.md             |   7 +
 36 files changed, 6871 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/README.md
----------------------------------------------------------------------
diff --cc README.md
index 0000000,9f95939..4b2da12
mode 000000,100644..100644
--- a/README.md
+++ b/README.md
@@@ -1,0 -1,44 +1,96 @@@
 -Qpid Proton - AMQP messaging toolkit
 -====================================
 -
 -Linux Build | Windows Build
 -------------|--------------
 -[![Linux Build Status](https://travis-ci.org/apache/qpid-proton.svg?branch=master)](https://travis-ci.org/apache/qpid-proton) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/apache/qpid-proton?branch=master&svg=true)](https://ci.appveyor.com/project/ke4qqq/qpid-proton/branch/master)
 -
 -Qpid Proton is a high-performance, lightweight messaging library. It can be
 -used in the widest range of messaging applications, including brokers, client
 -libraries, routers, bridges, proxies, and more. Proton makes it trivial to
 -integrate with the AMQP 1.0 ecosystem from any platform, environment, or
 -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
 -  + Pure-Java and pure-JavaScript implementations
 -  + 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
 -peer-to-peer configurations or as part of a global federated messaging network.
 -
 -Embeddable - Proton is carefully written to be portable and cross platform. It
 -has minimal dependencies, and it is architected to be usable with any threading
 -model, as well as with non-threaded applications. These features make it
 -uniquely suited for embedding messaging capabilities into existing software.
 -
 -Standard - Built around the AMQP 1.0 messaging standard, Proton is not only
 -ideal for building out your own messaging applications but also for connecting
 -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
 -DEVELOPERS file for information on how to modify and test the library code
 -itself.
 -
 -Please see http://qpid.apache.org/proton for a more info.
++# Qpid Go packages for AMQP
++
++These packages provide [Go](http://golang.org) support for sending and receiving
++AMQP messages in client or server applications. Reference documentation is
++available at: <http://godoc.org/?q=qpid.apache.org>
++
++There are 3 packages:
++
++[qpid.apache.org/amqp](http://godoc.org/qpid.apache.org/amqp) provides functions
++to convert AMQP messages and data types to and from Go data types.  Used by both
++the proton and electron packages to manage AMQP data.
++
++[qpid.apache.org/electron](http://godoc.org/qpid.apache.org/electron) is a
++simple, concurrent-safe API for sending and receiving messages. It can be used
++with goroutines and channels to build concurrent AMQP clients and servers.
++
++[qpid.apache.org/proton](http://godoc.org/qpid.apache.org/proton) is an
++event-driven, concurrent-unsafe package that closely follows the proton C
++API. Most Go programmers will find the electron package easier to use.
++
++There are [examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
++to help you get started.
++
++Feedback is encouraged at:
++
++- Email <pr...@qpid.apache.org>
++- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.
++
++### Why two APIs?
++
++The `proton` API is a direct mapping of the proton C library into Go. It is
++usable but not very natural for a Go programmer because it takes an
++*event-driven* approach and has no built-in support for concurrent
++use. `electron` uses `proton` internally but provides a more Go-like API that is
++safe to use from multiple concurrent goroutines.
++
++Go encourages programs to be structured as concurrent *goroutines* that
++communicate via *channels*. Go literature distinguishes between:
++
++- *concurrency*: "keeping track of things that could be done in parallel"
++- *parallelism*: "actually doing things in parallel on multiple CPUs or cores"
++
++A Go program expresses concurrency by starting goroutines for potentially
++concurrent tasks. The Go runtime schedules the activity of goroutines onto a
++small number (possibly one) of actual parallel executions.
++
++Even with no hardware parallelism, goroutine concurrency lets the Go runtime
++order unpredictable events like file descriptors being readable/writable,
++channels having data, timers firing etc. Go automatically takes care of
++switching out goroutines that block or sleep so it is normal to write code in
++terms of blocking calls.
++
++By contrast, event-driven programming is based on polling mechanisms like
++`select`, `poll` or `epoll`. These also dispatch unpredictably ordered events to
++a single thread or a small thread pool. However this requires a different style
++of programming: "event-driven" or "reactive" programming. Go developers call it
++"inside-out" programming.  In an event-driven program blocking is a big problem
++as it consumes a scarce thread of execution, so actions that take time to
++complete have to be re-structured in terms of multiple events.
++
++The promise of Go is that you can express your program in concurrent, sequential
++terms and the Go runtime will turn it inside-out for you. You can start
++goroutines for all concurrent activities. They can loop forever or block for as
++long as they need waiting for timers, IO or any unpredictable event. Go will
++interleave and schedule them efficiently onto the available parallel hardware.
++
++For example: in the `electron` API, you can send a message and wait for it to be
++acknowledged in a single function. All the information about the message, why
++you sent it, and what to do when it is acknowledged can be held in local
++variables, all the code is in a simple sequence. Other goroutines in your
++program can be sending and receiving messages concurrently, they are not
++blocked.
++
++In the `proton` API, an event handler that sends a message must return
++*immediately*, it cannot block the event loop to wait for
++acknowledgement. Acknowledgement is a separate event, so the code for handling
++it is in a different event handler. Context information about the message has to
++be stored in some non-local variable that both functions can find. This makes
++the code harder to follow.
++
++The `proton` API is important because it is the foundation for the `electron`
++API, and may be useful for programs that need to be close to the original C
++library for some reason. However the `electron` API hides the event-driven
++details behind simple, sequential, concurrent-safe methods that can be called
++from arbitrary goroutines. Under the covers, data is passed through channels to
++dedicated `proton` goroutines so user goroutines can work concurrently with the
++proton event-loop.
++
++## New to Go?
++
++If you are new to Go then these are a good place to start:
++
++- [A Tour of Go](http://tour.golang.org)
++- [Effective Go](http://golang.org/doc/effective_go.html)
++
++Then look at the tools and docs at <http://golang.org> as you need them.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/doc.go
----------------------------------------------------------------------
diff --cc amqp/doc.go
index 0000000,0000000..323c344
new file mode 100644
--- /dev/null
+++ b/amqp/doc.go
@@@ -1,0 -1,0 +1,34 @@@
++/*
++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 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.
++
++AMQP is an open standard for inter-operable message exchange, see <http://www.amqp.org/>
++*/
++package amqp
++
++// #cgo LDFLAGS: -lqpid-proton
++import "C"
++
++// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/error.go
----------------------------------------------------------------------
diff --cc amqp/error.go
index 0000000,0000000..868dbf3
new file mode 100644
--- /dev/null
+++ b/amqp/error.go
@@@ -1,0 -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 amqp
++
++import (
++	"fmt"
++	"reflect"
++)
++
++// Error is an AMQP error condition. It has a name and a description.
++// It implements the Go error interface so can be returned as an error value.
++//
++// You can pass amqp.Error to methods that pass an error to a remote endpoint,
++// this gives you full control over what the remote endpoint will see.
++//
++// You can also pass any Go error to such functions, the remote peer
++// will see the equivalent of MakeError(error)
++//
++type Error struct{ Name, Description string }
++
++// Error implements the Go error interface for AMQP error errors.
++func (c Error) Error() string { return fmt.Sprintf("proton %s: %s", c.Name, c.Description) }
++
++// Errorf makes a Error with name and formatted description as per fmt.Sprintf
++func Errorf(name, format string, arg ...interface{}) Error {
++	return Error{name, fmt.Sprintf(format, arg...)}
++}
++
++// MakeError makes an AMQP error from a go error using the Go error type as the name
++// and the err.Error() string as the description.
++func MakeError(err error) Error {
++	return Error{reflect.TypeOf(err).Name(), err.Error()}
++}
++
++var (
++	InternalError      = "amqp:internal-error"
++	NotFound           = "amqp:not-found"
++	UnauthorizedAccess = "amqp:unauthorized-access"
++	DecodeError        = "amqp:decode-error"
++	ResourceLimit      = "amqp:resource-limit"
++	NotAllowed         = "amqp:not-allowed"
++	InvalidField       = "amqp:invalid-field"
++	NotImplemented     = "amqp:not-implemented"
++	ResourceLocked     = "amqp:resource-locked"
++	PreerrorFailed     = "amqp:preerror-failed"
++	ResourceDeleted    = "amqp:resource-deleted"
++	IllegalState       = "amqp:illegal-state"
++	FrameSizeTooSmall  = "amqp:frame-size-too-small"
++)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/interop
----------------------------------------------------------------------
diff --cc amqp/interop
index 0000000,0000000..ad6fcad
new file mode 120000
--- /dev/null
+++ b/amqp/interop
@@@ -1,0 -1,0 +1,1 @@@
++../../../../../../tests/interop

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/interop_test.go
----------------------------------------------------------------------
diff --cc amqp/interop_test.go
index 0000000,0000000..b36ef64
new file mode 100644
--- /dev/null
+++ b/amqp/interop_test.go
@@@ -1,0 -1,0 +1,381 @@@
++/*
++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 that conversion of Go type to/from AMQP is compatible with other
++// bindings.
++//
++package amqp
++
++import (
++	"bytes"
++	"fmt"
++	"io"
++	"io/ioutil"
++	"os"
++	"reflect"
++	"strings"
++	"testing"
++)
++
++func checkEqual(want interface{}, got interface{}) error {
++	if !reflect.DeepEqual(want, got) {
++		return fmt.Errorf("%#v != %#v", want, got)
++	}
++	return nil
++}
++
++func getReader(name string) (r io.Reader) {
++	r, err := os.Open("interop/" + name + ".amqp")
++	if err != nil {
++		panic(fmt.Errorf("Can't open %#v: %v", name, err))
++	}
++	return
++}
++
++func remaining(d *Decoder) string {
++	remainder, _ := ioutil.ReadAll(io.MultiReader(d.Buffered(), d.reader))
++	return string(remainder)
++}
++
++// checkDecode: want is the expected value, gotPtr is a pointer to a
++// instance of the same type for Decode.
++func checkDecode(d *Decoder, want interface{}, gotPtr interface{}, t *testing.T) {
++
++	if err := d.Decode(gotPtr); err != nil {
++		t.Error("Decode failed", err)
++		return
++	}
++	got := reflect.ValueOf(gotPtr).Elem().Interface()
++	if err := checkEqual(want, got); err != nil {
++		t.Error("Decode bad value:", err)
++		return
++	}
++
++	// Try round trip encoding
++	bytes, err := Marshal(want, nil)
++	if err != nil {
++		t.Error("Marshal failed", err)
++		return
++	}
++	n, err := Unmarshal(bytes, gotPtr)
++	if err != nil {
++		t.Error("Unmarshal failed", err)
++		return
++	}
++	if err := checkEqual(n, len(bytes)); err != nil {
++		t.Error("Bad unmarshal length", err)
++		return
++	}
++	got = reflect.ValueOf(gotPtr).Elem().Interface()
++	if err = checkEqual(want, got); err != nil {
++		t.Error("Bad unmarshal value", err)
++		return
++	}
++}
++
++func TestUnmarshal(t *testing.T) {
++	bytes, err := ioutil.ReadAll(getReader("strings"))
++	if err != nil {
++		t.Error(err)
++	}
++	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
++		var got string
++		n, err := Unmarshal(bytes, &got)
++		if err != nil {
++			t.Error(err)
++		}
++		if want != got {
++			t.Errorf("%#v != %#v", want, got)
++		}
++		bytes = bytes[n:]
++	}
++}
++
++func TestPrimitivesExact(t *testing.T) {
++	d := NewDecoder(getReader("primitives"))
++	// Decoding into exact types
++	var b bool
++	checkDecode(d, true, &b, t)
++	checkDecode(d, false, &b, t)
++	var u8 uint8
++	checkDecode(d, uint8(42), &u8, t)
++	var u16 uint16
++	checkDecode(d, uint16(42), &u16, t)
++	var i16 int16
++	checkDecode(d, int16(-42), &i16, t)
++	var u32 uint32
++	checkDecode(d, uint32(12345), &u32, t)
++	var i32 int32
++	checkDecode(d, int32(-12345), &i32, t)
++	var u64 uint64
++	checkDecode(d, uint64(12345), &u64, t)
++	var i64 int64
++	checkDecode(d, int64(-12345), &i64, t)
++	var f32 float32
++	checkDecode(d, float32(0.125), &f32, t)
++	var f64 float64
++	checkDecode(d, float64(0.125), &f64, t)
++}
++
++func TestPrimitivesCompatible(t *testing.T) {
++	d := NewDecoder(getReader("primitives"))
++	// Decoding into compatible types
++	var b bool
++	var i int
++	var u uint
++	var f float64
++	checkDecode(d, true, &b, t)
++	checkDecode(d, false, &b, t)
++	checkDecode(d, uint(42), &u, t)
++	checkDecode(d, uint(42), &u, t)
++	checkDecode(d, -42, &i, t)
++	checkDecode(d, uint(12345), &u, t)
++	checkDecode(d, -12345, &i, t)
++	checkDecode(d, uint(12345), &u, t)
++	checkDecode(d, -12345, &i, t)
++	checkDecode(d, 0.125, &f, t)
++	checkDecode(d, 0.125, &f, t)
++}
++
++// checkDecodeValue: want is the expected value, decode into a reflect.Value
++func checkDecodeInterface(d *Decoder, want interface{}, t *testing.T) {
++
++	var got, got2 interface{}
++	if err := d.Decode(&got); err != nil {
++		t.Error("Decode failed", err)
++		return
++	}
++	if err := checkEqual(want, got); err != nil {
++		t.Error(err)
++		return
++	}
++	// Try round trip encoding
++	bytes, err := Marshal(got, nil)
++	if err != nil {
++		t.Error(err)
++		return
++	}
++	n, err := Unmarshal(bytes, &got2)
++	if err != nil {
++		t.Error(err)
++		return
++	}
++	if err := checkEqual(n, len(bytes)); err != nil {
++		t.Error(err)
++		return
++	}
++	if err := checkEqual(want, got2); err != nil {
++		t.Error(err)
++		return
++	}
++}
++
++func TestPrimitivesInterface(t *testing.T) {
++	d := NewDecoder(getReader("primitives"))
++	checkDecodeInterface(d, true, t)
++	checkDecodeInterface(d, false, t)
++	checkDecodeInterface(d, uint8(42), t)
++	checkDecodeInterface(d, uint16(42), t)
++	checkDecodeInterface(d, int16(-42), t)
++	checkDecodeInterface(d, uint32(12345), t)
++	checkDecodeInterface(d, int32(-12345), t)
++	checkDecodeInterface(d, uint64(12345), t)
++	checkDecodeInterface(d, int64(-12345), t)
++	checkDecodeInterface(d, float32(0.125), t)
++	checkDecodeInterface(d, float64(0.125), t)
++}
++
++func TestStrings(t *testing.T) {
++	d := NewDecoder(getReader("strings"))
++	// Test decoding as plain Go strings
++	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
++		var got string
++		checkDecode(d, want, &got, t)
++	}
++	remains := remaining(d)
++	if remains != "" {
++		t.Errorf("leftover: %s", remains)
++	}
++
++	// Test decoding as specific string types
++	d = NewDecoder(getReader("strings"))
++	var bytes []byte
++	var str, sym string
++	checkDecode(d, []byte("abc\000defg"), &bytes, t)
++	checkDecode(d, "abcdefg", &str, t)
++	checkDecode(d, "abcdefg", &sym, t)
++	checkDecode(d, make([]byte, 0), &bytes, t)
++	checkDecode(d, "", &str, t)
++	checkDecode(d, "", &sym, t)
++	remains = remaining(d)
++	if remains != "" {
++		t.Fatalf("leftover: %s", remains)
++	}
++
++	// Test some error handling
++	d = NewDecoder(getReader("strings"))
++	var s string
++	err := d.Decode(s)
++	if err == nil {
++		t.Fatal("Expected error")
++	}
++	if !strings.Contains(err.Error(), "not a pointer") {
++		t.Error(err)
++	}
++	var i int
++	err = d.Decode(&i)
++	if !strings.Contains(err.Error(), "cannot unmarshal") {
++		t.Error(err)
++	}
++	_, err = Unmarshal([]byte{}, nil)
++	if !strings.Contains(err.Error(), "not enough data") {
++		t.Error(err)
++	}
++	_, err = Unmarshal([]byte("foobar"), nil)
++	if !strings.Contains(err.Error(), "invalid-argument") {
++		t.Error(err)
++	}
++}
++
++func TestEncodeDecode(t *testing.T) {
++	type data struct {
++		s  string
++		i  int
++		u8 uint8
++		b  bool
++		f  float32
++		v  interface{}
++	}
++
++	in := data{"foo", 42, 9, true, 1.234, "thing"}
++
++	buf := bytes.Buffer{}
++	e := NewEncoder(&buf)
++	if err := e.Encode(in.s); err != nil {
++		t.Error(err)
++	}
++	if err := e.Encode(in.i); err != nil {
++		t.Error(err)
++	}
++	if err := e.Encode(in.u8); err != nil {
++		t.Error(err)
++	}
++	if err := e.Encode(in.b); err != nil {
++		t.Error(err)
++	}
++	if err := e.Encode(in.f); err != nil {
++		t.Error(err)
++	}
++	if err := e.Encode(in.v); err != nil {
++		t.Error(err)
++	}
++
++	var out data
++	d := NewDecoder(&buf)
++	if err := d.Decode(&out.s); err != nil {
++		t.Error(err)
++	}
++	if err := d.Decode(&out.i); err != nil {
++		t.Error(err)
++	}
++	if err := d.Decode(&out.u8); err != nil {
++		t.Error(err)
++	}
++	if err := d.Decode(&out.b); err != nil {
++		t.Error(err)
++	}
++	if err := d.Decode(&out.f); err != nil {
++		t.Error(err)
++	}
++	if err := d.Decode(&out.v); err != nil {
++		t.Error(err)
++	}
++
++	if err := checkEqual(in, out); err != nil {
++		t.Error(err)
++	}
++}
++
++func TestMap(t *testing.T) {
++	d := NewDecoder(getReader("maps"))
++
++	// Generic map
++	var m Map
++	checkDecode(d, Map{"one": int32(1), "two": int32(2), "three": int32(3)}, &m, t)
++
++	// Interface as map
++	var i interface{}
++	checkDecode(d, Map{int32(1): "one", int32(2): "two", int32(3): "three"}, &i, t)
++
++	d = NewDecoder(getReader("maps"))
++	// Specific typed map
++	var m2 map[string]int
++	checkDecode(d, map[string]int{"one": 1, "two": 2, "three": 3}, &m2, t)
++
++	// Nested map
++	m = Map{int64(1): "one", "two": int32(2), true: Map{uint8(1): true, uint8(2): false}}
++	bytes, err := Marshal(m, nil)
++	if err != nil {
++		t.Fatal(err)
++	}
++	_, err = Unmarshal(bytes, &i)
++	if err != nil {
++		t.Fatal(err)
++	}
++	if err = checkEqual(m, i); err != nil {
++		t.Fatal(err)
++	}
++}
++
++func TestList(t *testing.T) {
++	d := NewDecoder(getReader("lists"))
++	var l List
++	checkDecode(d, List{int32(32), "foo", true}, &l, t)
++	checkDecode(d, List{}, &l, t)
++}
++
++// TODO aconway 2015-09-08: the message.amqp file seems to be incorrectly coded as
++// as an AMQP string *inside* an AMQP binary?? Skip the test for now.
++func TODO_TestMessage(t *testing.T) {
++	bytes, err := ioutil.ReadAll(getReader("message"))
++	if err != nil {
++		t.Fatal(err)
++	}
++
++	m, err := DecodeMessage(bytes)
++	if err != nil {
++		t.Fatal(err)
++	} else {
++		if err := checkEqual(m.Body(), "hello"); err != nil {
++			t.Error(err)
++		}
++	}
++
++	m2 := NewMessageWith("hello")
++	bytes2, err := m2.Encode(nil)
++	if err != nil {
++		t.Error(err)
++	} else {
++		if err = checkEqual(bytes, bytes2); err != nil {
++			t.Error(err)
++		}
++	}
++}
++
++// TODO aconway 2015-03-13: finish the full interop test

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/marshal.go
----------------------------------------------------------------------
diff --cc amqp/marshal.go
index 0000000,0000000..666b4f6
new file mode 100644
--- /dev/null
+++ b/amqp/marshal.go
@@@ -1,0 -1,0 +1,250 @@@
++/*
++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
++
++// #include <proton/codec.h>
++import "C"
++
++import (
++	"io"
++	"qpid.apache.org/internal"
++	"reflect"
++	"unsafe"
++)
++
++func dataError(prefix string, data *C.pn_data_t) error {
++	err := internal.PnError(unsafe.Pointer(C.pn_data_error(data)))
++	if err != nil {
++		err = internal.Errorf("%s: %s", prefix, err.(internal.Error))
++	}
++	return err
++}
++
++/*
++Marshal encodes a Go value as AMQP data in buffer.
++If buffer is nil, or is not large enough, a new buffer  is created.
++
++Returns the buffer used for encoding with len() adjusted to the actual size of data.
++
++Go types are encoded as follows
++
++ +-------------------------------------+--------------------------------------------+
++ |Go type                              |AMQP type                                   |
++ +-------------------------------------+--------------------------------------------+
++ |bool                                 |bool                                        |
++ +-------------------------------------+--------------------------------------------+
++ |int8, int16, int32, int64 (int)      |byte, short, int, long (int or long)        |
++ +-------------------------------------+--------------------------------------------+
++ |uint8, uint16, uint32, uint64 (uint) |ubyte, ushort, uint, ulong (uint or ulong)  |
++ +-------------------------------------+--------------------------------------------+
++ |float32, float64                     |float, double.                              |
++ +-------------------------------------+--------------------------------------------+
++ |string                               |string                                      |
++ +-------------------------------------+--------------------------------------------+
++ |[]byte, Binary                       |binary                                      |
++ +-------------------------------------+--------------------------------------------+
++ |Symbol                               |symbol                                      |
++ +-------------------------------------+--------------------------------------------+
++ |interface{}                          |the contained type                          |
++ +-------------------------------------+--------------------------------------------+
++ |nil                                  |null                                        |
++ +-------------------------------------+--------------------------------------------+
++ |map[K]T                              |map with K and T converted as above         |
++ +-------------------------------------+--------------------------------------------+
++ |Map                                  |map, may have mixed types for keys, values  |
++ +-------------------------------------+--------------------------------------------+
++ |[]T                                  |list with T converted as above              |
++ +-------------------------------------+--------------------------------------------+
++ |List                                 |list, may have mixed types  values          |
++ +-------------------------------------+--------------------------------------------+
++
++The following Go types cannot be marshaled: uintptr, function, interface, channel
++
++TODO
++
++Go types: array, slice, struct, complex64/128.
++
++AMQP types: decimal32/64/128, char, timestamp, uuid, array, multi-section message bodies.
++
++Described types.
++
++*/
++func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) {
++	defer doRecover(&err)
++	data := C.pn_data(0)
++	defer C.pn_data_free(data)
++	marshal(v, data)
++	encode := func(buf []byte) ([]byte, error) {
++		n := int(C.pn_data_encode(data, cPtr(buf), cLen(buf)))
++		switch {
++		case n == int(C.PN_OVERFLOW):
++			return buf, overflow
++		case n < 0:
++			return buf, dataError("marshal error", data)
++		default:
++			return buf[:n], nil
++		}
++	}
++	return encodeGrow(buffer, encode)
++}
++
++const minEncode = 256
++
++// overflow is returned when an encoding function can't fit data in the buffer.
++var overflow = internal.Errorf("buffer too small")
++
++// encodeFn encodes into buffer[0:len(buffer)].
++// Returns buffer with length adjusted for data encoded.
++// If buffer too small, returns overflow as error.
++type encodeFn func(buffer []byte) ([]byte, error)
++
++// encodeGrow calls encode() into buffer, if it returns overflow grows the buffer.
++// Returns the final buffer.
++func encodeGrow(buffer []byte, encode encodeFn) ([]byte, error) {
++	if buffer == nil || len(buffer) == 0 {
++		buffer = make([]byte, minEncode)
++	}
++	var err error
++	for buffer, err = encode(buffer); err == overflow; buffer, err = encode(buffer) {
++		buffer = make([]byte, 2*len(buffer))
++	}
++	return buffer, err
++}
++
++func marshal(v interface{}, data *C.pn_data_t) {
++	switch v := v.(type) {
++	case nil:
++		C.pn_data_put_null(data)
++	case bool:
++		C.pn_data_put_bool(data, C.bool(v))
++	case int8:
++		C.pn_data_put_byte(data, C.int8_t(v))
++	case int16:
++		C.pn_data_put_short(data, C.int16_t(v))
++	case int32:
++		C.pn_data_put_int(data, C.int32_t(v))
++	case int64:
++		C.pn_data_put_long(data, C.int64_t(v))
++	case int:
++		if unsafe.Sizeof(0) == 8 {
++			C.pn_data_put_long(data, C.int64_t(v))
++		} else {
++			C.pn_data_put_int(data, C.int32_t(v))
++		}
++	case uint8:
++		C.pn_data_put_ubyte(data, C.uint8_t(v))
++	case uint16:
++		C.pn_data_put_ushort(data, C.uint16_t(v))
++	case uint32:
++		C.pn_data_put_uint(data, C.uint32_t(v))
++	case uint64:
++		C.pn_data_put_ulong(data, C.uint64_t(v))
++	case uint:
++		if unsafe.Sizeof(0) == 8 {
++			C.pn_data_put_ulong(data, C.uint64_t(v))
++		} else {
++			C.pn_data_put_uint(data, C.uint32_t(v))
++		}
++	case float32:
++		C.pn_data_put_float(data, C.float(v))
++	case float64:
++		C.pn_data_put_double(data, C.double(v))
++	case string:
++		C.pn_data_put_string(data, pnBytes([]byte(v)))
++	case []byte:
++		C.pn_data_put_binary(data, pnBytes(v))
++	case Binary:
++		C.pn_data_put_binary(data, pnBytes([]byte(v)))
++	case Symbol:
++		C.pn_data_put_symbol(data, pnBytes([]byte(v)))
++	case Map: // Special map type
++		C.pn_data_put_map(data)
++		C.pn_data_enter(data)
++		for key, val := range v {
++			marshal(key, data)
++			marshal(val, data)
++		}
++		C.pn_data_exit(data)
++	default:
++		switch reflect.TypeOf(v).Kind() {
++		case reflect.Map:
++			putMap(data, v)
++		case reflect.Slice:
++			putList(data, v)
++		default:
++			panic(internal.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
++		}
++	}
++	err := dataError("marshal", data)
++	if err != nil {
++		panic(err)
++	}
++	return
++}
++
++func clearMarshal(v interface{}, data *C.pn_data_t) {
++	C.pn_data_clear(data)
++	marshal(v, data)
++}
++
++func putMap(data *C.pn_data_t, v interface{}) {
++	mapValue := reflect.ValueOf(v)
++	C.pn_data_put_map(data)
++	C.pn_data_enter(data)
++	for _, key := range mapValue.MapKeys() {
++		marshal(key.Interface(), data)
++		marshal(mapValue.MapIndex(key).Interface(), data)
++	}
++	C.pn_data_exit(data)
++}
++
++func putList(data *C.pn_data_t, v interface{}) {
++	listValue := reflect.ValueOf(v)
++	C.pn_data_put_list(data)
++	C.pn_data_enter(data)
++	for i := 0; i < listValue.Len(); i++ {
++		marshal(listValue.Index(i).Interface(), data)
++	}
++	C.pn_data_exit(data)
++}
++
++// Encoder encodes AMQP values to an io.Writer
++type Encoder struct {
++	writer io.Writer
++	buffer []byte
++}
++
++// New encoder returns a new encoder that writes to w.
++func NewEncoder(w io.Writer) *Encoder {
++	return &Encoder{w, make([]byte, minEncode)}
++}
++
++func (e *Encoder) Encode(v interface{}) (err error) {
++	e.buffer, err = Marshal(v, e.buffer)
++	if err == nil {
++		e.writer.Write(e.buffer)
++	}
++	return err
++}
++
++func replace(data *C.pn_data_t, v interface{}) {
++	C.pn_data_clear(data)
++	marshal(v, data)
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/message.go
----------------------------------------------------------------------
diff --cc amqp/message.go
index 0000000,0000000..5ba4f4f
new file mode 100644
--- /dev/null
+++ b/amqp/message.go
@@@ -1,0 -1,0 +1,347 @@@
++/*
++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
++
++// #include <proton/types.h>
++// #include <proton/message.h>
++// #include <proton/codec.h>
++// #include <stdlib.h>
++//
++// /* Helper for setting message string fields */
++// typedef int (*set_fn)(pn_message_t*, const char*);
++// int msg_set_str(pn_message_t* m, char* s, set_fn set) {
++//     int result = set(m, s);
++//     free(s);
++//     return result;
++// }
++//
++import "C"
++
++import (
++	"qpid.apache.org/internal"
++	"runtime"
++	"time"
++	"unsafe"
++)
++
++// Message is the interface to an AMQP message.
++type Message interface {
++	// Durable indicates that any parties taking responsibility
++	// for the message must durably store the content.
++	Durable() bool
++	SetDurable(bool)
++
++	// Priority impacts ordering guarantees. Within a
++	// given ordered context, higher priority messages may jump ahead of
++	// lower priority messages.
++	Priority() uint8
++	SetPriority(uint8)
++
++	// TTL or Time To Live, a message it may be dropped after this duration
++	TTL() time.Duration
++	SetTTL(time.Duration)
++
++	// FirstAcquirer indicates
++	// that the recipient of the message is the first recipient to acquire
++	// the message, i.e. there have been no failed delivery attempts to
++	// other acquirers. Note that this does not mean the message has not
++	// been delivered to, but not acquired, by other recipients.
++	FirstAcquirer() bool
++	SetFirstAcquirer(bool)
++
++	// DeliveryCount tracks how many attempts have been made to
++	// delivery a message.
++	DeliveryCount() uint32
++	SetDeliveryCount(uint32)
++
++	// MessageId provides a unique identifier for a message.
++	// it can be an a string, an unsigned long, a uuid or a
++	// binary value.
++	MessageId() interface{}
++	SetMessageId(interface{})
++
++	UserId() string
++	SetUserId(string)
++
++	Address() string
++	SetAddress(string)
++
++	Subject() string
++	SetSubject(string)
++
++	ReplyTo() string
++	SetReplyTo(string)
++
++	// CorrelationId is set on correlated request and response messages. It can be
++	// an a string, an unsigned long, a uuid or a binary value.
++	CorrelationId() interface{}
++	SetCorrelationId(interface{})
++
++	ContentType() string
++	SetContentType(string)
++
++	ContentEncoding() string
++	SetContentEncoding(string)
++
++	// ExpiryTime indicates an absoulte time when the message may be dropped.
++	// A Zero time (i.e. t.isZero() == true) indicates a message never expires.
++	ExpiryTime() time.Time
++	SetExpiryTime(time.Time)
++
++	CreationTime() time.Time
++	SetCreationTime(time.Time)
++
++	GroupId() string
++	SetGroupId(string)
++
++	GroupSequence() int32
++	SetGroupSequence(int32)
++
++	ReplyToGroupId() string
++	SetReplyToGroupId(string)
++
++	// Instructions - AMQP delivery instructions.
++	Instructions() map[string]interface{}
++	SetInstructions(v map[string]interface{})
++
++	// Annotations - AMQP annotations.
++	Annotations() map[string]interface{}
++	SetAnnotations(v map[string]interface{})
++
++	// Properties - Application properties.
++	Properties() map[string]interface{}
++	SetProperties(v map[string]interface{})
++
++	// Inferred indicates how the message content
++	// is encoded into AMQP sections. If inferred is true then binary and
++	// list values in the body of the message will be encoded as AMQP DATA
++	// and AMQP SEQUENCE sections, respectively. If inferred is false,
++	// then all values in the body of the message will be encoded as AMQP
++	// VALUE sections regardless of their type.
++	Inferred() bool
++	SetInferred(bool)
++
++	// Marshal a Go value into the message body. See amqp.Marshal() for details.
++	Marshal(interface{})
++
++	// Unmarshal the message body into the value pointed to by v. See amqp.Unmarshal() for details.
++	Unmarshal(interface{})
++
++	// Body value resulting from the default unmarshalling of message body as interface{}
++	Body() interface{}
++
++	// Encode encodes the message as AMQP data. If buffer is non-nil and is large enough
++	// the message is encoded into it, otherwise a new buffer is created.
++	// Returns the buffer containing the message.
++	Encode(buffer []byte) ([]byte, error)
++
++	// Decode data into this message. Overwrites an existing message content.
++	Decode(buffer []byte) error
++
++	// Clear the message contents.
++	Clear()
++
++	// Copy the contents of another message to this one.
++	Copy(m Message) error
++}
++
++type message struct{ pn *C.pn_message_t }
++
++func freeMessage(m *message) {
++	C.pn_message_free(m.pn)
++	m.pn = nil
++}
++
++// NewMessage creates a new message instance.
++func NewMessage() Message {
++	m := &message{C.pn_message()}
++	runtime.SetFinalizer(m, freeMessage)
++	return m
++}
++
++// NewMessageWith creates a message with value as the body. Equivalent to
++//     m := NewMessage(); m.Marshal(body)
++func NewMessageWith(value interface{}) Message {
++	m := NewMessage()
++	m.Marshal(value)
++	return m
++}
++
++func (m *message) Clear() { C.pn_message_clear(m.pn) }
++
++func (m *message) Copy(x Message) error {
++	if data, err := x.Encode(nil); err == nil {
++		return m.Decode(data)
++	} else {
++		return err
++	}
++}
++
++// ==== message get functions
++
++func rewindGet(data *C.pn_data_t) (v interface{}) {
++	C.pn_data_rewind(data)
++	C.pn_data_next(data)
++	unmarshal(&v, data)
++	return v
++}
++
++func rewindMap(data *C.pn_data_t) (v map[string]interface{}) {
++	C.pn_data_rewind(data)
++	C.pn_data_next(data)
++	unmarshal(&v, data)
++	return v
++}
++
++func (m *message) Inferred() bool  { return bool(C.pn_message_is_inferred(m.pn)) }
++func (m *message) Durable() bool   { return bool(C.pn_message_is_durable(m.pn)) }
++func (m *message) Priority() uint8 { return uint8(C.pn_message_get_priority(m.pn)) }
++func (m *message) TTL() time.Duration {
++	return time.Duration(C.pn_message_get_ttl(m.pn)) * time.Millisecond
++}
++func (m *message) FirstAcquirer() bool        { return bool(C.pn_message_is_first_acquirer(m.pn)) }
++func (m *message) DeliveryCount() uint32      { return uint32(C.pn_message_get_delivery_count(m.pn)) }
++func (m *message) MessageId() interface{}     { return rewindGet(C.pn_message_id(m.pn)) }
++func (m *message) UserId() string             { return goString(C.pn_message_get_user_id(m.pn)) }
++func (m *message) Address() string            { return C.GoString(C.pn_message_get_address(m.pn)) }
++func (m *message) Subject() string            { return C.GoString(C.pn_message_get_subject(m.pn)) }
++func (m *message) ReplyTo() string            { return C.GoString(C.pn_message_get_reply_to(m.pn)) }
++func (m *message) CorrelationId() interface{} { return rewindGet(C.pn_message_correlation_id(m.pn)) }
++func (m *message) ContentType() string        { return C.GoString(C.pn_message_get_content_type(m.pn)) }
++func (m *message) ContentEncoding() string    { return C.GoString(C.pn_message_get_content_encoding(m.pn)) }
++
++func (m *message) ExpiryTime() time.Time {
++	return time.Unix(0, int64(time.Millisecond*time.Duration(C.pn_message_get_expiry_time(m.pn))))
++}
++func (m *message) CreationTime() time.Time {
++	return time.Unix(0, int64(time.Millisecond)*int64(C.pn_message_get_creation_time(m.pn)))
++}
++func (m *message) GroupId() string        { return C.GoString(C.pn_message_get_group_id(m.pn)) }
++func (m *message) GroupSequence() int32   { return int32(C.pn_message_get_group_sequence(m.pn)) }
++func (m *message) ReplyToGroupId() string { return C.GoString(C.pn_message_get_reply_to_group_id(m.pn)) }
++
++func (m *message) Instructions() map[string]interface{} {
++	return rewindMap(C.pn_message_instructions(m.pn))
++}
++func (m *message) Annotations() map[string]interface{} {
++	return rewindMap(C.pn_message_annotations(m.pn))
++}
++func (m *message) Properties() map[string]interface{} {
++	return rewindMap(C.pn_message_properties(m.pn))
++}
++
++// ==== message set methods
++
++func setData(v interface{}, data *C.pn_data_t) {
++	C.pn_data_clear(data)
++	marshal(v, data)
++}
++
++func dataString(data *C.pn_data_t) string {
++	str := C.pn_string(C.CString(""))
++	defer C.pn_free(unsafe.Pointer(str))
++	C.pn_inspect(unsafe.Pointer(data), str)
++	return C.GoString(C.pn_string_get(str))
++}
++
++func (m *message) SetInferred(b bool)  { C.pn_message_set_inferred(m.pn, C.bool(m.Inferred())) }
++func (m *message) SetDurable(b bool)   { C.pn_message_set_durable(m.pn, C.bool(b)) }
++func (m *message) SetPriority(b uint8) { C.pn_message_set_priority(m.pn, C.uint8_t(b)) }
++func (m *message) SetTTL(d time.Duration) {
++	C.pn_message_set_ttl(m.pn, C.pn_millis_t(d/time.Millisecond))
++}
++func (m *message) SetFirstAcquirer(b bool)     { C.pn_message_set_first_acquirer(m.pn, C.bool(b)) }
++func (m *message) SetDeliveryCount(c uint32)   { C.pn_message_set_delivery_count(m.pn, C.uint32_t(c)) }
++func (m *message) SetMessageId(id interface{}) { setData(id, C.pn_message_id(m.pn)) }
++func (m *message) SetUserId(s string)          { C.pn_message_set_user_id(m.pn, pnBytes(([]byte)(s))) }
++func (m *message) SetAddress(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_address))
++}
++func (m *message) SetSubject(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_subject))
++}
++func (m *message) SetReplyTo(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to))
++}
++func (m *message) SetCorrelationId(c interface{}) { setData(c, C.pn_message_correlation_id(m.pn)) }
++func (m *message) SetContentType(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_type))
++}
++func (m *message) SetContentEncoding(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_content_encoding))
++}
++func (m *message) SetExpiryTime(t time.Time)   { C.pn_message_set_expiry_time(m.pn, pnTime(t)) }
++func (m *message) SetCreationTime(t time.Time) { C.pn_message_set_creation_time(m.pn, pnTime(t)) }
++func (m *message) SetGroupId(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_group_id))
++}
++func (m *message) SetGroupSequence(s int32) {
++	C.pn_message_set_group_sequence(m.pn, C.pn_sequence_t(s))
++}
++func (m *message) SetReplyToGroupId(s string) {
++	C.msg_set_str(m.pn, C.CString(s), C.set_fn(C.pn_message_set_reply_to_group_id))
++}
++
++func (m *message) SetInstructions(v map[string]interface{}) {
++	setData(v, C.pn_message_instructions(m.pn))
++}
++func (m *message) SetAnnotations(v map[string]interface{}) { setData(v, C.pn_message_annotations(m.pn)) }
++func (m *message) SetProperties(v map[string]interface{})  { setData(v, C.pn_message_properties(m.pn)) }
++
++// Marshal/Unmarshal body
++func (m *message) Marshal(v interface{})   { clearMarshal(v, C.pn_message_body(m.pn)) }
++func (m *message) Unmarshal(v interface{}) { rewindUnmarshal(v, C.pn_message_body(m.pn)) }
++func (m *message) Body() (v interface{})   { m.Unmarshal(&v); return }
++
++func (m *message) Decode(data []byte) error {
++	m.Clear()
++	if len(data) == 0 {
++		return internal.Errorf("empty buffer for decode")
++	}
++	if C.pn_message_decode(m.pn, cPtr(data), cLen(data)) < 0 {
++		return internal.Errorf("decoding message: %s",
++			internal.PnError(unsafe.Pointer(C.pn_message_error(m.pn))))
++	}
++	return nil
++}
++
++func DecodeMessage(data []byte) (m Message, err error) {
++	m = NewMessage()
++	err = m.Decode(data)
++	return
++}
++
++func (m *message) Encode(buffer []byte) ([]byte, error) {
++	encode := func(buf []byte) ([]byte, error) {
++		len := cLen(buf)
++		result := C.pn_message_encode(m.pn, cPtr(buf), &len)
++		switch {
++		case result == C.PN_OVERFLOW:
++			return buf, overflow
++		case result < 0:
++			return buf, internal.Errorf("cannot encode message: %s", internal.PnErrorCode(result))
++		default:
++			return buf[:len], nil
++		}
++	}
++	return encodeGrow(buffer, encode)
++}
++
++// TODO aconway 2015-09-14: Multi-section messages.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/message_test.go
----------------------------------------------------------------------
diff --cc amqp/message_test.go
index 0000000,0000000..7a6e5a8
new file mode 100644
--- /dev/null
+++ b/amqp/message_test.go
@@@ -1,0 -1,0 +1,166 @@@
++/*
++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
++
++import (
++	"testing"
++	"time"
++)
++
++func roundTrip(m Message) error {
++	buffer, err := m.Encode(nil)
++	if err != nil {
++		return err
++	}
++	m2, err := DecodeMessage(buffer)
++	if err != nil {
++		return err
++	}
++	return checkEqual(m, m2)
++}
++
++func TestDefaultMessage(t *testing.T) {
++	m := NewMessage()
++	// Check defaults
++	for _, data := range [][]interface{}{
++		{m.Inferred(), false},
++		{m.Durable(), false},
++		{m.Priority(), uint8(4)},
++		{m.TTL(), time.Duration(0)},
++		{m.UserId(), ""},
++		{m.Address(), ""},
++		{m.Subject(), ""},
++		{m.ReplyTo(), ""},
++		{m.ContentType(), ""},
++		{m.ContentEncoding(), ""},
++		{m.GroupId(), ""},
++		{m.GroupSequence(), int32(0)},
++		{m.ReplyToGroupId(), ""},
++		{m.MessageId(), nil},
++		{m.CorrelationId(), nil},
++		{m.Instructions(), map[string]interface{}{}},
++		{m.Annotations(), map[string]interface{}{}},
++		{m.Properties(), map[string]interface{}{}},
++		{m.Body(), nil},
++	} {
++		if err := checkEqual(data[0], data[1]); err != nil {
++			t.Error(err)
++		}
++	}
++	if err := roundTrip(m); err != nil {
++		t.Error(err)
++	}
++}
++
++func TestMessageRoundTrip(t *testing.T) {
++	m := NewMessage()
++	m.SetInferred(false)
++	m.SetDurable(true)
++	m.SetPriority(42)
++	m.SetTTL(0)
++	m.SetUserId("user")
++	m.SetAddress("address")
++	m.SetSubject("subject")
++	m.SetReplyTo("replyto")
++	m.SetContentType("content")
++	m.SetContentEncoding("encoding")
++	m.SetGroupId("group")
++	m.SetGroupSequence(42)
++	m.SetReplyToGroupId("replytogroup")
++	m.SetMessageId("id")
++	m.SetCorrelationId("correlation")
++	m.SetInstructions(map[string]interface{}{"instructions": "foo"})
++	m.SetAnnotations(map[string]interface{}{"annotations": "foo"})
++	m.SetProperties(map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"})
++	m.Marshal("hello")
++
++	for _, data := range [][]interface{}{
++		{m.Inferred(), false},
++		{m.Durable(), true},
++		{m.Priority(), uint8(42)},
++		{m.TTL(), time.Duration(0)},
++		{m.UserId(), "user"},
++		{m.Address(), "address"},
++		{m.Subject(), "subject"},
++		{m.ReplyTo(), "replyto"},
++		{m.ContentType(), "content"},
++		{m.ContentEncoding(), "encoding"},
++		{m.GroupId(), "group"},
++		{m.GroupSequence(), int32(42)},
++		{m.ReplyToGroupId(), "replytogroup"},
++		{m.MessageId(), "id"},
++		{m.CorrelationId(), "correlation"},
++		{m.Instructions(), map[string]interface{}{"instructions": "foo"}},
++		{m.Annotations(), map[string]interface{}{"annotations": "foo"}},
++		{m.Properties(), map[string]interface{}{"int": int32(32), "bool": true, "string": "foo"}},
++		{m.Body(), "hello"},
++	} {
++		if err := checkEqual(data[0], data[1]); err != nil {
++			t.Error(err)
++		}
++	}
++	if err := roundTrip(m); err != nil {
++		t.Error(err)
++	}
++}
++
++func TestMessageBodyTypes(t *testing.T) {
++	var s string
++	var body interface{}
++	var i int64
++
++	m := NewMessageWith(int64(42))
++	m.Unmarshal(&body)
++	m.Unmarshal(&i)
++	if err := checkEqual(body.(int64), int64(42)); err != nil {
++		t.Error(err)
++	}
++	if err := checkEqual(i, int64(42)); err != nil {
++		t.Error(err)
++	}
++
++	m = NewMessageWith("hello")
++	m.Unmarshal(&s)
++	m.Unmarshal(&body)
++	if err := checkEqual(s, "hello"); err != nil {
++		t.Error(err)
++	}
++	if err := checkEqual(body.(string), "hello"); err != nil {
++		t.Error(err)
++	}
++	if err := roundTrip(m); err != nil {
++		t.Error(err)
++	}
++
++	m = NewMessageWith(Binary("bin"))
++	m.Unmarshal(&s)
++	m.Unmarshal(&body)
++	if err := checkEqual(body.(Binary), Binary("bin")); err != nil {
++		t.Error(err)
++	}
++	if err := checkEqual(s, "bin"); err != nil {
++		t.Error(err)
++	}
++	if err := roundTrip(m); err != nil {
++		t.Error(err)
++	}
++
++	// TODO aconway 2015-09-08: array etc.
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/types.go
----------------------------------------------------------------------
diff --cc amqp/types.go
index 0000000,0000000..796da66
new file mode 100644
--- /dev/null
+++ b/amqp/types.go
@@@ -1,0 -1,0 +1,199 @@@
++/*
++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
++
++// #include <proton/codec.h>
++import "C"
++
++import (
++	"bytes"
++	"fmt"
++	"reflect"
++	"time"
++	"unsafe"
++)
++
++type Type C.pn_type_t
++
++func (t Type) String() string {
++	switch C.pn_type_t(t) {
++	case C.PN_NULL:
++		return "null"
++	case C.PN_BOOL:
++		return "bool"
++	case C.PN_UBYTE:
++		return "ubyte"
++	case C.PN_BYTE:
++		return "byte"
++	case C.PN_USHORT:
++		return "ushort"
++	case C.PN_SHORT:
++		return "short"
++	case C.PN_CHAR:
++		return "char"
++	case C.PN_UINT:
++		return "uint"
++	case C.PN_INT:
++		return "int"
++	case C.PN_ULONG:
++		return "ulong"
++	case C.PN_LONG:
++		return "long"
++	case C.PN_TIMESTAMP:
++		return "timestamp"
++	case C.PN_FLOAT:
++		return "float"
++	case C.PN_DOUBLE:
++		return "double"
++	case C.PN_DECIMAL32:
++		return "decimal32"
++	case C.PN_DECIMAL64:
++		return "decimal64"
++	case C.PN_DECIMAL128:
++		return "decimal128"
++	case C.PN_UUID:
++		return "uuid"
++	case C.PN_BINARY:
++		return "binary"
++	case C.PN_STRING:
++		return "string"
++	case C.PN_SYMBOL:
++		return "symbol"
++	case C.PN_DESCRIBED:
++		return "described"
++	case C.PN_ARRAY:
++		return "array"
++	case C.PN_LIST:
++		return "list"
++	case C.PN_MAP:
++		return "map"
++	default:
++		if uint32(t) == uint32(C.PN_INVALID) {
++			return "no-data"
++		}
++		return fmt.Sprintf("unknown-type(%d)", t)
++	}
++}
++
++// Go types
++var (
++	bytesType = reflect.TypeOf([]byte{})
++	valueType = reflect.TypeOf(reflect.Value{})
++)
++
++// TODO aconway 2015-04-08: can't handle AMQP maps with key types that are not valid Go map keys.
++
++// Map is a generic map that can have mixed key and value types and so can represent any AMQP map
++type Map map[interface{}]interface{}
++
++// List is a generic list that can hold mixed values and can represent any AMQP list.
++//
++type List []interface{}
++
++// Symbol is a string that is encoded as an AMQP symbol
++type Symbol string
++
++func (s Symbol) GoString() string { return fmt.Sprintf("s\"%s\"", s) }
++
++// Binary is a string that is encoded as an AMQP binary.
++// It is a string rather than a byte[] because byte[] is not hashable and can't be used as
++// a map key, AMQP frequently uses binary types as map keys. It can convert to and from []byte
++type Binary string
++
++func (b Binary) GoString() string { return fmt.Sprintf("b\"%s\"", b) }
++
++// GoString for Map prints values with their types, useful for debugging.
++func (m Map) GoString() string {
++	out := &bytes.Buffer{}
++	fmt.Fprintf(out, "%T{", m)
++	i := len(m)
++	for k, v := range m {
++		fmt.Fprintf(out, "%T(%#v): %T(%#v)", k, k, v, v)
++		i--
++		if i > 0 {
++			fmt.Fprint(out, ", ")
++		}
++	}
++	fmt.Fprint(out, "}")
++	return out.String()
++}
++
++// GoString for List prints values with their types, useful for debugging.
++func (l List) GoString() string {
++	out := &bytes.Buffer{}
++	fmt.Fprintf(out, "%T{", l)
++	for i := 0; i < len(l); i++ {
++		fmt.Fprintf(out, "%T(%#v)", l[i], l[i])
++		if i == len(l)-1 {
++			fmt.Fprint(out, ", ")
++		}
++	}
++	fmt.Fprint(out, "}")
++	return out.String()
++}
++
++// pnTime converts Go time.Time to Proton millisecond Unix time.
++func pnTime(t time.Time) C.pn_timestamp_t {
++	secs := t.Unix()
++	// Note: sub-second accuracy is not guaraunteed if the Unix time in
++	// nanoseconds cannot be represented by an int64 (sometime around year 2260)
++	msecs := (t.UnixNano() % int64(time.Second)) / int64(time.Millisecond)
++	return C.pn_timestamp_t(secs*1000 + msecs)
++}
++
++// goTime converts a pn_timestamp_t to a Go time.Time.
++func goTime(t C.pn_timestamp_t) time.Time {
++	secs := int64(t) / 1000
++	nsecs := (int64(t) % 1000) * int64(time.Millisecond)
++	return time.Unix(secs, nsecs)
++}
++
++func goBytes(cBytes C.pn_bytes_t) (bytes []byte) {
++	if cBytes.start != nil {
++		bytes = C.GoBytes(unsafe.Pointer(cBytes.start), C.int(cBytes.size))
++	}
++	return
++}
++
++func goString(cBytes C.pn_bytes_t) (str string) {
++	if cBytes.start != nil {
++		str = C.GoStringN(cBytes.start, C.int(cBytes.size))
++	}
++	return
++}
++
++func pnBytes(b []byte) C.pn_bytes_t {
++	if len(b) == 0 {
++		return C.pn_bytes_t{0, nil}
++	} else {
++		return C.pn_bytes_t{C.size_t(len(b)), (*C.char)(unsafe.Pointer(&b[0]))}
++	}
++}
++
++func cPtr(b []byte) *C.char {
++	if len(b) == 0 {
++		return nil
++	}
++	return (*C.char)(unsafe.Pointer(&b[0]))
++}
++
++func cLen(b []byte) C.size_t {
++	return C.size_t(len(b))
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/unmarshal.go
----------------------------------------------------------------------
diff --cc amqp/unmarshal.go
index 0000000,0000000..751921d
new file mode 100644
--- /dev/null
+++ b/amqp/unmarshal.go
@@@ -1,0 -1,0 +1,558 @@@
++/*
++Licensed to the Apache Software Foundation (ASF) under one
++oor 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
++
++// #include <proton/codec.h>
++import "C"
++
++import (
++	"bytes"
++	"fmt"
++	"io"
++	"qpid.apache.org/internal"
++	"reflect"
++	"unsafe"
++)
++
++const minDecode = 1024
++
++// Error returned if AMQP data cannot be unmarshaled as the desired Go type.
++type UnmarshalError struct {
++	// The name of the AMQP type.
++	AMQPType string
++	// The Go type.
++	GoType reflect.Type
++}
++
++func newUnmarshalError(pnType C.pn_type_t, v interface{}) *UnmarshalError {
++	return &UnmarshalError{Type(pnType).String(), reflect.TypeOf(v)}
++}
++
++func (e UnmarshalError) Error() string {
++	if e.GoType.Kind() != reflect.Ptr {
++		return fmt.Sprintf("proton: cannot unmarshal to type %s, not a pointer", e.GoType)
++	} else {
++		return fmt.Sprintf("proton: cannot unmarshal AMQP %s to %s", e.AMQPType, e.GoType)
++	}
++}
++
++func doRecover(err *error) {
++	r := recover()
++	switch r := r.(type) {
++	case nil:
++	case *UnmarshalError, internal.Error:
++		*err = r.(error)
++	default:
++		panic(r)
++	}
++}
++
++//
++// Decoding from a pn_data_t
++//
++// NOTE: we use panic() to signal a decoding error, simplifies decoding logic.
++// We recover() at the highest possible level - i.e. in the exported Unmarshal or Decode.
++//
++
++// Decoder decodes AMQP values from an io.Reader.
++//
++type Decoder struct {
++	reader io.Reader
++	buffer bytes.Buffer
++}
++
++// NewDecoder returns a new decoder that reads from r.
++//
++// The decoder has it's own buffer and may read more data than required for the
++// AMQP values requested.  Use Buffered to see if there is data left in the
++// buffer.
++//
++func NewDecoder(r io.Reader) *Decoder {
++	return &Decoder{r, bytes.Buffer{}}
++}
++
++// Buffered returns a reader of the data remaining in the Decoder's buffer. The
++// reader is valid until the next call to Decode.
++//
++func (d *Decoder) Buffered() io.Reader {
++	return bytes.NewReader(d.buffer.Bytes())
++}
++
++// Decode reads the next AMQP value from the Reader and stores it in the value pointed to by v.
++//
++// See the documentation for Unmarshal for details about the conversion of AMQP into a Go value.
++//
++func (d *Decoder) Decode(v interface{}) (err error) {
++	defer doRecover(&err)
++	data := C.pn_data(0)
++	defer C.pn_data_free(data)
++	var n int
++	for n == 0 && err == nil {
++		n = decode(data, d.buffer.Bytes())
++		if n == 0 { // n == 0 means not enough data, read more
++			err = d.more()
++		} else {
++			unmarshal(v, data)
++		}
++	}
++	d.buffer.Next(n)
++	return
++}
++
++/*
++Unmarshal decodes AMQP-encoded bytes and stores the result in the value pointed to by v.
++Types are converted as follows:
++
++ +---------------------------+----------------------------------------------------------------------+
++ |To Go types                |From AMQP types                                                       |
++ +===========================+======================================================================+
++ |bool                       |bool                                                                  |
++ +---------------------------+----------------------------------------------------------------------+
++ |int, int8, int16,          |Equivalent or smaller signed integer type: byte, short, int, long.    |
++ |int32, int64               |                                                                      |
++ +---------------------------+----------------------------------------------------------------------+
++ |uint, uint8, uint16,       |Equivalent or smaller unsigned integer type: ubyte, ushort, uint,     |
++ |uint32, uint64 types       |ulong                                                                 |
++ +---------------------------+----------------------------------------------------------------------+
++ |float32, float64           |Equivalent or smaller float or double.                                |
++ +---------------------------+----------------------------------------------------------------------+
++ |string, []byte             |string, symbol or binary.                                             |
++ +---------------------------+----------------------------------------------------------------------+
++ |Symbol                     |symbol                                                                |
++ +---------------------------+----------------------------------------------------------------------+
++ |map[K]T                    |map, provided all keys and values can unmarshal to types K, T         |
++ +---------------------------+----------------------------------------------------------------------+
++ |Map                        |map, any AMQP map                                                     |
++ +---------------------------+----------------------------------------------------------------------+
++ |interface{}                |Any AMQP value can be unmarshaled to an interface{} as follows:       |
++ |                           +------------------------+---------------------------------------------+
++ |                           |AMQP Type               |Go Type in interface{}                       |
++ |                           +========================+=============================================+
++ |                           |bool                    |bool                                         |
++ |                           +------------------------+---------------------------------------------+
++ |                           |byte,short,int,long     |int8,int16,int32,int64                       |
++ |                           +------------------------+---------------------------------------------+
++ |                           |ubyte,ushort,uint,ulong |uint8,uint16,uint32,uint64                   |
++ |                           +------------------------+---------------------------------------------+
++ |                           |float, double           |float32, float64                             |
++ |                           +------------------------+---------------------------------------------+
++ |                           |string                  |string                                       |
++ |                           +------------------------+---------------------------------------------+
++ |                           |symbol                  |Symbol                                       |
++ |                           +------------------------+---------------------------------------------+
++ |                           |binary                  |Binary                                       |
++ |                           +------------------------+---------------------------------------------+
++ |                           |nulll                   |nil                                          |
++ |                           +------------------------+---------------------------------------------+
++ |                           |map                     |Map                                          |
++ |                           +------------------------+---------------------------------------------+
++ |                           |list                    |List                                         |
++ +---------------------------+------------------------+---------------------------------------------+
++
++The following Go types cannot be unmarshaled: uintptr, function, interface, channel.
++
++TODO
++
++Go types: array, struct.
++
++AMQP types: decimal32/64/128, char (round trip), timestamp, uuid, array, multi-section message bodies.
++
++AMQP maps with mixed/unhashable key types need an alternate representation.
++
++Described types.
++*/
++func Unmarshal(bytes []byte, v interface{}) (n int, err error) {
++	defer doRecover(&err)
++
++	data := C.pn_data(0)
++	defer C.pn_data_free(data)
++	n = decode(data, bytes)
++	if n == 0 {
++		err = internal.Errorf("not enough data")
++	} else {
++		unmarshal(v, data)
++	}
++	return
++}
++
++// more reads more data when we can't parse a complete AMQP type
++func (d *Decoder) more() error {
++	var readSize int64 = minDecode
++	if int64(d.buffer.Len()) > readSize { // Grow by doubling
++		readSize = int64(d.buffer.Len())
++	}
++	var n int64
++	n, err := d.buffer.ReadFrom(io.LimitReader(d.reader, readSize))
++	if n == 0 && err == nil { // ReadFrom won't report io.EOF, just returns 0
++		err = io.EOF
++	}
++	return err
++}
++
++// Unmarshal from data into value pointed at by v.
++func unmarshal(v interface{}, data *C.pn_data_t) {
++	pnType := C.pn_data_type(data)
++	switch v := v.(type) {
++	case *bool:
++		switch pnType {
++		case C.PN_BOOL:
++			*v = bool(C.pn_data_get_bool(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *int8:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = int8(C.pn_data_get_char(data))
++		case C.PN_BYTE:
++			*v = int8(C.pn_data_get_byte(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *uint8:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = uint8(C.pn_data_get_char(data))
++		case C.PN_UBYTE:
++			*v = uint8(C.pn_data_get_ubyte(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *int16:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = int16(C.pn_data_get_char(data))
++		case C.PN_BYTE:
++			*v = int16(C.pn_data_get_byte(data))
++		case C.PN_SHORT:
++			*v = int16(C.pn_data_get_short(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *uint16:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = uint16(C.pn_data_get_char(data))
++		case C.PN_UBYTE:
++			*v = uint16(C.pn_data_get_ubyte(data))
++		case C.PN_USHORT:
++			*v = uint16(C.pn_data_get_ushort(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *int32:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = int32(C.pn_data_get_char(data))
++		case C.PN_BYTE:
++			*v = int32(C.pn_data_get_byte(data))
++		case C.PN_SHORT:
++			*v = int32(C.pn_data_get_short(data))
++		case C.PN_INT:
++			*v = int32(C.pn_data_get_int(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	case *uint32:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = uint32(C.pn_data_get_char(data))
++		case C.PN_UBYTE:
++			*v = uint32(C.pn_data_get_ubyte(data))
++		case C.PN_USHORT:
++			*v = uint32(C.pn_data_get_ushort(data))
++		case C.PN_UINT:
++			*v = uint32(C.pn_data_get_uint(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *int64:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = int64(C.pn_data_get_char(data))
++		case C.PN_BYTE:
++			*v = int64(C.pn_data_get_byte(data))
++		case C.PN_SHORT:
++			*v = int64(C.pn_data_get_short(data))
++		case C.PN_INT:
++			*v = int64(C.pn_data_get_int(data))
++		case C.PN_LONG:
++			*v = int64(C.pn_data_get_long(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *uint64:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = uint64(C.pn_data_get_char(data))
++		case C.PN_UBYTE:
++			*v = uint64(C.pn_data_get_ubyte(data))
++		case C.PN_USHORT:
++			*v = uint64(C.pn_data_get_ushort(data))
++		case C.PN_ULONG:
++			*v = uint64(C.pn_data_get_ulong(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *int:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = int(C.pn_data_get_char(data))
++		case C.PN_BYTE:
++			*v = int(C.pn_data_get_byte(data))
++		case C.PN_SHORT:
++			*v = int(C.pn_data_get_short(data))
++		case C.PN_INT:
++			*v = int(C.pn_data_get_int(data))
++		case C.PN_LONG:
++			if unsafe.Sizeof(0) == 8 {
++				*v = int(C.pn_data_get_long(data))
++			} else {
++				panic(newUnmarshalError(pnType, v))
++			}
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *uint:
++		switch pnType {
++		case C.PN_CHAR:
++			*v = uint(C.pn_data_get_char(data))
++		case C.PN_UBYTE:
++			*v = uint(C.pn_data_get_ubyte(data))
++		case C.PN_USHORT:
++			*v = uint(C.pn_data_get_ushort(data))
++		case C.PN_UINT:
++			*v = uint(C.pn_data_get_uint(data))
++		case C.PN_ULONG:
++			if unsafe.Sizeof(0) == 8 {
++				*v = uint(C.pn_data_get_ulong(data))
++			} else {
++				panic(newUnmarshalError(pnType, v))
++			}
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *float32:
++		switch pnType {
++		case C.PN_FLOAT:
++			*v = float32(C.pn_data_get_float(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *float64:
++		switch pnType {
++		case C.PN_FLOAT:
++			*v = float64(C.pn_data_get_float(data))
++		case C.PN_DOUBLE:
++			*v = float64(C.pn_data_get_double(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *string:
++		switch pnType {
++		case C.PN_STRING:
++			*v = goString(C.pn_data_get_string(data))
++		case C.PN_SYMBOL:
++			*v = goString(C.pn_data_get_symbol(data))
++		case C.PN_BINARY:
++			*v = goString(C.pn_data_get_binary(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *[]byte:
++		switch pnType {
++		case C.PN_STRING:
++			*v = goBytes(C.pn_data_get_string(data))
++		case C.PN_SYMBOL:
++			*v = goBytes(C.pn_data_get_symbol(data))
++		case C.PN_BINARY:
++			*v = goBytes(C.pn_data_get_binary(data))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *Binary:
++		switch pnType {
++		case C.PN_BINARY:
++			*v = Binary(goBytes(C.pn_data_get_binary(data)))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *Symbol:
++		switch pnType {
++		case C.PN_SYMBOL:
++			*v = Symbol(goBytes(C.pn_data_get_symbol(data)))
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++
++	case *interface{}:
++		getInterface(data, v)
++
++	default:
++		if reflect.TypeOf(v).Kind() != reflect.Ptr {
++			panic(newUnmarshalError(pnType, v))
++		}
++		switch reflect.TypeOf(v).Elem().Kind() {
++		case reflect.Map:
++			getMap(data, v)
++		case reflect.Slice:
++			getList(data, v)
++		default:
++			panic(newUnmarshalError(pnType, v))
++		}
++	}
++	err := dataError("unmarshaling", data)
++	if err != nil {
++		panic(err)
++	}
++	return
++}
++
++func rewindUnmarshal(v interface{}, data *C.pn_data_t) {
++	C.pn_data_rewind(data)
++	C.pn_data_next(data)
++	unmarshal(v, data)
++}
++
++// Getting into an interface is driven completely by the AMQP type, since the interface{}
++// target is type-neutral.
++func getInterface(data *C.pn_data_t, v *interface{}) {
++	pnType := C.pn_data_type(data)
++	switch pnType {
++	// Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t
++	case C.PN_NULL, C.pn_type_t(C.PN_INVALID): // No data.
++		*v = nil
++	case C.PN_BOOL:
++		*v = bool(C.pn_data_get_bool(data))
++	case C.PN_UBYTE:
++		*v = uint8(C.pn_data_get_ubyte(data))
++	case C.PN_BYTE:
++		*v = int8(C.pn_data_get_byte(data))
++	case C.PN_USHORT:
++		*v = uint16(C.pn_data_get_ushort(data))
++	case C.PN_SHORT:
++		*v = int16(C.pn_data_get_short(data))
++	case C.PN_UINT:
++		*v = uint32(C.pn_data_get_uint(data))
++	case C.PN_INT:
++		*v = int32(C.pn_data_get_int(data))
++	case C.PN_CHAR:
++		*v = uint8(C.pn_data_get_char(data))
++	case C.PN_ULONG:
++		*v = uint64(C.pn_data_get_ulong(data))
++	case C.PN_LONG:
++		*v = int64(C.pn_data_get_long(data))
++	case C.PN_FLOAT:
++		*v = float32(C.pn_data_get_float(data))
++	case C.PN_DOUBLE:
++		*v = float64(C.pn_data_get_double(data))
++	case C.PN_BINARY:
++		*v = Binary(goBytes(C.pn_data_get_binary(data)))
++	case C.PN_STRING:
++		*v = goString(C.pn_data_get_string(data))
++	case C.PN_SYMBOL:
++		*v = Symbol(goString(C.pn_data_get_symbol(data)))
++	case C.PN_MAP:
++		m := make(Map)
++		unmarshal(&m, data)
++		*v = m
++	case C.PN_LIST:
++		l := make(List, 0)
++		unmarshal(&l, data)
++		*v = l
++	default:
++		panic(newUnmarshalError(pnType, v))
++	}
++}
++
++// get into map pointed at by v
++func getMap(data *C.pn_data_t, v interface{}) {
++	mapValue := reflect.ValueOf(v).Elem()
++	mapValue.Set(reflect.MakeMap(mapValue.Type())) // Clear the map
++	switch pnType := C.pn_data_type(data); pnType {
++	case C.PN_MAP:
++		count := int(C.pn_data_get_map(data))
++		if bool(C.pn_data_enter(data)) {
++			defer C.pn_data_exit(data)
++			for i := 0; i < count/2; i++ {
++				if bool(C.pn_data_next(data)) {
++					key := reflect.New(mapValue.Type().Key())
++					unmarshal(key.Interface(), data)
++					if bool(C.pn_data_next(data)) {
++						val := reflect.New(mapValue.Type().Elem())
++						unmarshal(val.Interface(), data)
++						mapValue.SetMapIndex(key.Elem(), val.Elem())
++					}
++				}
++			}
++		}
++		// Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t
++	case C.pn_type_t(C.PN_INVALID): // Leave the map empty
++	default:
++		panic(newUnmarshalError(pnType, v))
++	}
++}
++
++func getList(data *C.pn_data_t, v interface{}) {
++	pnType := C.pn_data_type(data)
++	if pnType != C.PN_LIST {
++		panic(newUnmarshalError(pnType, v))
++	}
++	count := int(C.pn_data_get_list(data))
++	listValue := reflect.MakeSlice(reflect.TypeOf(v).Elem(), count, count)
++	if bool(C.pn_data_enter(data)) {
++		for i := 0; i < count; i++ {
++			if bool(C.pn_data_next(data)) {
++				val := reflect.New(listValue.Type().Elem())
++				unmarshal(val.Interface(), data)
++				listValue.Index(i).Set(val.Elem())
++			}
++		}
++		C.pn_data_exit(data)
++	}
++	reflect.ValueOf(v).Elem().Set(listValue)
++}
++
++// decode from bytes.
++// Return bytes decoded or 0 if we could not decode a complete object.
++//
++func decode(data *C.pn_data_t, bytes []byte) int {
++	if len(bytes) == 0 {
++		return 0
++	}
++	n := int(C.pn_data_decode(data, cPtr(bytes), cLen(bytes)))
++	if n == int(C.PN_UNDERFLOW) {
++		C.pn_error_clear(C.pn_data_error(data))
++		return 0
++	} else if n <= 0 {
++		panic(internal.Errorf("unmarshal %s", internal.PnErrorCode(n)))
++	}
++	return n
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/url.go
----------------------------------------------------------------------
diff --cc amqp/url.go
index 0000000,0000000..0d0c662
new file mode 100644
--- /dev/null
+++ b/amqp/url.go
@@@ -1,0 -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.
++*/
++
++package amqp
++
++/*
++#include <stdlib.h>
++#include <string.h>
++#include <proton/url.h>
++
++// Helper function for setting URL fields.
++typedef void (*setter_fn)(pn_url_t* url, const char* value);
++inline void	set(pn_url_t *url, setter_fn s, const char* value) {
++  s(url, value);
++}
++*/
++import "C"
++
++import (
++	"net"
++	"net/url"
++	"qpid.apache.org/internal"
++	"unsafe"
++)
++
++const (
++	amqp  string = "amqp"
++	amqps        = "amqps"
++)
++
++// ParseUrl parses an AMQP URL string and returns a net/url.Url.
++//
++// It is more forgiving than net/url.Parse and allows most of the parts of the
++// URL to be missing, assuming AMQP defaults.
++//
++func ParseURL(s string) (u *url.URL, err error) {
++	cstr := C.CString(s)
++	defer C.free(unsafe.Pointer(cstr))
++	pnUrl := C.pn_url_parse(cstr)
++	if pnUrl == nil {
++		return nil, internal.Errorf("bad URL %#v", s)
++	}
++	defer C.pn_url_free(pnUrl)
++
++	scheme := C.GoString(C.pn_url_get_scheme(pnUrl))
++	username := C.GoString(C.pn_url_get_username(pnUrl))
++	password := C.GoString(C.pn_url_get_password(pnUrl))
++	host := C.GoString(C.pn_url_get_host(pnUrl))
++	port := C.GoString(C.pn_url_get_port(pnUrl))
++	path := C.GoString(C.pn_url_get_path(pnUrl))
++
++	if err != nil {
++		return nil, internal.Errorf("bad URL %#v: %s", s, err)
++	}
++	if scheme == "" {
++		scheme = amqp
++	}
++	if port == "" {
++		if scheme == amqps {
++			port = amqps
++		} else {
++			port = amqp
++		}
++	}
++	var user *url.Userinfo
++	if password != "" {
++		user = url.UserPassword(username, password)
++	} else if username != "" {
++		user = url.User(username)
++	}
++
++	u = &url.URL{
++		Scheme: scheme,
++		User:   user,
++		Host:   net.JoinHostPort(host, port),
++		Path:   path,
++	}
++
++	return u, nil
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/amqp/url_test.go
----------------------------------------------------------------------
diff --cc amqp/url_test.go
index 0000000,0000000..f80f1c4
new file mode 100644
--- /dev/null
+++ b/amqp/url_test.go
@@@ -1,0 -1,0 +1,51 @@@
++/*
++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
++
++import (
++	"fmt"
++)
++
++func ExampleParseURL() {
++	for _, s := range []string{
++		"amqp://username:password@host:1234/path",
++		"host:1234",
++		"host",
++		":1234",
++		"host/path",
++		"amqps://host",
++		"",
++	} {
++		u, err := ParseURL(s)
++		if err != nil {
++			fmt.Println(err)
++		} else {
++			fmt.Println(u)
++		}
++	}
++	// Output:
++	// amqp://username:password@host:1234/path
++	// amqp://host:1234
++	// amqp://host:amqp
++	// amqp://:1234
++	// amqp://host:amqp/path
++	// amqps://host:amqps
++	// proton: bad URL ""
++}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8dc93cd0/electron/connection.go
----------------------------------------------------------------------
diff --cc electron/connection.go
index 0000000,0000000..d6761d6
new file mode 100644
--- /dev/null
+++ b/electron/connection.go
@@@ -1,0 -1,0 +1,218 @@@
++/*
++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
++
++// #include <proton/disposition.h>
++import "C"
++
++import (
++	"net"
++	"qpid.apache.org/amqp"
++	"qpid.apache.org/internal"
++	"qpid.apache.org/proton"
++	"sync"
++	"time"
++)
++
++// Connection is an AMQP connection, created by a Container.
++type Connection interface {
++	Endpoint
++
++	// Sender opens a new sender on the DefaultSession.
++	//
++	// v can be a string, which is used as the Target address, or a SenderSettings
++	// struct containing more details settings.
++	Sender(...LinkSetting) (Sender, error)
++
++	// Receiver opens a new Receiver on the DefaultSession().
++	//
++	// v can be a string, which is used as the
++	// Source address, or a ReceiverSettings struct containing more details
++	// settings.
++	Receiver(...LinkSetting) (Receiver, error)
++
++	// DefaultSession() returns a default session for the connection. It is opened
++	// on the first call to DefaultSession and returned on subsequent calls.
++	DefaultSession() (Session, error)
++
++	// Session opens a new session.
++	Session(...SessionSetting) (Session, error)
++
++	// Container for the connection.
++	Container() Container
++
++	// Disconnect the connection abruptly with an error.
++	Disconnect(error)
++
++	// Wait waits for the connection to be disconnected.
++	Wait() error
++
++	// WaitTimeout is like Wait but returns Timeout if the timeout expires.
++	WaitTimeout(time.Duration) error
++}
++
++// ConnectionSetting can be passed when creating a connection.
++// See functions that return ConnectionSetting for details
++type ConnectionSetting func(*connection)
++
++// Server setting puts the connection in server mode.
++//
++// A server connection will do protocol negotiation to accept a incoming AMQP
++// connection. Normally you would call this for a connection created by
++// net.Listener.Accept()
++//
++func Server() ConnectionSetting { return func(c *connection) { c.engine.Server() } }
++
++// Accepter provides a function to be called when a connection receives an incoming
++// request to open an endpoint, one of IncomingSession, IncomingSender or IncomingReceiver.
++//
++// The accept() function must not block or use the accepted endpoint.
++// It can pass the endpoint to another goroutine for processing.
++//
++// By default all incoming endpoints are rejected.
++func Accepter(accept func(Incoming)) ConnectionSetting {
++	return func(c *connection) { c.accept = accept }
++}
++
++type connection struct {
++	endpoint
++	listenOnce, defaultSessionOnce, closeOnce sync.Once
++
++	container   *container
++	conn        net.Conn
++	accept      func(Incoming)
++	handler     *handler
++	engine      *proton.Engine
++	err         internal.ErrorHolder
++	eConnection proton.Connection
++
++	defaultSession Session
++	done           chan struct{}
++}
++
++func newConnection(conn net.Conn, cont *container, setting ...ConnectionSetting) (*connection, error) {
++	c := &connection{container: cont, conn: conn, accept: func(Incoming) {}, done: make(chan struct{})}
++	c.handler = newHandler(c)
++	var err error
++	c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
++	if err != nil {
++		return nil, err
++	}
++	for _, set := range setting {
++		set(c)
++	}
++	c.str = c.engine.String()
++	c.eConnection = c.engine.Connection()
++	go func() { c.engine.Run(); close(c.done) }()
++	return c, nil
++}
++
++func (c *connection) Close(err error) { c.err.Set(err); c.engine.Close(err) }
++
++func (c *connection) Disconnect(err error) { c.err.Set(err); c.engine.Disconnect(err) }
++
++func (c *connection) Session(setting ...SessionSetting) (Session, error) {
++	var s Session
++	err := c.engine.InjectWait(func() error {
++		eSession, err := c.engine.Connection().Session()
++		if err == nil {
++			eSession.Open()
++			if err == nil {
++				s = newSession(c, eSession, setting...)
++			}
++		}
++		return err
++	})
++	return s, err
++}
++
++func (c *connection) Container() Container { return c.container }
++
++func (c *connection) DefaultSession() (s Session, err error) {
++	c.defaultSessionOnce.Do(func() {
++		c.defaultSession, err = c.Session()
++	})
++	if err == nil {
++		err = c.Error()
++	}
++	return c.defaultSession, err
++}
++
++func (c *connection) Sender(setting ...LinkSetting) (Sender, error) {
++	if s, err := c.DefaultSession(); err == nil {
++		return s.Sender(setting...)
++	} else {
++		return nil, err
++	}
++}
++
++func (c *connection) Receiver(setting ...LinkSetting) (Receiver, error) {
++	if s, err := c.DefaultSession(); err == nil {
++		return s.Receiver(setting...)
++	} else {
++		return nil, err
++	}
++}
++
++func (c *connection) Connection() Connection { return c }
++
++func (c *connection) Wait() error { return c.WaitTimeout(Forever) }
++func (c *connection) WaitTimeout(timeout time.Duration) error {
++	_, err := timedReceive(c.done, timeout)
++	if err == Timeout {
++		return Timeout
++	}
++	return c.Error()
++}
++
++// Incoming is the interface for incoming requests to open an endpoint.
++// Implementing types are IncomingSession, IncomingSender and IncomingReceiver.
++type Incoming interface {
++	// Accept the endpoint with default settings.
++	//
++	// You must not use the returned endpoint in the accept() function that
++	// receives the Incoming value, but you can pass it to other goroutines.
++	//
++	// Implementing types provide type-specific Accept functions that take additional settings.
++	Accept() Endpoint
++
++	// Reject the endpoint with an error
++	Reject(error)
++
++	error() error
++}
++
++type incoming struct {
++	err      error
++	accepted bool
++}
++
++func (i *incoming) Reject(err error) { i.err = err }
++
++func (i *incoming) error() error {
++	switch {
++	case i.err != nil:
++		return i.err
++	case !i.accepted:
++		return amqp.Errorf(amqp.NotAllowed, "remote open rejected")
++	default:
++		return nil
++	}
++}


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


[41/50] [abbrv] qpid-proton git commit: PROTON-1030: workaround that resets reactors handlers after stopping to allow it to be freed

Posted by ac...@apache.org.
PROTON-1030: workaround that resets reactors handlers after stopping to allow it to be freed


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

Branch: refs/heads/go1
Commit: bbba61afef7c2c67cd6be6a0393dd5233d0d473c
Parents: c799a29
Author: Gordon Sim <gs...@redhat.com>
Authored: Wed Oct 21 20:31:30 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Wed Oct 21 20:31:46 2015 +0100

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bbba61af/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 b8e4b6a..8eaee5c 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -159,6 +159,8 @@ class Reactor(Wrapper):
     def stop(self):
         pn_reactor_stop(self._impl)
         self._check_errors()
+        self.global_handler = None
+        self.handler = None
 
     def schedule(self, delay, task):
         impl = _chandler(task, self.on_error)


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


[31/50] [abbrv] qpid-proton git commit: NO-JIRA: c++: rename sync_request_response to request_response

Posted by ac...@apache.org.
NO-JIRA: c++: rename sync_request_response to request_response


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

Branch: refs/heads/go1
Commit: abea588a4da7be36820974f0ebedf3ac6d634f46
Parents: ea52a27
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 2 17:10:39 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 19 12:45:24 2015 -0400

----------------------------------------------------------------------
 examples/cpp/example_test.py                    |  2 +-
 examples/cpp/sync_client.cpp                    |  4 +-
 proton-c/bindings/cpp/CMakeLists.txt            |  2 +-
 proton-c/bindings/cpp/docs/tutorial.hpp         |  2 +-
 .../cpp/include/proton/blocking_connection.hpp  |  2 +-
 .../cpp/include/proton/request_response.hpp     | 63 ++++++++++++++++++++
 .../include/proton/sync_request_response.hpp    | 63 --------------------
 proton-c/bindings/cpp/src/request_response.cpp  | 57 ++++++++++++++++++
 .../bindings/cpp/src/sync_request_response.cpp  | 57 ------------------
 9 files changed, 126 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index cc27a1f..bb40265 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -178,7 +178,7 @@ class ExampleTest(unittest.TestCase):
         finally:
             server.kill()
 
-    def test_sync_request_response(self):
+    def test_request_response(self):
         b = Broker.get()
         server = background("server", "-a", b.addr)
         try:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/examples/cpp/sync_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/sync_client.cpp b/examples/cpp/sync_client.cpp
index 39bdabf..9493579 100644
--- a/examples/cpp/sync_client.cpp
+++ b/examples/cpp/sync_client.cpp
@@ -23,7 +23,7 @@
 
 #include "proton/container.hpp"
 #include "proton/blocking_connection.hpp"
-#include "proton/sync_request_response.hpp"
+#include "proton/request_response.hpp"
 #include "proton/url.hpp"
 #include "proton/types.hpp"
 
@@ -50,7 +50,7 @@ int main(int argc, char **argv) {
         opts.parse();
 
         proton::blocking_connection conn(url, proton::duration(timeout));
-        proton::sync_request_response client(conn, url.path());
+        proton::request_response client(conn, url.path());
         for (std::vector<std::string>::const_iterator i=requests.begin(); i != requests.end(); i++) {
             proton::message request;
             request.body(*i);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 45e47b2..9f423fb 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -59,7 +59,7 @@ set(qpid-proton-cpp-source
   src/receiver.cpp
   src/sender.cpp
   src/session.cpp
-  src/sync_request_response.cpp
+  src/request_response.cpp
   src/task.cpp
   src/terminus.cpp
   src/transport.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/docs/tutorial.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/tutorial.hpp b/proton-c/bindings/cpp/docs/tutorial.hpp
index cae3745..bc5b758 100644
--- a/proton-c/bindings/cpp/docs/tutorial.hpp
+++ b/proton-c/bindings/cpp/docs/tutorial.hpp
@@ -396,7 +396,7 @@ server or mixed client-server programs. However for simple client-only programs
 a synchronous or blocking style of programming is sometimes simpler.
 
 `proton::blocking_connection` allows a blocking style of programming,
-`proton::sync_request_response` automates the common case of synchronous
+`proton::request_response` automates the common case of synchronous
 request/response, send a request and block for the response.
 
 \ref sync_client.cpp is our request/response client in blocking style. Here's the key section

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
index d6db1e2..f7787cb 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -54,7 +54,7 @@ class blocking_connection
   friend class blocking_link;
   friend class blocking_sender;
   friend class blocking_receiver;
-  friend class sync_request_response;
+  friend class request_response;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/include/proton/request_response.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/request_response.hpp b/proton-c/bindings/cpp/include/proton/request_response.hpp
new file mode 100644
index 0000000..9bc4392
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/request_response.hpp
@@ -0,0 +1,63 @@
+#ifndef PROTON_CPP_SYNC_REQUEST_RESPONSE_H
+#define PROTON_CPP_SYNC_REQUEST_RESPONSE_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/blocking_receiver.hpp"
+#include "proton/blocking_sender.hpp"
+#include "proton/export.hpp"
+#include "proton/messaging_handler.hpp"
+#include "proton/pn_unique_ptr.hpp"
+
+#include <string>
+
+struct pn_message_t;
+struct pn_data_t;
+
+namespace proton {
+
+/**
+ * An implementation of the synchronous request-response pattern (aka RPC).
+ */
+class request_response
+{
+  public:
+    PN_CPP_EXTERN request_response(
+        blocking_connection &, const std::string address=std::string());
+    /**
+     * Send a request message, wait for and return the response message.
+     * Modifies the message to set `address` (if not already set), `reply_to` and `correlation_id`.
+     */
+    PN_CPP_EXTERN message call(message &request);
+    /** Return the dynamic address of our receiver. */
+    PN_CPP_EXTERN std::string reply_to();
+
+  private:
+    blocking_connection &connection_;
+    std::string address_;
+    pn_unique_ptr<blocking_sender> sender_;
+    pn_unique_ptr<blocking_receiver> receiver_;
+    amqp_ulong correlation_id_;
+};
+
+}
+
+#endif  /*!PROTON_CPP_SYNC_REQUEST_RESPONSE_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/include/proton/sync_request_response.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sync_request_response.hpp b/proton-c/bindings/cpp/include/proton/sync_request_response.hpp
deleted file mode 100644
index d5bfb59..0000000
--- a/proton-c/bindings/cpp/include/proton/sync_request_response.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef PROTON_CPP_SYNC_REQUEST_RESPONSE_H
-#define PROTON_CPP_SYNC_REQUEST_RESPONSE_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/blocking_receiver.hpp"
-#include "proton/blocking_sender.hpp"
-#include "proton/export.hpp"
-#include "proton/messaging_handler.hpp"
-#include "proton/pn_unique_ptr.hpp"
-
-#include <string>
-
-struct pn_message_t;
-struct pn_data_t;
-
-namespace proton {
-
-/**
- * An implementation of the synchronous request-response pattern (aka RPC).
- */
-class sync_request_response
-{
-  public:
-    PN_CPP_EXTERN sync_request_response(
-        blocking_connection &, const std::string address=std::string());
-    /**
-     * Send a request message, wait for and return the response message.
-     * Modifies the message to set `address` (if not already set), `reply_to` and `correlation_id`.
-     */
-    PN_CPP_EXTERN message call(message &request);
-    /** Return the dynamic address of our receiver. */
-    PN_CPP_EXTERN std::string reply_to();
-
-  private:
-    blocking_connection &connection_;
-    std::string address_;
-    pn_unique_ptr<blocking_sender> sender_;
-    pn_unique_ptr<blocking_receiver> receiver_;
-    amqp_ulong correlation_id_;
-};
-
-}
-
-#endif  /*!PROTON_CPP_SYNC_REQUEST_RESPONSE_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/src/request_response.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/request_response.cpp b/proton-c/bindings/cpp/src/request_response.cpp
new file mode 100644
index 0000000..9b8207c
--- /dev/null
+++ b/proton-c/bindings/cpp/src/request_response.cpp
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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/blocking_connection.hpp"
+#include "proton/request_response.hpp"
+#include "proton/event.hpp"
+#include "proton/error.hpp"
+#include "proton/value.hpp"
+#include "blocking_connection_impl.hpp"
+#include "msg.hpp"
+
+namespace proton {
+
+request_response::request_response(blocking_connection &conn, const std::string addr):
+    connection_(conn), address_(addr),
+    sender_(new blocking_sender(connection_, addr)),
+    receiver_(new blocking_receiver(connection_, "", 1/*credit*/, true/*dynamic*/)),
+    correlation_id_(0)
+{}
+
+message request_response::call(message &request) {
+    if (address_.empty() && request.address().empty())
+        throw error(MSG("Request message has no address"));
+    // TODO: atomic increment.
+    value cid(++correlation_id_);
+    request.correlation_id(cid);
+    request.reply_to(this->reply_to());
+    sender_->send(request);
+    message response;
+    while (response.correlation_id() != cid) {
+        response = receiver_->receive();
+    }
+    return response;
+}
+
+std::string request_response::reply_to() {
+    return receiver_->receiver().remote_source().address();
+}
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/abea588a/proton-c/bindings/cpp/src/sync_request_response.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/sync_request_response.cpp b/proton-c/bindings/cpp/src/sync_request_response.cpp
deleted file mode 100644
index 69249c7..0000000
--- a/proton-c/bindings/cpp/src/sync_request_response.cpp
+++ /dev/null
@@ -1,57 +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/blocking_connection.hpp"
-#include "proton/sync_request_response.hpp"
-#include "proton/event.hpp"
-#include "proton/error.hpp"
-#include "proton/value.hpp"
-#include "blocking_connection_impl.hpp"
-#include "msg.hpp"
-
-namespace proton {
-
-sync_request_response::sync_request_response(blocking_connection &conn, const std::string addr):
-    connection_(conn), address_(addr),
-    sender_(new blocking_sender(connection_, addr)),
-    receiver_(new blocking_receiver(connection_, "", 1/*credit*/, true/*dynamic*/)),
-    correlation_id_(0)
-{}
-
-message sync_request_response::call(message &request) {
-    if (address_.empty() && request.address().empty())
-        throw error(MSG("Request message has no address"));
-    // TODO: atomic increment.
-    value cid(++correlation_id_);
-    request.correlation_id(cid);
-    request.reply_to(this->reply_to());
-    sender_->send(request);
-    message response;
-    while (response.correlation_id() != cid) {
-        response = receiver_->receive();
-    }
-    return response;
-}
-
-std::string sync_request_response::reply_to() {
-    return receiver_->receiver().remote_source().address();
-}
-
-}


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


[43/50] [abbrv] qpid-proton git commit: NO-JIRA: c++: Finish fixing compile error on older c++ compilers (noticed on gcc 4.7)

Posted by ac...@apache.org.
NO-JIRA: c++: Finish fixing compile error on older c++ compilers (noticed on gcc 4.7)


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

Branch: refs/heads/go1
Commit: 60aafbc349ac95e5aa9752e983194966ca7fe526
Parents: bbba61a
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Oct 21 16:02:55 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Oct 21 16:03:04 2015 -0400

----------------------------------------------------------------------
 .../bindings/cpp/include/proton/endpoint.hpp    | 39 ++++++++++----------
 proton-c/bindings/cpp/src/endpoint.cpp          |  8 ++--
 2 files changed, 24 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/60aafbc3/proton-c/bindings/cpp/include/proton/endpoint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp
index 5ed2646..d1cccb5 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -64,7 +64,7 @@ class endpoint
 };
 
 ///@cond INTERNAL
-template <class T, class D> class iter_base {
+template <class T> class iter_base {
   public:
     typedef T value_type;
 
@@ -72,17 +72,17 @@ template <class T, class D> class iter_base {
     T* operator->() const { return ptr_; }
     operator bool() const { return ptr_; }
     bool operator !() const { return !ptr_; }
-    iter_base<T, D>& operator++() { static_cast<D*>(this)->advance(); return *this; }
-    iter_base<T, D>& operator++(int) { iter_base<T, D> x(*this); ++(*this); return x; }
-    bool operator==(const iter_base<T, D>& x) const { return ptr_ == x.ptr_; }
-    bool operator!=(const iter_base<T, D>& x) const { return ptr_ != x.ptr_; }
+    bool operator==(const iter_base<T>& x) const { return ptr_ == x.ptr_; }
+    bool operator!=(const iter_base<T>& x) const { return ptr_ != x.ptr_; }
 
   protected:
     explicit iter_base(T* p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
     T* ptr_;
     endpoint::state state_;
 };
+///@endcond INTERNAL
 
+/// An iterator range.
 template<class I> class range {
   public:
     typedef I iterator;
@@ -93,35 +93,34 @@ template<class I> class range {
   private:
     I begin_, end_;
 };
-///@endcond INTERNAL
 
-///@ An iterator for a range of sessions.
-class session_iterator : public iter_base<session, session_iterator> {
+/// An iterator for sessions.
+class session_iterator : public iter_base<session> {
  public:
     explicit session_iterator(session* p = 0, endpoint::state s = 0) :
-        iter_base<session, session_iterator>(p, s) {}
-  private:
-    PN_CPP_EXTERN void advance();
-  friend class iter_base<session, session_iterator>;
+        iter_base<session>(p, s) {}
+    PN_CPP_EXTERN session_iterator operator++();
+    session_iterator operator++(int) { session_iterator x(*this); ++(*this); return x; }
 };
 
-///@ A range of sessions.
+/// A range of sessions.
 typedef range<session_iterator> session_range;
 
-///@ An iterator for a range of links.
-class link_iterator : public iter_base<link, link_iterator> {
+/// An iterator for links.
+class link_iterator : public iter_base<link> {
   public:
     explicit link_iterator(link* p = 0, endpoint::state s = 0) :
-        iter_base(p, s), session_(0) {}
+        iter_base<link>(p, s), session_(0) {}
     explicit link_iterator(const link_iterator& i, const session *ssn) :
-        iter_base(i.ptr_, i.state_), session_(ssn) {}
+        iter_base<link>(i.ptr_, i.state_), session_(ssn) {}
+    PN_CPP_EXTERN link_iterator operator++();
+    link_iterator operator++(int) { link_iterator x(*this); ++(*this); return x; }
+
   private:
-    PN_CPP_EXTERN void advance();
     const session* session_;
-  friend class iter_base<link, link_iterator>;
 };
 
-///@ A range of links.
+/// A range of links.
 typedef range<link_iterator> link_range;
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/60aafbc3/proton-c/bindings/cpp/src/endpoint.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/endpoint.cpp b/proton-c/bindings/cpp/src/endpoint.cpp
index 7f65054..34ea7c7 100644
--- a/proton-c/bindings/cpp/src/endpoint.cpp
+++ b/proton-c/bindings/cpp/src/endpoint.cpp
@@ -40,14 +40,16 @@ const int endpoint::REMOTE_CLOSED = PN_REMOTE_CLOSED;
 const int endpoint::LOCAL_MASK = PN_LOCAL_MASK;
 const int endpoint::REMOTE_MASK = PN_REMOTE_MASK;
 
-void session_iterator::advance() {
+session_iterator session_iterator::operator++() {
     ptr_ = session::cast(pn_session_next(pn_cast(ptr_), (pn_state_t) state_));
+    return *this;
 }
 
-void link_iterator::advance() {
+link_iterator link_iterator::operator++() {
     do {
         ptr_ = link::cast(pn_link_next(pn_cast(ptr_), (pn_state_t) state_));
-    } while (session_ && &ptr_->session() != session_);
+    } while (ptr_ && session_ && &ptr_->session() != session_);
+    return *this;
 }
 
 }


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


[19/50] [abbrv] qpid-proton git commit: PROTON-1015: Documentation improvement from Otavio Rodolfo Piske.

Posted by ac...@apache.org.
PROTON-1015: Documentation improvement from Otavio Rodolfo Piske.


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

Branch: refs/heads/go1
Commit: bd698eebad0dc169b4946f8eb4cadf9d6ad4a19b
Parents: 617cf65
Author: Chuck Rolke <cr...@redhat.com>
Authored: Fri Oct 9 16:58:14 2015 -0400
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Fri Oct 9 16:58:14 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/docs/tutorial.hpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bd698eeb/proton-c/bindings/cpp/docs/tutorial.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/tutorial.hpp b/proton-c/bindings/cpp/docs/tutorial.hpp
index 56f3e9f..cae3745 100644
--- a/proton-c/bindings/cpp/docs/tutorial.hpp
+++ b/proton-c/bindings/cpp/docs/tutorial.hpp
@@ -93,7 +93,7 @@ Hello World, Direct!
 \dontinclude helloworld_direct.cpp
 
 Though often used in conjunction with a broker, AMQP does not *require* this. It
-also allows senders and receivers can communicate directly if desired.
+also allows senders and receivers to communicate directly if desired.
 
 We will modify our example to send a message directly to itself. This is a bit
 contrived but illustrates both sides of the direct send/receive scenario. Full
@@ -101,7 +101,7 @@ code at \ref helloworld_direct.cpp
 
 The first difference, is that rather than creating a receiver on the same
 connection as our sender, we listen for incoming connections by invoking the
-`proton::container::Xblisten()` method on the container.
+`proton::container::listen()` method on the container.
 
 \skip on_start
 \until }
@@ -137,7 +137,7 @@ event loop exits, and the run() method will return.
 
 So now we have our example working without a broker involved!
 
-Note that for this example we paick an "unusual" port 8888 since we are talking
+Note that for this example we pick an "unusual" port 8888 since we are talking
 to ourselves rather than a broker.
 
 \skipline url =
@@ -216,8 +216,8 @@ got to.
 
 Now let's look at the corresponding receiver \ref simple_recv.cpp
 
-This time we'll use an `expected` member variable for for the number of messages we expecct and
-a `received` variable to count how many we have received so far.send.
+This time we'll use an `expected` member variable for for the number of messages we expect and
+a `received` variable to count how many we have received so far.
 
 \skip class simple_recv
 \until received
@@ -363,7 +363,7 @@ to our original server:
 
 \dontinclude server_direct.cpp
 
-Our server must generate a unique reply-to addreses for links from the
+Our server must generate a unique reply-to addresses for links from the
 client that request a dynamic address (previously this was done by the broker.)
 We use a simple counter.
 
@@ -418,7 +418,7 @@ of the headers. The following example shows how that can be achieved:
 When creating the receiver, we specify a Selector object as an option.
 The options argument can take a single object or a list. Another option
 that is sometimes of interest when using a broker is the ability to
-'browse' the messages on a queue, rather than consumig them. This is
+'browse' the messages on a queue, rather than consuming them. This is
 done in AMQP by specifying a distribution mode of 'copy' (instead of
 'move' which is the expected default for queues). An example of that is
 shown next:


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


[24/50] [abbrv] qpid-proton git commit: NO-JIRA: Fix Go example tests to run without GOPATH set.

Posted by ac...@apache.org.
NO-JIRA: Fix Go example tests to run without GOPATH set.


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

Branch: refs/heads/go1
Commit: 63cd40f4ff2269dff69f8831524a0c8e3582e93f
Parents: 43eb7f0
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 12 16:43:24 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 13 10:59:42 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt          |  4 ++--
 examples/go/example_test.go         |  1 +
 proton-c/bindings/go/CMakeLists.txt | 10 ++++++----
 3 files changed, 9 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/63cd40f4/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 76487fd..67c6cd7 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -32,12 +32,12 @@ if(BUILD_GO)
 
   add_test(
     NAME go_example_electron_test
-    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
+    COMMAND ${GO_ENV} ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
 
 
   add_test(
     NAME go_example_proton_test
-    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
+    COMMAND ${GO_ENV} ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/63cd40f4/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
index 1e497b9..479864c 100644
--- a/examples/go/example_test.go
+++ b/examples/go/example_test.go
@@ -113,6 +113,7 @@ func checkStaleLibs(t *testing.T) {
 	var stale []string
 	pp := "qpid.apache.org"
 	for _, p := range []string{pp + "/proton", pp + "/amqp", pp + "/electron"} {
+		t.Log("FIXME", os.Getenv("GOPATH"))
 		out, err := exec.Command("go", "list", "-f", "{{.Stale}}", p).CombinedOutput()
 		if err != nil {
 			t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/63cd40f4/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 11a3b78..27d2349 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -41,11 +41,13 @@ set(GO_ENV ${env_py} --
   "GOPATH=${CMAKE_CURRENT_SOURCE_DIR}"
   "CGO_CFLAGS=-I${CMAKE_SOURCE_DIR}/proton-c/include"
   "CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/proton-c"
-  ${GO_EXE} CACHE INTERNAL "Run go with environment set")
+  CACHE INTERNAL "Run a command with Go environment variables")
 
-set(GO_BUILD ${GO_ENV} build ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} CACHE INTERNAL "Run go build")
-set(GO_INSTALL ${GO_ENV} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
-set(GO_TEST ${GO_ENV} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
+set(GO ${GO_ENV} ${GO_EXE} CACHE INTERNAL "Run go with environment set")
+
+set(GO_BUILD ${GO} build ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} CACHE INTERNAL "Run go build")
+set(GO_INSTALL ${GO} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
+set(GO_TEST ${GO} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
 
 # Install packages in the source tree, go tools aren't friendly otherwise.
 # All build output goes in git-ignored pkg or bin subdirectories.


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


[03/50] [abbrv] qpid-proton git commit: NO-JIRA: Make the C++ examples have self contained build.

Posted by ac...@apache.org.
NO-JIRA: Make the C++ examples have self contained build.


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

Branch: refs/heads/go1
Commit: fe0817e2a98183dc298d757692667b12f36a8dda
Parents: 43c5cff
Author: Andrew Stitcher <as...@apache.org>
Authored: Wed Sep 30 14:30:16 2015 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Wed Sep 30 14:30:16 2015 -0400

----------------------------------------------------------------------
 examples/CMakeLists.txt                         |  2 +
 examples/ProtonCppConfig.cmake                  | 23 ++++++
 examples/cpp/CMakeLists.txt                     |  8 +--
 proton-c/CMakeLists.txt                         | 10 +--
 proton-c/bindings/cpp/CMakeLists.txt            | 73 ++++++++++++++------
 proton-c/bindings/cpp/ProtonCppConfig.cmake.in  | 30 ++++++++
 .../cpp/ProtonCppConfigVersion.cmake.in         | 30 ++++++++
 proton-c/bindings/cpp/libqpid-proton-cpp.pc.in  | 30 ++++++++
 8 files changed, 173 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c4c4058..99e8315 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -18,6 +18,8 @@
 #
 
 set (Proton_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set (ProtonCpp_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
 add_subdirectory(c)
 add_subdirectory(go)
 if (BUILD_CPP)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/examples/ProtonCppConfig.cmake
----------------------------------------------------------------------
diff --git a/examples/ProtonCppConfig.cmake b/examples/ProtonCppConfig.cmake
new file mode 100644
index 0000000..d3a7813
--- /dev/null
+++ b/examples/ProtonCppConfig.cmake
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+set (ProtonCpp_VERSION       ${PN_VERSION})
+set (ProtonCpp_INCLUDE_DIRS  ${CMAKE_SOURCE_DIR}/proton-c/include ${CMAKE_SOURCE_DIR}/proton-c/bindings/cpp/include)
+set (ProtonCpp_LIBRARIES     qpid-proton-cpp)
+set (ProtonCpp_FOUND True)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 1ac1b1e..34edb83 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -17,11 +17,9 @@
 # under the License.
 #
 
-include(${CMAKE_SOURCE_DIR}/cpp.cmake) # Compiler checks
+find_package(ProtonCpp REQUIRED)
 
-include_directories(
-  "${CMAKE_SOURCE_DIR}/proton-c/include"
-  "${CMAKE_SOURCE_DIR}/proton-c/bindings/cpp/include")
+include_directories(${ProtonCpp_INCLUDE_DIRS})
 
 foreach(example
     broker
@@ -39,7 +37,7 @@ foreach(example
     recurring_timer
     encode_decode)
   add_executable(${example} ${example}.cpp)
-  target_link_libraries(${example} qpid-proton-cpp)
+  target_link_libraries(${example} ${ProtonCpp_LIBRARIES})
   set_source_files_properties(${example}.cpp PROPERTIES COMPILE_FLAGS "${CXX_WARNING_FLAGS}")
 endforeach()
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 0d9cf85..6a35170 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -269,6 +269,11 @@ macro (pn_absolute_install_dir NAME VALUE PREFIX)
   get_filename_component(${NAME} ${${NAME}} ABSOLUTE)
 endmacro()
 
+pn_absolute_install_dir(PREFIX "." ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(EXEC_PREFIX "." ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(LIBDIR ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
+
 add_subdirectory(bindings)
 add_subdirectory(docs/api)
 add_subdirectory(docs/man)
@@ -457,11 +462,6 @@ install (FILES ${headers} DESTINATION ${INCLUDE_INSTALL_DIR}/proton)
 install (FILES  ${CMAKE_CURRENT_BINARY_DIR}/include/proton/version.h
          DESTINATION ${INCLUDE_INSTALL_DIR}/proton)
 
-pn_absolute_install_dir(PREFIX "." ${CMAKE_INSTALL_PREFIX})
-pn_absolute_install_dir(EXEC_PREFIX "." ${CMAKE_INSTALL_PREFIX})
-pn_absolute_install_dir(LIBDIR ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
-pn_absolute_install_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
-
 # Pkg config file
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/src/libqpid-proton.pc.in

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 868bbb9..45e47b2 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -88,27 +88,6 @@ set_target_properties (
   LINK_FLAGS "${CATCH_UNDEFINED}"
   )
 
-## Test
-if (ENABLE_VALGRIND AND VALGRIND_EXE)
-  set(memcheck-cmd ${VALGRIND_EXE} --error-exitcode=1 --quiet --leak-check=full --trace-children=yes)
-endif ()
-
-macro(add_cpp_test test)
-  add_executable (${test} src/${test}.cpp)
-  target_link_libraries (${test} qpid-proton qpid-proton-cpp)
-  if (CMAKE_SYSTEM_NAME STREQUAL Windows)
-    add_test (NAME cpp_${test}
-      COMMAND ${env_py}
-      "PATH=$<TARGET_FILE_DIR:qpid-proton>"
-      $<TARGET_FILE:${test}> ${ARGN})
-  else ()
-    add_test (NAME cpp_${test} COMMAND ${memcheck-cmd} ${CMAKE_CURRENT_BINARY_DIR}/${test} ${ARGN})
-  endif ()
-endmacro(add_cpp_test)
-
-add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
-add_cpp_test(conversion_test ${CMAKE_SOURCE_DIR}/tests)
-
 ## Install
 
 install(TARGETS qpid-proton-cpp
@@ -129,8 +108,56 @@ if (MSVC)
 endif (MSVC)
 
 # Install header files
-file(GLOB headers "include/proton/cpp/*.h")
-install (FILES ${headers} DESTINATION ${INCLUDE_INSTALL_DIR}/proton/cpp)
+file(GLOB headers "include/proton/*.hpp")
+install (FILES ${headers} DESTINATION ${INCLUDE_INSTALL_DIR}/proton)
 
 add_subdirectory(docs)
 add_subdirectory(${CMAKE_SOURCE_DIR}/tests/tools/apps/cpp ${CMAKE_BINARY_DIR}/tests/tools/apps/cpp)
+
+# Pkg config file
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/libqpid-proton-cpp.pc.in
+  ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton-cpp.pc @ONLY)
+install (FILES 
+  ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton-cpp.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+if (DEFINED CMAKE_IMPORT_LIBRARY_PREFIX)
+set(PROTONCPPLIB ${CMAKE_IMPORT_LIBRARY_PREFIX}qpid-proton-cpp${CMAKE_IMPORT_LIBRARY_SUFFIX})
+set(PROTONCPPLIBDEBUG ${CMAKE_IMPORT_LIBRARY_PREFIX}qpid-proton-cpp${CMAKE_DEBUG_POSTFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX})
+else ()
+set(PROTONCPPLIB ${CMAKE_SHARED_LIBRARY_PREFIX}qpid-proton-cpp${CMAKE_SHARED_LIBRARY_SUFFIX})
+set(PROTONCPPLIBDEBUG ${CMAKE_SHARED_LIBRARY_PREFIX}qpid-proton-cpp${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
+endif ()
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/ProtonCppConfig.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonCppConfig.cmake @ONLY)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/ProtonCppConfigVersion.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonCppConfigVersion.cmake @ONLY)
+install (FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonCppConfig.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonCppConfigVersion.cmake
+  DESTINATION ${LIB_INSTALL_DIR}/cmake/ProtonCpp)
+
+## Test
+if (ENABLE_VALGRIND AND VALGRIND_EXE)
+  set(memcheck-cmd ${VALGRIND_EXE} --error-exitcode=1 --quiet --leak-check=full --trace-children=yes)
+endif ()
+
+macro(add_cpp_test test)
+  add_executable (${test} src/${test}.cpp)
+  target_link_libraries (${test} qpid-proton qpid-proton-cpp)
+  if (CMAKE_SYSTEM_NAME STREQUAL Windows)
+    add_test (NAME cpp_${test}
+      COMMAND ${env_py}
+      "PATH=$<TARGET_FILE_DIR:qpid-proton>"
+      $<TARGET_FILE:${test}> ${ARGN})
+  else ()
+    add_test (NAME cpp_${test} COMMAND ${memcheck-cmd} ${CMAKE_CURRENT_BINARY_DIR}/${test} ${ARGN})
+  endif ()
+endmacro(add_cpp_test)
+
+add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
+add_cpp_test(conversion_test ${CMAKE_SOURCE_DIR}/tests)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/proton-c/bindings/cpp/ProtonCppConfig.cmake.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/ProtonCppConfig.cmake.in b/proton-c/bindings/cpp/ProtonCppConfig.cmake.in
new file mode 100644
index 0000000..0068067
--- /dev/null
+++ b/proton-c/bindings/cpp/ProtonCppConfig.cmake.in
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+# Name: Proton
+# Description: Qpid Proton C library
+# Version: @PN_VERSION@
+# URL: http://qpid.apache.org/proton/
+
+set (ProtonCpp_VERSION       @PN_VERSION@)
+
+set (ProtonCpp_INCLUDE_DIRS  @INCLUDEDIR@)
+set (ProtonCpp_LIBRARIES     optimized @LIBDIR@/@PROTONCPPLIB@ debug @LIBDIR@/@PROTONCPPLIBDEBUG@)
+
+set (ProtonCpp_FOUND True)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/proton-c/bindings/cpp/ProtonCppConfigVersion.cmake.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/ProtonCppConfigVersion.cmake.in b/proton-c/bindings/cpp/ProtonCppConfigVersion.cmake.in
new file mode 100644
index 0000000..d40f5c3
--- /dev/null
+++ b/proton-c/bindings/cpp/ProtonCppConfigVersion.cmake.in
@@ -0,0 +1,30 @@
+# This is a basic version file for the Config-mode of find_package().
+# It is used by write_basic_package_version_file() as input file for configure_file()
+# to create a version-file which can be installed along a config.cmake file.
+#
+# The created file sets PACKAGE_VERSION_EXACT if the current version string and
+# the requested version string are exactly the same and it sets
+# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
+
+set(PACKAGE_VERSION "@PN_VERSION@")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()
+
+# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
+if("${CMAKE_SIZEOF_VOID_P}"  STREQUAL ""  OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+   return()
+endif()
+
+# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
+if(NOT "${CMAKE_SIZEOF_VOID_P}"  STREQUAL  "@CMAKE_SIZEOF_VOID_P@")
+   math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
+   set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+   set(PACKAGE_VERSION_UNSUITABLE TRUE)
+endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fe0817e2/proton-c/bindings/cpp/libqpid-proton-cpp.pc.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/libqpid-proton-cpp.pc.in b/proton-c/bindings/cpp/libqpid-proton-cpp.pc.in
new file mode 100644
index 0000000..4b556f4
--- /dev/null
+++ b/proton-c/bindings/cpp/libqpid-proton-cpp.pc.in
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: Proton C++
+Description: Qpid Proton C++ library
+Version: @PN_VERSION@
+URL: http://qpid.apache.org/proton/
+Libs: -L${libdir} -lqpid-proton-cpp
+Cflags: -I${includedir}


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


[02/50] [abbrv] qpid-proton git commit: PROTON-827: Doc updates, minor API cleanup.

Posted by ac...@apache.org.
PROTON-827: Doc updates, minor API cleanup.

Added DefaultSession, Sender()/Receiver() on Connection.
Improved documentation and package README


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

Branch: refs/heads/go1
Commit: 43c5cff3274f4d4e9150202255ee9cafea83ed47
Parents: 3a48863
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Sep 29 16:07:27 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Sep 29 16:12:14 2015 -0400

----------------------------------------------------------------------
 examples/go/broker.go                           |  2 +-
 examples/go/receive.go                          | 10 +---
 examples/go/send.go                             | 10 +---
 .../go/src/qpid.apache.org/proton/README.md     | 12 ++++
 .../proton/concurrent/connection.go             | 62 +++++++++++++++++---
 .../proton/concurrent/container.go              |  4 +-
 .../qpid.apache.org/proton/concurrent/doc.go    | 22 ++++---
 .../proton/concurrent/endpoint.go               |  3 +-
 .../proton/concurrent/messaging_test.go         |  6 +-
 .../proton/concurrent/receiver.go               |  1 -
 .../proton/concurrent/session.go                |  5 +-
 .../go/src/qpid.apache.org/proton/doc.go        | 50 +++++++++++-----
 .../go/src/qpid.apache.org/proton/engine.go     |  7 +--
 13 files changed, 134 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/examples/go/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/broker.go b/examples/go/broker.go
index 3f85e9e..47d0a76 100644
--- a/examples/go/broker.go
+++ b/examples/go/broker.go
@@ -81,7 +81,7 @@ func (b *broker) listen(addr string) (err error) {
 		if err != nil {
 			return err
 		}
-		c, err := b.container.NewConnection(conn)
+		c, err := b.container.Connection(conn)
 		if err != nil {
 			return err
 		}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/examples/go/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/receive.go b/examples/go/receive.go
index a45ffe3..86244d7 100644
--- a/examples/go/receive.go
+++ b/examples/go/receive.go
@@ -73,19 +73,13 @@ func main() {
 			// Open a new connection
 			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
 			util.ExitIf(err)
-			c, err := container.NewConnection(conn)
+			c, err := container.Connection(conn)
 			util.ExitIf(err)
 			util.ExitIf(c.Open())
 			connections <- c // Save connection so we can Close() when main() ends
 
-			// Create and open a session
-			ss, err := c.NewSession()
-			util.ExitIf(err)
-			err = ss.Open()
-			util.ExitIf(err)
-
 			// Create a Receiver using the path of the URL as the source address
-			r, err := ss.Receiver(url.Path)
+			r, err := c.Receiver(url.Path)
 			util.ExitIf(err)
 
 			// Loop receiving messages and sending them to the main() goroutine

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/examples/go/send.go
----------------------------------------------------------------------
diff --git a/examples/go/send.go b/examples/go/send.go
index 7fa5416..edac2ae 100644
--- a/examples/go/send.go
+++ b/examples/go/send.go
@@ -76,20 +76,14 @@ func main() {
 			// Open a new connection
 			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
 			util.ExitIf(err)
-			c, err := container.NewConnection(conn)
+			c, err := container.Connection(conn)
 			util.ExitIf(err)
 			err = c.Open()
 			util.ExitIf(err)
 			connections = append(connections, c) // Save connection so it will be closed when main() ends
 
-			// Create and open a session
-			ss, err := c.NewSession()
-			util.ExitIf(err)
-			err = ss.Open()
-			util.ExitIf(err)
-
 			// Create a Sender using the path of the URL as the AMQP address
-			s, err := ss.Sender(url.Path)
+			s, err := c.Sender(url.Path)
 			util.ExitIf(err)
 
 			// Loop sending messages.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/README.md b/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
new file mode 100644
index 0000000..ad57b47
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/README.md
@@ -0,0 +1,12 @@
+# Go binding for proton
+
+This is a a [Go](http://golang.org) binding for proton.
+Package documentation is available at: <http://godoc.org/qpid.apache.org/proton>
+
+See the [examples](https://github.com/apache/qpid-proton/blob/master/examples/cpp/README.md)
+for working examples and practical instructions on how to get started.
+
+Feedback is encouraged at:
+
+- Email <pr...@qpid.apache.org>
+- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
index 9e82760..63fd3fc 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/connection.go
@@ -33,6 +33,19 @@ import (
 type Connection interface {
 	Endpoint
 
+	// Sender opens a new sender on the DefaultSession.
+	//
+	// v can be a string, which is used as the Target address, or a SenderSettings
+	// struct containing more details settings.
+	Sender(v interface{}) (Sender, error)
+
+	// Receiver opens a new Receiver on the DefaultSession().
+	//
+	// v can be a string, which is used as the
+	// Source address, or a ReceiverSettings struct containing more details
+	// settings.
+	Receiver(v interface{}) (Receiver, error)
+
 	// Server puts the connection in server mode, must be called before Open().
 	//
 	// A server connection will do protocol negotiation to accept a incoming AMQP
@@ -45,9 +58,12 @@ type Connection interface {
 	// Must be called before Open().
 	Listen()
 
-	// NewSession creates a new local session, you must call Session.Open()
-	// to open it with the remote peer.
-	NewSession() (s Session, err error)
+	// DefaultSession() returns a default session for the connection. It is opened
+	// on the first call to DefaultSession and returned on subsequent calls.
+	DefaultSession() (Session, error)
+
+	// Session opens a new session.
+	Session() (Session, error)
 
 	// Accept returns the next Endpoint (Session, Sender or Receiver) opened by
 	// the remote peer. It returns (nil, error) if the connection closes.
@@ -70,13 +86,13 @@ type Connection interface {
 	// Container for the connection.
 	Container() Container
 
-	// Disconnect the connection abrubtly.
+	// Disconnect the connection abruptly with an error.
 	Disconnect(error)
 }
 
 type connection struct {
 	endpoint
-	listenOnce sync.Once
+	listenOnce, defaultSessionOnce sync.Once
 
 	// Set before Open()
 	container *container
@@ -88,6 +104,8 @@ type connection struct {
 	engine      *proton.Engine
 	err         internal.FirstError
 	eConnection proton.Connection
+
+	defaultSession Session
 }
 
 func newConnection(conn net.Conn, cont *container) (*connection, error) {
@@ -129,18 +147,20 @@ func (c *connection) Disconnect(err error) {
 	}
 }
 
-// FIXME aconway 2015-09-24: needed?
 func (c *connection) closed(err error) {
 	// Call from another goroutine to initiate close without deadlock.
 	go c.Close(err)
 }
 
-func (c *connection) NewSession() (Session, error) {
+func (c *connection) Session() (Session, error) {
 	var s Session
 	err := c.engine.InjectWait(func() error {
 		eSession, err := c.engine.Connection().Session()
 		if err == nil {
-			s = newSession(c, eSession)
+			eSession.Open()
+			if err == nil {
+				s = newSession(c, eSession)
+			}
 		}
 		return err
 	})
@@ -165,3 +185,29 @@ func (c *connection) Accept() (Endpoint, error) {
 }
 
 func (c *connection) Container() Container { return c.container }
+
+func (c *connection) DefaultSession() (s Session, err error) {
+	c.defaultSessionOnce.Do(func() {
+		c.defaultSession, err = c.Session()
+	})
+	if err == nil {
+		err = c.Error()
+	}
+	return c.defaultSession, err
+}
+
+func (c *connection) Sender(v interface{}) (Sender, error) {
+	if s, err := c.DefaultSession(); err == nil {
+		return s.Sender(v)
+	} else {
+		return nil, err
+	}
+}
+
+func (c *connection) Receiver(v interface{}) (Receiver, error) {
+	if s, err := c.DefaultSession(); err == nil {
+		return s.Receiver(v)
+	} else {
+		return nil, err
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
index 5c090e3..5edecfc 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/container.go
@@ -39,7 +39,7 @@ type Container interface {
 	// setting any Connection properties you need to set. Note the net.Conn
 	// can be an outgoing connection (e.g. made with net.Dial) or an incoming
 	// connection (e.g. made with net.Listener.Accept())
-	NewConnection(conn net.Conn) (Connection, error)
+	Connection(conn net.Conn) (Connection, error)
 }
 
 type container struct {
@@ -66,6 +66,6 @@ func (cont *container) nextLinkName() string {
 	return cont.id + "@" + cont.linkNames.Next()
 }
 
-func (cont *container) NewConnection(conn net.Conn) (Connection, error) {
+func (cont *container) Connection(conn net.Conn) (Connection, error) {
 	return newConnection(conn, cont)
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
index 3e7756c..810a5da 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/doc.go
@@ -20,15 +20,23 @@ under the License.
 /*
 
 Package concurrent provides a procedural, concurrent Go API for exchanging AMQP
-messages.
+messages. You can write clients or servers using this API.
 
-AMPQ defines a credit-based scheme for flow control of messages over a
-link. Credit is the number of messages the receiver is willing to accept.  The
-receiver gives credit to the sender. The sender can send messages without
-waiting for a response from the receiver until it runs out of credit, at which
-point it must wait for more credit to send more messages.
+Start by creating a Container with NewContainer. A Container represents a client
+or server application that can contain incoming or outgoing connections.
+
+You can create connections with the standard Go 'net' package using net.Dial or
+net.Listen. Create an AMQP connection over a net.Conn with
+Container.Connection() and open it with Connection.Open().
+
+AMQP sends messages over "links", each link has a Sender and Receiver
+end. Connection.Sender() and Connection.Receiver() allow you to create links to
+send and receive messages.
+
+You can also create an AMQP server connection by calling Connection.Listen()
+before calling Open() on the connection. You can then call Connection.Accept()
+after calling Connection.Open() to accept incoming sessions and links.
 
-See the documentation of Sender and Receiver for details of how this API uses credit.
 */
 package concurrent
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
index 717cac1..f647058 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/endpoint.go
@@ -37,7 +37,8 @@ var Closed = io.EOF
 // Link, Sender and Receiver for details.
 //
 type Endpoint interface {
-	// Open the endpoint.
+	// Open the local end of a remotely-initiated endpoint. You must Open()
+	// endpoints returned by Connection.Accept() before using them.
 	Open() error
 
 	// Close an endpoint and signal an error to the remote end if error != nil.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
index aa806d7..0ee9f1a 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/messaging_test.go
@@ -41,7 +41,7 @@ func newServer(cont Container) (net.Addr, <-chan Connection) {
 	ch := make(chan Connection)
 	go func() {
 		conn, err := listener.Accept()
-		c, err := cont.NewConnection(conn)
+		c, err := cont.Connection(conn)
 		panicIf(err)
 		c.Server()
 		c.Listen()
@@ -55,10 +55,10 @@ func newServer(cont Container) (net.Addr, <-chan Connection) {
 func newClient(cont Container, addr net.Addr) Session {
 	conn, err := net.Dial(addr.Network(), addr.String())
 	panicIf(err)
-	c, err := cont.NewConnection(conn)
+	c, err := cont.Connection(conn)
 	panicIf(err)
 	c.Open()
-	sn, err := c.NewSession()
+	sn, err := c.Session()
 	panicIf(err)
 	panicIf(sn.Open())
 	return sn

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
index ad033a6..5bcf9f2 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/receiver.go
@@ -190,7 +190,6 @@ func (r *receiver) ReceiveTimeout(timeout time.Duration) (rm ReceivedMessage, er
 
 // Called in proton goroutine
 func (r *receiver) handleDelivery(delivery proton.Delivery) {
-	// FIXME aconway 2015-09-24: how can this happen if we are remote closed?
 	if r.eLink.State().RemoteClosed() {
 		localClose(r.eLink, r.eLink.RemoteCondition().Error())
 		return

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
index ba09690..2f609be 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/concurrent/session.go
@@ -28,6 +28,8 @@ import (
 //
 type Session interface {
 	Endpoint
+
+	// Connection owning this session.
 	Connection() Connection
 
 	// Sender opens a new sender. v can be a string, which is used as the Target
@@ -63,8 +65,6 @@ func (s *session) Close(err error) {
 	s.engine().Inject(func() { localClose(s.eSession, err) })
 }
 
-// NewSender create a link sending to target.
-// You must call snd.Open() before calling snd.Send().
 func (s *session) Sender(v interface{}) (snd Sender, err error) {
 	var settings LinkSettings
 	switch v := v.(type) {
@@ -86,7 +86,6 @@ func (s *session) Sender(v interface{}) (snd Sender, err error) {
 	return
 }
 
-// Receiver opens a receiving link.
 func (s *session) Receiver(v interface{}) (rcv Receiver, err error) {
 	var settings ReceiverSettings
 	switch v := v.(type) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/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 b175cf6..25b43af 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
@@ -18,24 +18,46 @@ under the License.
 */
 
 /*
-Package proton provides a Go binding for the Qpid proton AMQP library.
-AMQP is an open standard for inter-operable message exchange, see <http://www.amqp.org/>
 
-Proton is an event-driven, concurrent-unsafe AMQP protocol library that allows
-you to send and receive messages using the standard AMQP concurrent protocol.
+Package proton is a Go binding for the Qpid Proton AMQP messaging toolkit (see
+http://qpid.apache.org/proton) It is a concurrent-unsafe, event-driven API that
+closely follows the Proton C API.
 
-For most tasks, consider using package `qpid.apache.org/proton/concurrent`.  It
-provides a concurrent-safe API that is easier and more natural to use in Go.
+Package qpid.apache.org/proton/concurrent provides an alternative,
+concurrent-safe, procedural API. Most applications will find the concurrent API
+easier to use.
 
-The raw proton API is event-driven and not concurrent-safe. You implement a
-MessagingHandler event handler to react to AMQP protocol events. You must ensure
-that all events are handled in a single goroutine or that you serialize all all
-uses of the proton objects associated with a single connection using a lock.
-You can use channels to communicate between application goroutines and the
-event-handling goroutine, see type Event fro more detail.
+If you need direct access to the underlying proton library for some reason, this
+package provides it. The types in this package are simple wrappers for C
+pointers. They provide access to C functions as Go methods and do some trivial
+conversions, for example between Go string and C null-terminated char* strings.
 
-Package `qpid.apache.org/proton/concurrent` does all this for you and presents
-a simple concurrent-safe interface.
+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 connection and a
+proton.Connection goroutine that feeds events to a proton.MessagingHandler. See
+the proton.Engine documentation for more detail.
+
+EventHandler and MessagingHandler define an event handling interfaces that you
+can implement to react to protocol events. MessagingHandler provides a somewhat
+simpler set of events and automates some common tasks for you.
+
+You must ensure that all events are handled in a single goroutine or that you
+serialize all all uses of the proton objects associated with a single connection
+using a lock.  You can use channels to communicate between application
+goroutines and the event-handling goroutine, see Engine documentation for more details.
+
+Package qpid.apache.org/proton/concurrent does all this for you and presents a
+simple concurrent-safe interface, for most applications you should use that
+instead.
 
 */
 package proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/43c5cff3/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
index 3096280..63dc452 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/engine.go
@@ -76,10 +76,9 @@ func (b *bufferChan) buffer() []byte {
 // functions (such as sending messages) are encoded and written to the
 // net.Conn. Create a engine with NewEngine()
 //
-// The proton protocol engine is single threaded (per connection). The Engine runs
-// proton in the goroutine that calls Engine.Run() and creates goroutines to feed
-// data to/from a net.Conn. You can create multiple Engines to handle multiple
-// connections concurrently.
+// The Engine runs a proton event loop in the goroutine that calls Engine.Run()
+// and creates goroutines to feed data to/from a net.Conn. You can create
+// multiple Engines to handle multiple connections concurrently.
 //
 // Methods on proton values defined in this package (Sessions, Links etc.) can
 // only be called in the goroutine that executes the corresponding


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


[34/50] [abbrv] qpid-proton git commit: NO-JIRA: c++: Minor renaming for consistency and conciseness.

Posted by ac...@apache.org.
NO-JIRA: c++: Minor renaming for consistency and conciseness.

- Replace redundant container::container_id() with container::id()
- Replace bool is_sender()/sender& sender() with sender* sender()
  Consistent with casting, since these functions are cast-like.
- Drop "is_" from is_dynamic, is_described for consistency with other accessors.
- Rename create_(sender|receiver|sessin) to open_... for functions that open the endpoint.
- Renamed create_(sender|receiver)_link to create_... for functions that create but do not open.


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

Branch: refs/heads/go1
Commit: 4e9afbb088be900b1ad08ce1ef8974e833f5aa2f
Parents: 9106cb0
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 19 15:50:16 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 19 17:18:31 2015 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp                         | 20 +++++++++-----------
 examples/cpp/client.cpp                         |  4 ++--
 examples/cpp/helloworld.cpp                     |  4 ++--
 examples/cpp/helloworld_direct.cpp              |  2 +-
 examples/cpp/server.cpp                         |  4 ++--
 examples/cpp/server_direct.cpp                  |  4 ++--
 examples/cpp/simple_recv.cpp                    |  2 +-
 examples/cpp/simple_send.cpp                    |  2 +-
 .../bindings/cpp/include/proton/connection.hpp  |  6 +++---
 .../bindings/cpp/include/proton/container.hpp   |  6 +++---
 proton-c/bindings/cpp/include/proton/link.hpp   | 12 ++++--------
 .../bindings/cpp/include/proton/reactor.hpp     |  2 +-
 .../bindings/cpp/include/proton/session.hpp     |  8 ++++----
 .../bindings/cpp/include/proton/terminus.hpp    |  2 +-
 proton-c/bindings/cpp/include/proton/types.hpp  |  2 +-
 proton-c/bindings/cpp/src/blocking_receiver.cpp |  4 ++--
 proton-c/bindings/cpp/src/blocking_sender.cpp   |  4 ++--
 proton-c/bindings/cpp/src/connection.cpp        | 12 ++++++------
 proton-c/bindings/cpp/src/connector.cpp         |  2 +-
 proton-c/bindings/cpp/src/container.cpp         | 10 +++++-----
 proton-c/bindings/cpp/src/container_impl.cpp    | 12 ++++++------
 proton-c/bindings/cpp/src/container_impl.hpp    | 10 +++++-----
 proton-c/bindings/cpp/src/link.cpp              | 13 ++++---------
 proton-c/bindings/cpp/src/proton_event.cpp      | 10 ++++++++--
 proton-c/bindings/cpp/src/receiver.cpp          |  2 +-
 proton-c/bindings/cpp/src/sender.cpp            |  2 +-
 proton-c/bindings/cpp/src/session.cpp           | 12 ++++++------
 proton-c/bindings/cpp/src/terminus.cpp          |  2 +-
 tests/tools/apps/cpp/reactor_send.cpp           |  2 +-
 29 files changed, 86 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index 991fb88..c37f45c 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -121,22 +121,21 @@ class broker : public proton::messaging_handler {
 
     void on_link_opening(proton::event &e) {
         proton::link& lnk = e.link();
-        if (lnk.is_sender()) {
-            proton::sender &sender(lnk.sender());
+        if (lnk.sender()) {
             proton::terminus &remote_source(lnk.remote_source());
-            if (remote_source.is_dynamic()) {
+            if (remote_source.dynamic()) {
                 std::string address = queue_name();
                 lnk.source().address(address);
                 queue *q = new queue(true);
                 queues[address] = q;
-                q->subscribe(sender);
+                q->subscribe(*lnk.sender());
                 std::cout << "broker dynamic outgoing link from " << address << std::endl;
             }
             else {
                 std::string address = remote_source.address();
                 if (!address.empty()) {
                     lnk.source().address(address);
-                    get_queue(address).subscribe(sender);
+                    get_queue(address).subscribe(*lnk.sender());
                     std::cout << "broker outgoing link from " << address << std::endl;
                 }
             }
@@ -160,8 +159,8 @@ class broker : public proton::messaging_handler {
 
     void on_link_closing(proton::event &e) {
         proton::link &lnk = e.link();
-        if (lnk.is_sender()) {
-            unsubscribe(lnk.sender());
+        if (lnk.sender()) {
+            unsubscribe(*lnk.sender());
         }
     }
 
@@ -176,8 +175,8 @@ class broker : public proton::messaging_handler {
     void remove_stale_consumers(proton::connection &connection) {
         proton::link *l = connection.link_head(proton::endpoint::REMOTE_ACTIVE);
         while (l) {
-            if (l->is_sender()) {
-                unsubscribe(l->sender());
+            if (l->sender()) {
+                unsubscribe(*l->sender());
             }
             l = l->next(proton::endpoint::REMOTE_ACTIVE);
         }
@@ -186,8 +185,7 @@ class broker : public proton::messaging_handler {
     void on_sendable(proton::event &e) {
         proton::link& lnk = e.link();
         std::string addr = lnk.source().address();
-        proton::sender &s(lnk.sender());
-        get_queue(addr).dispatch(&s);
+        get_queue(addr).dispatch(lnk.sender());
     }
 
     void on_message(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 502e490..05924f6 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -38,9 +38,9 @@ class client : public proton::messaging_handler {
     client(const proton::url &u, const std::vector<std::string>& r) : url(u), requests(r) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().create_sender(url).ptr();
+        sender = e.container().open_sender(url).ptr();
         // Create a receiver with a dynamically chosen unique address.
-        receiver = sender->connection().create_receiver("", true/*dynamic*/).ptr();
+        receiver = sender->connection().open_receiver("", true/*dynamic*/).ptr();
     }
 
     void send_request() {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index 358162d..b1eed87 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -35,8 +35,8 @@ class hello_world : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         proton::connection& conn = e.container().connect(url);
-        conn.create_receiver(url.path());
-        conn.create_sender(url.path());
+        conn.open_receiver(url.path());
+        conn.open_sender(url.path());
     }
 
     void on_sendable(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index 4d96924..b141f1b 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -36,7 +36,7 @@ class hello_world_direct : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         acceptor = e.container().listen(url).ptr();
-        e.container().create_sender(url);
+        e.container().open_sender(url);
     }
 
     void on_sendable(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index 7c94228..e1de85e 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -43,7 +43,7 @@ class server : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         connection = e.container().connect(url).ptr();
-        connection->create_receiver(url.path());
+        connection->open_receiver(url.path());
         std::cout << "server connected to " << url << std::endl;
     }
 
@@ -62,7 +62,7 @@ class server : public proton::messaging_handler {
         reply.body(to_upper(e.message().body().get<std::string>()));
         reply.correlation_id(e.message().correlation_id());
         if (!senders[reply_to])
-            senders[reply_to] = connection->create_sender(reply_to).ptr();
+            senders[reply_to] = connection->open_sender(reply_to).ptr();
         senders[reply_to]->send(reply);
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 80e672a..2b6d8e2 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -63,9 +63,9 @@ class server : public proton::messaging_handler {
 
     void on_link_opening(proton::event& e) {
         proton::link& link = e.link();
-        if (link.is_sender() && link.has_remote_source() && link.remote_source().is_dynamic()) {
+        if (link.sender() && link.has_remote_source() && link.remote_source().dynamic()) {
             link.source().address(generate_address());
-            senders[link.source().address()] = link.sender().ptr();
+            senders[link.source().address()] = link.sender()->ptr();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index a3337d9..dfd8b5f 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -42,7 +42,7 @@ class simple_recv : public proton::messaging_handler {
     simple_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
 
     void on_start(proton::event &e) {
-        receiver = e.container().create_receiver(url).ptr();
+        receiver = e.container().open_receiver(url).ptr();
         std::cout << "simple_recv listening on " << url << std::endl;
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 971fbae..d103359 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -41,7 +41,7 @@ class simple_send : public proton::messaging_handler {
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().create_sender(url).ptr();
+        sender = e.container().open_sender(url).ptr();
     }
 
     void on_sendable(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 08b6ad9..2732802 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -55,16 +55,16 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
     PN_CPP_EXTERN void close();
 
     /** Create a new session */
-    PN_CPP_EXTERN class session& create_session();
+    PN_CPP_EXTERN class session& open_session();
 
     /** Default session is created on first call and re-used for the lifeime of the connection */
     PN_CPP_EXTERN class session& default_session();
 
     /** Create a sender on default_session() with target=addr and optional handler h */
-    PN_CPP_EXTERN sender& create_sender(const std::string &addr, handler *h=0);
+    PN_CPP_EXTERN sender& open_sender(const std::string &addr, handler *h=0);
 
     /** Create a receiver on default_session() with target=addr and optional handler h */
-    PN_CPP_EXTERN receiver& create_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
+    PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Get the first link on this connection matching the state mask.
      * Return 0 if none. Don't delete returned pointer.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 98754cf..ddb12e9 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -65,13 +65,13 @@ class container
     PN_CPP_EXTERN void run();
 
     /** Open a connection to url and create a sender with target=url.path() */
-    PN_CPP_EXTERN sender& create_sender(const proton::url &);
+    PN_CPP_EXTERN sender& open_sender(const proton::url &);
 
     /** Create a receiver on connection with source=url.path() */
-    PN_CPP_EXTERN receiver& create_receiver(const url &);
+    PN_CPP_EXTERN receiver& open_receiver(const url &);
 
     /// Identifier for the container
-    PN_CPP_EXTERN std::string container_id();
+    PN_CPP_EXTERN std::string id();
 
     /// Set the prefix to be used when generating link names. @see proton::session
     PN_CPP_EXTERN void link_prefix(const std::string&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 88b5368..8146f33 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -49,14 +49,10 @@ class link : public counted_facade<pn_link_t, link, endpoint>
      */
     PN_CPP_EXTERN void close();
 
-    /** True if link is a sender */
-    PN_CPP_EXTERN bool is_sender();
-    /** True if link is a receiver */
-    PN_CPP_EXTERN bool is_receiver();
-    /** Return sender pointer. @throw if link is not a sender. */
-    PN_CPP_EXTERN class sender& sender();
-    /** Return receiver pointer. @throw if link is not a receiver. */
-    PN_CPP_EXTERN class receiver& receiver();
+    /** Return sender if this link is a sender, 0 if not. */
+    PN_CPP_EXTERN class sender* sender();
+    /** Return receiver if this link is a receiver, 0 if not. */
+    PN_CPP_EXTERN class receiver* receiver();
     /** Credit available on the link */
     PN_CPP_EXTERN int credit();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/include/proton/reactor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reactor.hpp b/proton-c/bindings/cpp/include/proton/reactor.hpp
index 401c7dc..b9e9427 100644
--- a/proton-c/bindings/cpp/include/proton/reactor.hpp
+++ b/proton-c/bindings/cpp/include/proton/reactor.hpp
@@ -56,7 +56,7 @@ class reactor : public facade<pn_reactor_t, reactor> {
     PN_CPP_EXTERN void stop();
 
     /// Identifier for the container
-    PN_CPP_EXTERN std::string container_id();
+    PN_CPP_EXTERN std::string id();
 
     /// Get timeout, process() will return if there is no activity within the timeout.
     PN_CPP_EXTERN duration timeout();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 fdee859..7fe3e8d 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -59,20 +59,20 @@ class session : public counted_facade<pn_session_t, session, endpoint>
      *@param name must be unique within a container, if empty a unique name is
      * generated beginning with connection().container().link_prefix()
      */
-    PN_CPP_EXTERN receiver& create_receiver_link(const std::string& name=std::string());
+    PN_CPP_EXTERN receiver& create_receiver(const std::string& name=std::string());
 
     /** An un-opened sender link, you can set link properties before calling open().
      *
      *@param name must be unique within a container, if empty a unique name is
      * generated beginning with connection().container().link_prefix()
      */
-    PN_CPP_EXTERN sender& create_sender_link(const std::string& name=std::string());
+    PN_CPP_EXTERN sender& create_sender(const std::string& name=std::string());
 
     /** Create and open a sender with target=addr and optional handler h */
-    PN_CPP_EXTERN sender& create_sender(const std::string &addr, handler *h=0);
+    PN_CPP_EXTERN sender& open_sender(const std::string &addr, handler *h=0);
 
     /** Create and open a receiver with target=addr and optional handler h */
-    PN_CPP_EXTERN receiver& create_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
+    PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/include/proton/terminus.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/terminus.hpp b/proton-c/bindings/cpp/include/proton/terminus.hpp
index 4bb9651..e058e84 100644
--- a/proton-c/bindings/cpp/include/proton/terminus.hpp
+++ b/proton-c/bindings/cpp/include/proton/terminus.hpp
@@ -67,7 +67,7 @@ class terminus : public counted_facade<pn_terminus_t, terminus>
     PN_CPP_EXTERN void distribution_mode(distribution_mode_t);
     PN_CPP_EXTERN std::string address();
     PN_CPP_EXTERN void address(const std::string &);
-    PN_CPP_EXTERN bool is_dynamic();
+    PN_CPP_EXTERN bool dynamic();
     PN_CPP_EXTERN void dynamic(bool);
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/include/proton/types.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/types.hpp b/proton-c/bindings/cpp/include/proton/types.hpp
index 2de83d2..972f35d 100644
--- a/proton-c/bindings/cpp/include/proton/types.hpp
+++ b/proton-c/bindings/cpp/include/proton/types.hpp
@@ -228,7 +228,7 @@ struct start {
     type_id type;            ///< The container type: ARRAY, LIST, MAP or DESCRIBED.
     type_id element;         ///< the element type for array only.
     bool is_described;       ///< true if first value is a descriptor.
-    size_t size;            ///< the element count excluding the descriptor (if any)
+    size_t size;             ///< the element count excluding the descriptor (if any)
 
     /** Return a start for an array */
     PN_CPP_EXTERN static start array(type_id element, bool described=false);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/blocking_receiver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_receiver.cpp b/proton-c/bindings/cpp/src/blocking_receiver.cpp
index 9628620..656e770 100644
--- a/proton-c/bindings/cpp/src/blocking_receiver.cpp
+++ b/proton-c/bindings/cpp/src/blocking_receiver.cpp
@@ -46,7 +46,7 @@ blocking_receiver::blocking_receiver(
     class blocking_connection &c, const std::string& addr, int credit, bool dynamic) :
     blocking_link(c), fetcher_(new blocking_fetcher(credit))
 {
-    open(c.impl_->connection_->create_receiver(addr, dynamic, fetcher_.get()));
+    open(c.impl_->connection_->open_receiver(addr, dynamic, fetcher_.get()));
     std::string sa = link_->source().address();
     std::string rsa = link_->remote_source().address();
     if (!sa.empty() && sa.compare(rsa) != 0) {
@@ -97,6 +97,6 @@ void blocking_receiver::flow(int count) {
     receiver().flow(count);
 }
 
-receiver& blocking_receiver::receiver() { return link_->receiver(); }
+receiver& blocking_receiver::receiver() { return *link_->receiver(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/blocking_sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_sender.cpp b/proton-c/bindings/cpp/src/blocking_sender.cpp
index 323dc5e..1fca30b 100644
--- a/proton-c/bindings/cpp/src/blocking_sender.cpp
+++ b/proton-c/bindings/cpp/src/blocking_sender.cpp
@@ -39,7 +39,7 @@ struct delivery_settled : public blocking_connection_impl::condition {
 blocking_sender::blocking_sender(blocking_connection &c, const std::string &address) :
     blocking_link(c)
 {
-    open(c.impl_->connection_->create_sender(address));
+    open(c.impl_->connection_->open_sender(address));
     std::string ta = link_->target().address();
     std::string rta = link_->remote_target().address();
     if (ta.empty() || ta.compare(rta) != 0) {
@@ -63,6 +63,6 @@ delivery& blocking_sender::send(const message &msg) {
     return send(msg, connection_.timeout());
 }
 
-sender& blocking_sender::sender() { return link_->sender(); }
+sender& blocking_sender::sender() { return *link_->sender(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp
index 84c79a6..8f27a01 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -57,24 +57,24 @@ link* connection::link_head(endpoint::state mask) {
     return link::cast(pn_link_head(pn_cast(this), mask));
 }
 
-session& connection::create_session() { return *session::cast(pn_session(pn_cast(this))); }
+session& connection::open_session() { return *session::cast(pn_session(pn_cast(this))); }
 
 session& connection::default_session() {
     struct connection_context& ctx = connection_context::get(pn_cast(this));
     if (!ctx.default_session) {
-        ctx.default_session = &create_session();
+        ctx.default_session = &open_session();
         ctx.default_session->open();
     }
     return *ctx.default_session;
 }
 
-sender& connection::create_sender(const std::string &addr, handler *h) {
-    return default_session().create_sender(addr, h);
+sender& connection::open_sender(const std::string &addr, handler *h) {
+    return default_session().open_sender(addr, h);
 }
 
-receiver& connection::create_receiver(const std::string &addr, bool dynamic, handler *h)
+receiver& connection::open_receiver(const std::string &addr, bool dynamic, handler *h)
 {
-    return default_session().create_receiver(addr, dynamic, h);
+    return default_session().open_receiver(addr, dynamic, h);
 }
 
 endpoint::state connection::state() { return pn_connection_state(pn_cast(this)); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/connector.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.cpp b/proton-c/bindings/cpp/src/connector.cpp
index 3c7c970..49660ea 100644
--- a/proton-c/bindings/cpp/src/connector.cpp
+++ b/proton-c/bindings/cpp/src/connector.cpp
@@ -40,7 +40,7 @@ void connector::address(const url &a) {
 
 void connector::connect() {
     pn_connection_t *conn = pn_cast(connection_);
-    pn_connection_set_container(conn, connection_->container().container_id().c_str());
+    pn_connection_set_container(conn, connection_->container().id().c_str());
     pn_connection_set_hostname(conn, address_.host_port().c_str());
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 da97191..9b681b9 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -51,16 +51,16 @@ connection& container::connect(const url &host, handler *h) { return impl_->conn
 
 reactor &container::reactor() { return *impl_->reactor_; }
 
-std::string container::container_id() { return impl_->container_id_; }
+std::string container::id() { return impl_->id_; }
 
 void container::run() { impl_->reactor_->run(); }
 
-sender& container::create_sender(const proton::url &url) {
-    return impl_->create_sender(url);
+sender& container::open_sender(const proton::url &url) {
+    return impl_->open_sender(url);
 }
 
-receiver& container::create_receiver(const proton::url &url) {
-    return impl_->create_receiver(url);
+receiver& container::open_receiver(const proton::url &url) {
+    return impl_->open_receiver(url);
 }
 
 acceptor& container::listen(const proton::url &url) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index eda3c3b..cb32d75 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -116,10 +116,10 @@ counted_ptr<pn_handler_t> container_impl::cpp_handler(handler *h)
 }
 
 container_impl::container_impl(container& c, handler *h, const std::string& id) :
-    container_(c), reactor_(reactor::create()), handler_(h), container_id_(id),
+    container_(c), reactor_(reactor::create()), handler_(h), id_(id),
     link_id_(0)
 {
-    if (container_id_.empty()) container_id_ = uuid().str();
+    if (id_.empty()) id_ = uuid().str();
     container_context(pn_cast(reactor_.get()), container_);
 
     // Set our own global handler that "subclasses" the existing one
@@ -154,19 +154,19 @@ connection& container_impl::connect(const proton::url &url, handler *h) {
     return conn;
 }
 
-sender& container_impl::create_sender(const proton::url &url) {
+sender& container_impl::open_sender(const proton::url &url) {
     connection& conn = connect(url, 0);
     std::string path = url.path();
-    sender& snd = conn.default_session().create_sender(container_id_ + '-' + path);
+    sender& snd = conn.default_session().open_sender(id_ + '-' + path);
     snd.target().address(path);
     snd.open();
     return snd;
 }
 
-receiver& container_impl::create_receiver(const proton::url &url) {
+receiver& container_impl::open_receiver(const proton::url &url) {
     connection& conn = connect(url, 0);
     std::string path = url.path();
-    receiver& rcv = conn.default_session().create_receiver(container_id_ + '-' + path);
+    receiver& rcv = conn.default_session().open_receiver(id_ + '-' + path);
     pn_terminus_set_address(pn_link_source(pn_cast(&rcv)), path.c_str());
     rcv.open();
     return rcv;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index 6210b23..76d30fb 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -45,10 +45,10 @@ class container_impl
     PN_CPP_EXTERN container_impl(container&, handler *, const std::string& id);
     PN_CPP_EXTERN ~container_impl();
     PN_CPP_EXTERN connection& connect(const url&, handler *h);
-    PN_CPP_EXTERN sender& create_sender(connection &connection, const std::string &addr, handler *h);
-    PN_CPP_EXTERN sender& create_sender(const url&);
-    PN_CPP_EXTERN receiver& create_receiver(connection &connection, const std::string &addr, bool dynamic, handler *h);
-    PN_CPP_EXTERN receiver& create_receiver(const url&);
+    PN_CPP_EXTERN sender& open_sender(connection &connection, const std::string &addr, handler *h);
+    PN_CPP_EXTERN sender& open_sender(const url&);
+    PN_CPP_EXTERN receiver& open_receiver(connection &connection, const std::string &addr, bool dynamic, handler *h);
+    PN_CPP_EXTERN receiver& open_receiver(const url&);
     PN_CPP_EXTERN class acceptor& listen(const url&);
     PN_CPP_EXTERN duration timeout();
     PN_CPP_EXTERN void timeout(duration timeout);
@@ -66,7 +66,7 @@ class container_impl
     pn_unique_ptr<messaging_adapter> messaging_adapter_;
     pn_unique_ptr<handler> override_handler_;
     pn_unique_ptr<handler> flow_controller_;
-    std::string container_id_;
+    std::string id_;
     uint64_t link_id_;
     std::string prefix_;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp
index 12c8790..8afad6d 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -39,17 +39,12 @@ void link::close() {
     pn_link_close(pn_cast(this));
 }
 
-bool link::is_sender() { return pn_link_is_sender(pn_cast(this)); }
-bool link::is_receiver() { return pn_link_is_receiver(pn_cast(this)); }
-
-sender& link::sender() {
-    if (!is_sender()) throw error("link is not a sender");
-    return *reinterpret_cast<class sender*>(this);
+sender* link::sender() {
+    return pn_link_is_sender(pn_cast(this)) ? reinterpret_cast<class sender*>(this) : 0;
 }
 
-receiver& link::receiver() {
-    if (!is_receiver()) throw error("link is not a receiver");
-    return *reinterpret_cast<class receiver*>(this);
+receiver* link::receiver() {
+    return pn_link_is_receiver(pn_cast(this)) ? reinterpret_cast<class receiver*>(this) : 0;
 }
 
 int link::credit() {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 767c6af..80e678e 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -63,9 +63,15 @@ link& proton_event::link() {
     return *lnk;
 }
 
-sender& proton_event::sender() { return link().sender(); }
+sender& proton_event::sender() {
+    if (!link().sender()) throw error(MSG("No sender context for this event"));
+    return *link().sender();
+}
 
-receiver& proton_event::receiver() { return link().receiver(); }
+receiver& proton_event::receiver() {
+    if (!link().receiver()) throw error(MSG("No receiver context for this event"));
+    return *link().receiver();
+}
 
 delivery& proton_event::delivery() {
     class delivery *dlv = delivery::cast(pn_event_delivery(pn_event()));

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/receiver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/receiver.cpp b/proton-c/bindings/cpp/src/receiver.cpp
index 96a116d..d997c23 100644
--- a/proton-c/bindings/cpp/src/receiver.cpp
+++ b/proton-c/bindings/cpp/src/receiver.cpp
@@ -33,6 +33,6 @@ void receiver::flow(int count) {
     pn_link_flow(pn_cast(this), count);
 }
 
-receiver* receiver::cast(pn_type* p) { return &link::cast(p)->receiver(); }
+receiver* receiver::cast(pn_type* p) { return link::cast(p)->receiver(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/sender.cpp b/proton-c/bindings/cpp/src/sender.cpp
index 993f27d..cd1b0ae 100644
--- a/proton-c/bindings/cpp/src/sender.cpp
+++ b/proton-c/bindings/cpp/src/sender.cpp
@@ -54,6 +54,6 @@ delivery& sender::send(const message &message) {
     return *delivery::cast(dlv);
 }
 
-sender* sender::cast(pn_type* p) { return &link::cast(p)->sender(); }
+sender* sender::cast(pn_type* p) { return link::cast(p)->sender(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/session.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/session.cpp b/proton-c/bindings/cpp/src/session.cpp
index 3629f21..fd5df6f 100644
--- a/proton-c/bindings/cpp/src/session.cpp
+++ b/proton-c/bindings/cpp/src/session.cpp
@@ -46,27 +46,27 @@ std::string set_name(const std::string& name, session* s) {
 }
 }
 
-receiver& session::create_receiver_link(const std::string& name) {
+receiver& session::create_receiver(const std::string& name) {
     return *reinterpret_cast<receiver*>(
         pn_receiver(pn_cast(this), set_name(name, this).c_str()));
 }
 
-sender& session::create_sender_link(const std::string& name) {
+sender& session::create_sender(const std::string& name) {
     return *reinterpret_cast<sender*>(
         pn_sender(pn_cast(this), set_name(name, this).c_str()));
 }
 
-sender& session::create_sender(const std::string &addr, handler *h) {
-    sender& snd = create_sender_link();
+sender& session::open_sender(const std::string &addr, handler *h) {
+    sender& snd = create_sender();
     snd.target().address(addr);
     if (h) snd.handler(*h);
     snd.open();
     return snd;
 }
 
-receiver& session::create_receiver(const std::string &addr, bool dynamic, handler *h)
+receiver& session::open_receiver(const std::string &addr, bool dynamic, handler *h)
 {
-    receiver& rcv = create_receiver_link();
+    receiver& rcv = create_receiver();
     rcv.source().address(addr);
     if (dynamic) rcv.source().dynamic(true);
     if (h) rcv.handler(*h);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/proton-c/bindings/cpp/src/terminus.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/terminus.cpp b/proton-c/bindings/cpp/src/terminus.cpp
index 2c960d6..6d17786 100644
--- a/proton-c/bindings/cpp/src/terminus.cpp
+++ b/proton-c/bindings/cpp/src/terminus.cpp
@@ -57,7 +57,7 @@ void terminus::address(const std::string &addr) {
     pn_terminus_set_address(pn_cast(this), addr.c_str());
 }
 
-bool terminus::is_dynamic() {
+bool terminus::dynamic() {
     return (type_t) pn_terminus_is_dynamic(pn_cast(this));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4e9afbb0/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 721a7cd..7064876 100644
--- a/tests/tools/apps/cpp/reactor_send.cpp
+++ b/tests/tools/apps/cpp/reactor_send.cpp
@@ -64,7 +64,7 @@ class reactor_send : public proton::messaging_handler {
     }
 
     void on_start(proton::event &e) {
-        e.container().create_sender(url_);
+        e.container().open_sender(url_);
         reactor_ = pn_cast(&e.container().reactor());
     }
 


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


[46/50] [abbrv] qpid-proton git commit: NO-JIRA: go: restore go1 branch for go-get

Posted by ac...@apache.org.
NO-JIRA: go: restore go1 branch for go-get

Allows the go-get subtree to be updated, tested and served on the proton repo.
If required the go1 branch can also be pushed to a separate repo.


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

Branch: refs/heads/go1
Commit: f70afb69788c2652561bda625005a8f8cf7be53e
Parents: bc0a242
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 23 09:28:51 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 23 09:48:51 2015 -0400

----------------------------------------------------------------------
 .../bindings/go/src/qpid.apache.org/README.md   |  8 +++---
 .../go/src/qpid.apache.org/go-get-repo.sh       | 26 --------------------
 .../go/src/qpid.apache.org/readme-branch.md     |  7 ++++++
 3 files changed, 11 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70afb69/proton-c/bindings/go/src/qpid.apache.org/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/README.md b/proton-c/bindings/go/src/qpid.apache.org/README.md
index 21dcc19..4b2da12 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/README.md
+++ b/proton-c/bindings/go/src/qpid.apache.org/README.md
@@ -1,4 +1,4 @@
-# Qpid Go Libraries for AMQP
+# Qpid Go packages for AMQP
 
 These packages provide [Go](http://golang.org) support for sending and receiving
 AMQP messages in client or server applications. Reference documentation is
@@ -15,8 +15,8 @@ simple, concurrent-safe API for sending and receiving messages. It can be used
 with goroutines and channels to build concurrent AMQP clients and servers.
 
 [qpid.apache.org/proton](http://godoc.org/qpid.apache.org/proton) is an
-event-driven, concurrent-unsafe library that closely follows the proton C
-API. Most Go programmers will find the electron library easier to use.
+event-driven, concurrent-unsafe package that closely follows the proton C
+API. Most Go programmers will find the electron package easier to use.
 
 There are [examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
 to help you get started.
@@ -93,4 +93,4 @@ If you are new to Go then these are a good place to start:
 - [A Tour of Go](http://tour.golang.org)
 - [Effective Go](http://golang.org/doc/effective_go.html)
 
-Then look at the tools and library docs at <http://golang.org> as you need them.
+Then look at the tools and docs at <http://golang.org> as you need them.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70afb69/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh b/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
deleted file mode 100755
index 3a84191..0000000
--- a/proton-c/bindings/go/src/qpid.apache.org/go-get-repo.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-#
-# This script is used to create a repository to support the "go get" command.
-#
-# WARNING: DO NOT run in the main proton repository.
-#
-# This script will REPLACE the master branch of the current repository with just
-# the Go subset of the proton repository.
-#
-# Currently the go-get repository is: https://github.com/alanconway/proton-go.git
-#
-
-set -e -x
-# Safety check: the repo for `go get` should have a branch called proton_go_get_master
-git checkout proton_go_get_master
-git checkout master
-git fetch -f https://git-wip-us.apache.org/repos/asf/qpid-proton.git master:proton_go_get_master
-git checkout proton_go_get_master
-git branch -f -D master  # Will replace master with the go subtree of proton
-git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b master
-git checkout master
-
-set +x
-echo
-echo TO FINISH:
-echo git push -f -u origin master

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f70afb69/proton-c/bindings/go/src/qpid.apache.org/readme-branch.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/readme-branch.md b/proton-c/bindings/go/src/qpid.apache.org/readme-branch.md
new file mode 100644
index 0000000..b488eea
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/readme-branch.md
@@ -0,0 +1,7 @@
+`go1` is a special branch for the `go get` command, it contains just the Go subtree of proton.
+
+Created with: `git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b go1`
+Update with:  `git checkout go1; git merge -s subtree master`
+
+To see the branch description: `git config branch.go1.description`
+


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


[50/50] [abbrv] qpid-proton git commit: NO-JIRA: update reamde-branch.md with correct merge instructions.

Posted by ac...@apache.org.
NO-JIRA: update reamde-branch.md with correct merge instructions.


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

Branch: refs/heads/go1
Commit: e1a83ee2528b61f847df550d1e48279250cbb0d0
Parents: 8dc93cd
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 23 10:25:15 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 23 10:25:15 2015 -0400

----------------------------------------------------------------------
 readme-branch.md | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e1a83ee2/readme-branch.md
----------------------------------------------------------------------
diff --git a/readme-branch.md b/readme-branch.md
index b488eea..85e64f1 100644
--- a/readme-branch.md
+++ b/readme-branch.md
@@ -1,7 +1,9 @@
 `go1` is a special branch for the `go get` command, it contains just the Go subtree of proton.
 
-Created with: `git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b go1`
-Update with:  `git checkout go1; git merge -s subtree master`
+Created with:
+    git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b go1
+
+Update with:
+    git checkout go1; git merge -s recursive -X subtree=proton-c/bindings/go/src/qpid.apache.org master
 
-To see the branch description: `git config branch.go1.description`
 


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


[18/50] [abbrv] qpid-proton git commit: NO-JIRA: C++: Move event implementation classes out of public headers.

Posted by ac...@apache.org.
NO-JIRA: C++: Move event implementation classes out of public headers.

messaging_event and proton_event are implementation details, only proton::event needs to be public.


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

Branch: refs/heads/go1
Commit: 617cf6554de5b413e4cdcd6adb985ccb8d1a9463
Parents: da3ee2c
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 9 15:37:23 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 9 15:37:50 2015 -0400

----------------------------------------------------------------------
 .../cpp/include/proton/messaging_adapter.hpp    |   1 -
 .../cpp/include/proton/messaging_event.hpp      | 111 -------
 .../cpp/include/proton/proton_event.hpp         | 298 -------------------
 proton-c/bindings/cpp/src/container.cpp         |   2 +-
 proton-c/bindings/cpp/src/container_impl.cpp    |   2 +-
 proton-c/bindings/cpp/src/messaging_adapter.cpp |   2 +-
 proton-c/bindings/cpp/src/messaging_event.cpp   |   2 +-
 proton-c/bindings/cpp/src/messaging_event.hpp   | 111 +++++++
 proton-c/bindings/cpp/src/messaging_handler.cpp |   2 +-
 proton-c/bindings/cpp/src/proton_event.cpp      |   2 +-
 proton-c/bindings/cpp/src/proton_event.hpp      | 298 +++++++++++++++++++
 proton-c/bindings/cpp/src/proton_handler.cpp    |   2 +-
 12 files changed, 416 insertions(+), 417 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
index ded1309..29a26c6 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
@@ -25,7 +25,6 @@
 #include "proton/facade.hpp"
 #include "proton/messaging_handler.hpp"
 
-#include "proton/messaging_event.hpp"
 #include "proton/event.h"
 #include "proton/reactor.h"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/include/proton/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_event.hpp b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
deleted file mode 100644
index d130064..0000000
--- a/proton-c/bindings/cpp/include/proton/messaging_event.hpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef PROTON_CPP_MESSAGINGEVENT_H
-#define PROTON_CPP_MESSAGINGEVENT_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/proton_event.hpp"
-#include "proton/link.hpp"
-#include "proton/message.hpp"
-
-namespace proton {
-
-class handler;
-class container;
-class connection;
-class message;
-
-/** An event for the proton::messaging_handler */
-class messaging_event : public proton_event
-{
-  public:
-
-    std::string name() const;
-
-    // TODO aconway 2015-07-16: document meaning of each event type.
-
-    /** Event types for a messaging_handler */
-    enum event_type {
-        PROTON = 0,  // Wrapped pn_event_t
-        ABORT,
-        ACCEPTED,
-        COMMIT,
-        CONNECTION_CLOSED,
-        CONNECTION_CLOSING,
-        CONNECTION_ERROR,
-        CONNECTION_OPENED,
-        CONNECTION_OPENING,
-        DISCONNECTED,
-        FETCH,
-        ID_LOADED,
-        LINK_CLOSED,
-        LINK_CLOSING,
-        LINK_OPENED,
-        LINK_OPENING,
-        LINK_ERROR,
-        MESSAGE,
-        QUIT,
-        RECORD_INSERTED,
-        RECORDS_LOADED,
-        REJECTED,
-        RELEASED,
-        REQUEST,
-        RESPONSE,
-        SENDABLE,
-        SESSION_CLOSED,
-        SESSION_CLOSING,
-        SESSION_OPENED,
-        SESSION_OPENING,
-        SESSION_ERROR,
-        SETTLED,
-        START,
-        TIMER,
-        TRANSACTION_ABORTED,
-        TRANSACTION_COMMITTED,
-        TRANSACTION_DECLARED,
-        TRANSPORT_CLOSED
-    };
-
-    messaging_event(pn_event_t *ce, proton_event::event_type t, class container &c);
-    messaging_event(event_type t, proton_event &parent);
-    ~messaging_event();
-
-    virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class connection &connection();
-    virtual PN_CPP_EXTERN class sender& sender();
-    virtual PN_CPP_EXTERN class receiver& receiver();
-    virtual PN_CPP_EXTERN class link& link();
-    virtual PN_CPP_EXTERN class delivery& delivery();
-    virtual PN_CPP_EXTERN class message& message();
-
-    PN_CPP_EXTERN event_type type() const;
-
-  private:
-  friend class messaging_adapter;
-    event_type type_;
-    proton_event *parent_event_;
-    class message *message_;
-    messaging_event operator=(const messaging_event&);
-    messaging_event(const messaging_event&);
-};
-
-}
-
-#endif  /*!PROTON_CPP_MESSAGINGEVENT_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/include/proton/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/proton_event.hpp b/proton-c/bindings/cpp/include/proton/proton_event.hpp
deleted file mode 100644
index f71af55..0000000
--- a/proton-c/bindings/cpp/include/proton/proton_event.hpp
+++ /dev/null
@@ -1,298 +0,0 @@
-#ifndef PROTON_CPP_PROTONEVENT_H
-#define PROTON_CPP_PROTONEVENT_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/event.hpp"
-#include "proton/link.hpp"
-
-struct pn_event_t;
-
-namespace proton {
-
-class handler;
-class container;
-class connection;
-class container;
-
-/** Event information for a proton::proton_handler */
-class proton_event : public event
-{
-  public:
-
-    std::string name() const;
-
-    ///@name Event types
-    ///@{
-
-    /// The type of an event
-    typedef int event_type;
-
-    /**
-     * Defined as a programming convenience. No event of this type will
-     * ever be generated.
-     */
-    PN_CPP_EXTERN static const event_type EVENT_NONE;
-
-    /**
-     * A reactor has been started. Events of this type point to the reactor.
-     */
-    PN_CPP_EXTERN static const event_type REACTOR_INIT;
-
-    /**
-     * A reactor has no more events to process. Events of this type
-     * point to the reactor.
-     */
-    PN_CPP_EXTERN static const event_type REACTOR_QUIESCED;
-
-    /**
-     * A reactor has been stopped. Events of this type point to the reactor.
-     */
-    PN_CPP_EXTERN static const event_type REACTOR_FINAL;
-
-    /**
-     * A timer event has occurred.
-     */
-    PN_CPP_EXTERN static const event_type TIMER_TASK;
-
-    /**
-     * The connection has been created. This is the first event that
-     * will ever be issued for a connection. Events of this type point
-     * to the relevant connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_INIT;
-
-    /**
-     * The connection has been bound to a transport. This event is
-     * issued when the transport::bind() is called.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_BOUND;
-
-    /**
-     * The connection has been unbound from its transport. This event is
-     * issued when transport::unbind() is called.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_UNBOUND;
-
-    /**
-     * The local connection endpoint has been closed. Events of this
-     * type point to the relevant connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_LOCAL_OPEN;
-
-    /**
-     * The remote endpoint has opened the connection. Events of this
-     * type point to the relevant connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_REMOTE_OPEN;
-
-    /**
-     * The local connection endpoint has been closed. Events of this
-     * type point to the relevant connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_LOCAL_CLOSE;
-
-    /**
-     *  The remote endpoint has closed the connection. Events of this
-     *  type point to the relevant connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_REMOTE_CLOSE;
-
-    /**
-     * The connection has been freed and any outstanding processing has
-     * been completed. This is the final event that will ever be issued
-     * for a connection.
-     */
-    PN_CPP_EXTERN static const event_type CONNECTION_FINAL;
-
-    /**
-     * The session has been created. This is the first event that will
-     * ever be issued for a session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_INIT;
-
-    /**
-     * The local session endpoint has been opened. Events of this type
-     * point ot the relevant session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_LOCAL_OPEN;
-
-    /**
-     * The remote endpoint has opened the session. Events of this type
-     * point to the relevant session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_REMOTE_OPEN;
-
-    /**
-     * The local session endpoint has been closed. Events of this type
-     * point ot the relevant session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_LOCAL_CLOSE;
-
-    /**
-     * The remote endpoint has closed the session. Events of this type
-     * point to the relevant session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_REMOTE_CLOSE;
-
-    /**
-     * The session has been freed and any outstanding processing has
-     * been completed. This is the final event that will ever be issued
-     * for a session.
-     */
-    PN_CPP_EXTERN static const event_type SESSION_FINAL;
-
-    /**
-     * The link has been created. This is the first event that will ever
-     * be issued for a link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_INIT;
-
-    /**
-     * The local link endpoint has been opened. Events of this type
-     * point ot the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_LOCAL_OPEN;
-
-    /**
-     * The remote endpoint has opened the link. Events of this type
-     * point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_REMOTE_OPEN;
-
-    /**
-     * The local link endpoint has been closed. Events of this type
-     * point ot the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_LOCAL_CLOSE;
-
-    /**
-     * The remote endpoint has closed the link. Events of this type
-     * point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_REMOTE_CLOSE;
-
-    /**
-     * The local link endpoint has been detached. Events of this type
-     * point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_LOCAL_DETACH;
-
-    /**
-     * The remote endpoint has detached the link. Events of this type
-     * point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_REMOTE_DETACH;
-
-    /**
-     * The flow control state for a link has changed. Events of this
-     * type point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_FLOW;
-
-    /**
-     * The link has been freed and any outstanding processing has been
-     * completed. This is the final event that will ever be issued for a
-     * link. Events of this type point to the relevant link.
-     */
-    PN_CPP_EXTERN static const event_type LINK_FINAL;
-
-    /**
-     * A delivery has been created or updated. Events of this type point
-     * to the relevant delivery.
-     */
-    PN_CPP_EXTERN static const event_type DELIVERY;
-
-    /**
-     * The transport has new data to read and/or write. Events of this
-     * type point to the relevant transport.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT;
-
-    /**
-     * The transport has authenticated, if this is received by a server
-     * the associated transport has authenticated an incoming connection
-     * and transport::user() can be used to obtain the authenticated
-     * user.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT_AUTHENTICATED;
-
-    /**
-     * Indicates that a transport error has occurred. Use
-     * transport::condition() to access the details of the error
-     * from the associated transport.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT_ERROR;
-
-    /**
-     * Indicates that the head of the transport has been closed. This
-     * means the transport will never produce more bytes for output to
-     * the network. Events of this type point to the relevant transport.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT_HEAD_CLOSED;
-
-    /**
-     * Indicates that the tail of the transport has been closed. This
-     * means the transport will never be able to process more bytes from
-     * the network. Events of this type point to the relevant transport.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT_TAIL_CLOSED;
-
-    /**
-     * Indicates that the both the head and tail of the transport are
-     * closed. Events of this type point to the relevant transport.
-     */
-    PN_CPP_EXTERN static const event_type TRANSPORT_CLOSED;
-
-    PN_CPP_EXTERN static const event_type SELECTABLE_INIT;
-    PN_CPP_EXTERN static const event_type SELECTABLE_UPDATED;
-    PN_CPP_EXTERN static const event_type SELECTABLE_READABLE;
-    PN_CPP_EXTERN static const event_type SELECTABLE_WRITABLE;
-    PN_CPP_EXTERN static const event_type SELECTABLE_ERROR;
-    PN_CPP_EXTERN static const event_type SELECTABLE_EXPIRED;
-    PN_CPP_EXTERN static const event_type SELECTABLE_FINAL;
-
-    ///@}
-
-    virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class container &container();
-    virtual PN_CPP_EXTERN class connection &connection();
-    virtual PN_CPP_EXTERN class sender& sender();
-    virtual PN_CPP_EXTERN class receiver& receiver();
-    virtual PN_CPP_EXTERN class link& link();
-    virtual PN_CPP_EXTERN class delivery& delivery();
-
-    /** Get type of event */
-    PN_CPP_EXTERN event_type type() const;
-
-    PN_CPP_EXTERN pn_event_t* pn_event();
-
-  protected:
-    PN_CPP_EXTERN proton_event(pn_event_t *ce, proton_event::event_type t, class container &c);
-  private:
-    pn_event_t *pn_event_;
-    event_type type_;
-    class container &container_;
-};
-
-}
-
-#endif  /*!PROTON_CPP_PROTONEVENT_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/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 f9dc06e..da97191 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -19,7 +19,7 @@
  *
  */
 #include "proton/container.hpp"
-#include "proton/messaging_event.hpp"
+#include "messaging_event.hpp"
 #include "proton/connection.hpp"
 #include "proton/session.hpp"
 #include "proton/messaging_adapter.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index 3aab33f..eda3c3b 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -20,7 +20,7 @@
  */
 #include "proton/container.hpp"
 #include "proton/event.hpp"
-#include "proton/messaging_event.hpp"
+#include "messaging_event.hpp"
 #include "proton/connection.hpp"
 #include "proton/session.hpp"
 #include "proton/messaging_adapter.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/messaging_adapter.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp
index 6c86581..7235244 100644
--- a/proton-c/bindings/cpp/src/messaging_adapter.cpp
+++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp
@@ -19,7 +19,7 @@
  *
  */
 #include "proton/messaging_adapter.hpp"
-#include "proton/messaging_event.hpp"
+#include "messaging_event.hpp"
 #include "proton/sender.hpp"
 #include "proton/error.hpp"
 #include "msg.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index e602dc4..a9347d1 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -23,7 +23,7 @@
 #include "proton/event.h"
 #include "proton/link.h"
 
-#include "proton/messaging_event.hpp"
+#include "messaging_event.hpp"
 #include "proton/message.hpp"
 #include "proton/proton_handler.hpp"
 #include "proton/messaging_handler.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.hpp b/proton-c/bindings/cpp/src/messaging_event.hpp
new file mode 100644
index 0000000..1f73477
--- /dev/null
+++ b/proton-c/bindings/cpp/src/messaging_event.hpp
@@ -0,0 +1,111 @@
+#ifndef PROTON_CPP_MESSAGINGEVENT_H
+#define PROTON_CPP_MESSAGINGEVENT_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_event.hpp"
+#include "proton/link.hpp"
+#include "proton/message.hpp"
+
+namespace proton {
+
+class handler;
+class container;
+class connection;
+class message;
+
+/** An event for the proton::messaging_handler */
+class messaging_event : public proton_event
+{
+  public:
+
+    std::string name() const;
+
+    // TODO aconway 2015-07-16: document meaning of each event type.
+
+    /** Event types for a messaging_handler */
+    enum event_type {
+        PROTON = 0,  // Wrapped pn_event_t
+        ABORT,
+        ACCEPTED,
+        COMMIT,
+        CONNECTION_CLOSED,
+        CONNECTION_CLOSING,
+        CONNECTION_ERROR,
+        CONNECTION_OPENED,
+        CONNECTION_OPENING,
+        DISCONNECTED,
+        FETCH,
+        ID_LOADED,
+        LINK_CLOSED,
+        LINK_CLOSING,
+        LINK_OPENED,
+        LINK_OPENING,
+        LINK_ERROR,
+        MESSAGE,
+        QUIT,
+        RECORD_INSERTED,
+        RECORDS_LOADED,
+        REJECTED,
+        RELEASED,
+        REQUEST,
+        RESPONSE,
+        SENDABLE,
+        SESSION_CLOSED,
+        SESSION_CLOSING,
+        SESSION_OPENED,
+        SESSION_OPENING,
+        SESSION_ERROR,
+        SETTLED,
+        START,
+        TIMER,
+        TRANSACTION_ABORTED,
+        TRANSACTION_COMMITTED,
+        TRANSACTION_DECLARED,
+        TRANSPORT_CLOSED
+    };
+
+    messaging_event(pn_event_t *ce, proton_event::event_type t, class container &c);
+    messaging_event(event_type t, proton_event &parent);
+    ~messaging_event();
+
+    virtual PN_CPP_EXTERN void dispatch(handler &h);
+    virtual PN_CPP_EXTERN class connection &connection();
+    virtual PN_CPP_EXTERN class sender& sender();
+    virtual PN_CPP_EXTERN class receiver& receiver();
+    virtual PN_CPP_EXTERN class link& link();
+    virtual PN_CPP_EXTERN class delivery& delivery();
+    virtual PN_CPP_EXTERN class message& message();
+
+    PN_CPP_EXTERN event_type type() const;
+
+  private:
+  friend class messaging_adapter;
+    event_type type_;
+    proton_event *parent_event_;
+    class message *message_;
+    messaging_event operator=(const messaging_event&);
+    messaging_event(const messaging_event&);
+};
+
+}
+
+#endif  /*!PROTON_CPP_MESSAGINGEVENT_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/messaging_handler.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_handler.cpp b/proton-c/bindings/cpp/src/messaging_handler.cpp
index cd580f4..babe458 100644
--- a/proton-c/bindings/cpp/src/messaging_handler.cpp
+++ b/proton-c/bindings/cpp/src/messaging_handler.cpp
@@ -19,7 +19,7 @@
  *
  */
 #include "proton/messaging_handler.hpp"
-#include "proton/proton_event.hpp"
+#include "proton_event.hpp"
 #include "proton/messaging_adapter.hpp"
 #include "proton/handlers.h"
 #include <algorithm>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 9b08826..767c6af 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -26,7 +26,7 @@
 #include "proton/container.hpp"
 #include "proton/delivery.hpp"
 #include "proton/error.hpp"
-#include "proton/proton_event.hpp"
+#include "proton_event.hpp"
 #include "proton/proton_handler.hpp"
 #include "proton/receiver.hpp"
 #include "proton/sender.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.hpp b/proton-c/bindings/cpp/src/proton_event.hpp
new file mode 100644
index 0000000..f71af55
--- /dev/null
+++ b/proton-c/bindings/cpp/src/proton_event.hpp
@@ -0,0 +1,298 @@
+#ifndef PROTON_CPP_PROTONEVENT_H
+#define PROTON_CPP_PROTONEVENT_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/event.hpp"
+#include "proton/link.hpp"
+
+struct pn_event_t;
+
+namespace proton {
+
+class handler;
+class container;
+class connection;
+class container;
+
+/** Event information for a proton::proton_handler */
+class proton_event : public event
+{
+  public:
+
+    std::string name() const;
+
+    ///@name Event types
+    ///@{
+
+    /// The type of an event
+    typedef int event_type;
+
+    /**
+     * Defined as a programming convenience. No event of this type will
+     * ever be generated.
+     */
+    PN_CPP_EXTERN static const event_type EVENT_NONE;
+
+    /**
+     * A reactor has been started. Events of this type point to the reactor.
+     */
+    PN_CPP_EXTERN static const event_type REACTOR_INIT;
+
+    /**
+     * A reactor has no more events to process. Events of this type
+     * point to the reactor.
+     */
+    PN_CPP_EXTERN static const event_type REACTOR_QUIESCED;
+
+    /**
+     * A reactor has been stopped. Events of this type point to the reactor.
+     */
+    PN_CPP_EXTERN static const event_type REACTOR_FINAL;
+
+    /**
+     * A timer event has occurred.
+     */
+    PN_CPP_EXTERN static const event_type TIMER_TASK;
+
+    /**
+     * The connection has been created. This is the first event that
+     * will ever be issued for a connection. Events of this type point
+     * to the relevant connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_INIT;
+
+    /**
+     * The connection has been bound to a transport. This event is
+     * issued when the transport::bind() is called.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_BOUND;
+
+    /**
+     * The connection has been unbound from its transport. This event is
+     * issued when transport::unbind() is called.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_UNBOUND;
+
+    /**
+     * The local connection endpoint has been closed. Events of this
+     * type point to the relevant connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_LOCAL_OPEN;
+
+    /**
+     * The remote endpoint has opened the connection. Events of this
+     * type point to the relevant connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_REMOTE_OPEN;
+
+    /**
+     * The local connection endpoint has been closed. Events of this
+     * type point to the relevant connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_LOCAL_CLOSE;
+
+    /**
+     *  The remote endpoint has closed the connection. Events of this
+     *  type point to the relevant connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_REMOTE_CLOSE;
+
+    /**
+     * The connection has been freed and any outstanding processing has
+     * been completed. This is the final event that will ever be issued
+     * for a connection.
+     */
+    PN_CPP_EXTERN static const event_type CONNECTION_FINAL;
+
+    /**
+     * The session has been created. This is the first event that will
+     * ever be issued for a session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_INIT;
+
+    /**
+     * The local session endpoint has been opened. Events of this type
+     * point ot the relevant session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_LOCAL_OPEN;
+
+    /**
+     * The remote endpoint has opened the session. Events of this type
+     * point to the relevant session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_REMOTE_OPEN;
+
+    /**
+     * The local session endpoint has been closed. Events of this type
+     * point ot the relevant session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_LOCAL_CLOSE;
+
+    /**
+     * The remote endpoint has closed the session. Events of this type
+     * point to the relevant session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_REMOTE_CLOSE;
+
+    /**
+     * The session has been freed and any outstanding processing has
+     * been completed. This is the final event that will ever be issued
+     * for a session.
+     */
+    PN_CPP_EXTERN static const event_type SESSION_FINAL;
+
+    /**
+     * The link has been created. This is the first event that will ever
+     * be issued for a link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_INIT;
+
+    /**
+     * The local link endpoint has been opened. Events of this type
+     * point ot the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_LOCAL_OPEN;
+
+    /**
+     * The remote endpoint has opened the link. Events of this type
+     * point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_REMOTE_OPEN;
+
+    /**
+     * The local link endpoint has been closed. Events of this type
+     * point ot the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_LOCAL_CLOSE;
+
+    /**
+     * The remote endpoint has closed the link. Events of this type
+     * point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_REMOTE_CLOSE;
+
+    /**
+     * The local link endpoint has been detached. Events of this type
+     * point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_LOCAL_DETACH;
+
+    /**
+     * The remote endpoint has detached the link. Events of this type
+     * point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_REMOTE_DETACH;
+
+    /**
+     * The flow control state for a link has changed. Events of this
+     * type point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_FLOW;
+
+    /**
+     * The link has been freed and any outstanding processing has been
+     * completed. This is the final event that will ever be issued for a
+     * link. Events of this type point to the relevant link.
+     */
+    PN_CPP_EXTERN static const event_type LINK_FINAL;
+
+    /**
+     * A delivery has been created or updated. Events of this type point
+     * to the relevant delivery.
+     */
+    PN_CPP_EXTERN static const event_type DELIVERY;
+
+    /**
+     * The transport has new data to read and/or write. Events of this
+     * type point to the relevant transport.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT;
+
+    /**
+     * The transport has authenticated, if this is received by a server
+     * the associated transport has authenticated an incoming connection
+     * and transport::user() can be used to obtain the authenticated
+     * user.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT_AUTHENTICATED;
+
+    /**
+     * Indicates that a transport error has occurred. Use
+     * transport::condition() to access the details of the error
+     * from the associated transport.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT_ERROR;
+
+    /**
+     * Indicates that the head of the transport has been closed. This
+     * means the transport will never produce more bytes for output to
+     * the network. Events of this type point to the relevant transport.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT_HEAD_CLOSED;
+
+    /**
+     * Indicates that the tail of the transport has been closed. This
+     * means the transport will never be able to process more bytes from
+     * the network. Events of this type point to the relevant transport.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT_TAIL_CLOSED;
+
+    /**
+     * Indicates that the both the head and tail of the transport are
+     * closed. Events of this type point to the relevant transport.
+     */
+    PN_CPP_EXTERN static const event_type TRANSPORT_CLOSED;
+
+    PN_CPP_EXTERN static const event_type SELECTABLE_INIT;
+    PN_CPP_EXTERN static const event_type SELECTABLE_UPDATED;
+    PN_CPP_EXTERN static const event_type SELECTABLE_READABLE;
+    PN_CPP_EXTERN static const event_type SELECTABLE_WRITABLE;
+    PN_CPP_EXTERN static const event_type SELECTABLE_ERROR;
+    PN_CPP_EXTERN static const event_type SELECTABLE_EXPIRED;
+    PN_CPP_EXTERN static const event_type SELECTABLE_FINAL;
+
+    ///@}
+
+    virtual PN_CPP_EXTERN void dispatch(handler &h);
+    virtual PN_CPP_EXTERN class container &container();
+    virtual PN_CPP_EXTERN class connection &connection();
+    virtual PN_CPP_EXTERN class sender& sender();
+    virtual PN_CPP_EXTERN class receiver& receiver();
+    virtual PN_CPP_EXTERN class link& link();
+    virtual PN_CPP_EXTERN class delivery& delivery();
+
+    /** Get type of event */
+    PN_CPP_EXTERN event_type type() const;
+
+    PN_CPP_EXTERN pn_event_t* pn_event();
+
+  protected:
+    PN_CPP_EXTERN proton_event(pn_event_t *ce, proton_event::event_type t, class container &c);
+  private:
+    pn_event_t *pn_event_;
+    event_type type_;
+    class container &container_;
+};
+
+}
+
+#endif  /*!PROTON_CPP_PROTONEVENT_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/617cf655/proton-c/bindings/cpp/src/proton_handler.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_handler.cpp b/proton-c/bindings/cpp/src/proton_handler.cpp
index d7c2da4..7080d39 100644
--- a/proton-c/bindings/cpp/src/proton_handler.cpp
+++ b/proton-c/bindings/cpp/src/proton_handler.cpp
@@ -19,7 +19,7 @@
  *
  */
 #include "proton/proton_handler.hpp"
-#include "proton/proton_event.hpp"
+#include "proton_event.hpp"
 
 namespace proton {
 


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


[32/50] [abbrv] qpid-proton git commit: NO-JIRA: Correct go documentation links.

Posted by ac...@apache.org.
NO-JIRA: Correct go documentation links.


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

Branch: refs/heads/go1
Commit: dc5cbac0a8f9e77cf91a6def28d0fcfbe4d4dfa8
Parents: abea588
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 19 14:08:29 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 19 15:01:50 2015 -0400

----------------------------------------------------------------------
 .../bindings/go/src/qpid.apache.org/README.md   | 147 +++++++++----------
 1 file changed, 69 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/dc5cbac0/proton-c/bindings/go/src/qpid.apache.org/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/README.md b/proton-c/bindings/go/src/qpid.apache.org/README.md
index b99047d..21dcc19 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/README.md
+++ b/proton-c/bindings/go/src/qpid.apache.org/README.md
@@ -1,99 +1,90 @@
 # Qpid Go Libraries for AMQP
 
-These packages provide [Go](http://golang.org) support for sending and receiving AMQP
-messages in client or server applications.
+These packages provide [Go](http://golang.org) support for sending and receiving
+AMQP messages in client or server applications. Reference documentation is
+available at: <http://godoc.org/?q=qpid.apache.org>
 
-Package documentation is available at: <http://godoc.org/qpid.apache.org/>
+There are 3 packages:
 
-See the [examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
-for working examples and practical instructions on how to get started.
+[qpid.apache.org/amqp](http://godoc.org/qpid.apache.org/amqp) provides functions
+to convert AMQP messages and data types to and from Go data types.  Used by both
+the proton and electron packages to manage AMQP data.
 
-Feedback is encouraged at:
-
-- Email <pr...@qpid.apache.org>
-- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.
-
-## Status
-
-There are 3 go packages for proton:
+[qpid.apache.org/electron](http://godoc.org/qpid.apache.org/electron) is a
+simple, concurrent-safe API for sending and receiving messages. It can be used
+with goroutines and channels to build concurrent AMQP clients and servers.
 
-`qpid.apache.org/electron`:  procedural, concurrent-safe Go library for AMQP messaging.
-A simple procedural API that can easily be used with goroutines and channels to construct
-concurrent AMQP clients and servers.
+[qpid.apache.org/proton](http://godoc.org/qpid.apache.org/proton) is an
+event-driven, concurrent-unsafe library that closely follows the proton C
+API. Most Go programmers will find the electron library easier to use.
 
-`qpid.apache.org/proton`: event-driven, concurrent-unsafe Go library for AMQP messaging.
-A simple port into Go of the Proton C library. Its event-driven, single-threaded nature
-may be off-putting for Go programmers, hence the electron API.
+There are [examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
+to help you get started.
 
-`qpid.apache.org/amqp`: converts AMQP messages and data types to and from Go data types.
-Used by both the proton and electron packages to represent AMQP types.
-
-See the
-[examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
-for an illustration of the APIs, in particular compare `proton/broker.go` and
-`electron/broker.go` which illustrate the different API approaches to the same
-task (a simple broker.)
+Feedback is encouraged at:
 
+- Email <pr...@qpid.apache.org>
+- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.
 
 ### Why two APIs?
 
-Go is a concurrent language and encourages applications to be divided into
-concurrent *goroutines*. It provides traditional locking but it encourages the
-use *channels* to communicate between goroutines without explicit locks:
-
-  "Share memory by communicating, don't communicate by sharing memory"
-
-The idea is that a given value is only operated on by one goroutine at a time,
-but values can easily be passed from one goroutine to another.
+The `proton` API is a direct mapping of the proton C library into Go. It is
+usable but not very natural for a Go programmer because it takes an
+*event-driven* approach and has no built-in support for concurrent
+use. `electron` uses `proton` internally but provides a more Go-like API that is
+safe to use from multiple concurrent goroutines.
 
-Go literature distinguishes between:
+Go encourages programs to be structured as concurrent *goroutines* that
+communicate via *channels*. Go literature distinguishes between:
 
 - *concurrency*: "keeping track of things that could be done in parallel"
-- *parallelism*: "actually doing things in parallel"
+- *parallelism*: "actually doing things in parallel on multiple CPUs or cores"
 
-The application expresses concurrency by starting goroutines for potentially
-concurrent tasks. The Go run-times schedule the activity of goroutines onto a
+A Go program expresses concurrency by starting goroutines for potentially
+concurrent tasks. The Go runtime schedules the activity of goroutines onto a
 small number (possibly one) of actual parallel executions.
 
-Even with *no* parallelism, concurrency lets the Go run-times *order* work with
-respect to events like file descriptors being readable/writable, channels having
-data, timers firing etc. Go automatically takes care of switching out goroutines
-that block or sleep so it is normal to write code in terms of blocking calls.
-
-Event-driven programming (such as poll, epoll, select or the `proton` package)
-also channels unpredictably ordered events to actions in one or a small pool of
-execution threads. However this requires a different style of programming:
-"event-driven" or "reactive" programming. Go developers call it "inside-out"
-programming. In an event-driven architecture blocking is a big problem as it
-consumes a scarce thread of execution, so actions that take time to complete
-have to be re-structured in terms of future event delivery.
-
-The promise of Go is that you can express your application in concurrent,
-procedural terms with simple blocking calls and the Go run-times will turn it
-inside-out for you. Write as many goroutines as you want, and let Go interleave
-and schedule them efficiently.
-
-For example: the Go equivalent of listening for connections is a goroutine with
-a simple endless loop that calls a blocking Listen() function and starts a
-goroutine for each new connection. Each connection has its own goroutine that
-deals with just that connection till it closes.
-
-The benefit is that the variables and logic live closer together. Once you're in
-a goroutine, you have everything you need in local variables, and they are
-preserved across blocking calls. There's no need to store details in context
-objects that you have to look up when handling a later event to figure out how
-to continue where you left off.
-
-The `proton` API is important because it is close to the original proton-C
-reactive API and gives you direct access to the underlying library. However it
-is un-Go-like in it's event-driven nature, and it requires care as methods on
-values associated with the same underlying proton engine are not
-concurrent-safe.
-
-The `electron` API hides the event-driven details behind a simple blocking API
-that can be safely called from arbitrary goroutines. Under the covers data is
-passed through channels to dedicated goroutines running separate `proton` event
-loops for each connection.
+Even with no hardware parallelism, goroutine concurrency lets the Go runtime
+order unpredictable events like file descriptors being readable/writable,
+channels having data, timers firing etc. Go automatically takes care of
+switching out goroutines that block or sleep so it is normal to write code in
+terms of blocking calls.
+
+By contrast, event-driven programming is based on polling mechanisms like
+`select`, `poll` or `epoll`. These also dispatch unpredictably ordered events to
+a single thread or a small thread pool. However this requires a different style
+of programming: "event-driven" or "reactive" programming. Go developers call it
+"inside-out" programming.  In an event-driven program blocking is a big problem
+as it consumes a scarce thread of execution, so actions that take time to
+complete have to be re-structured in terms of multiple events.
+
+The promise of Go is that you can express your program in concurrent, sequential
+terms and the Go runtime will turn it inside-out for you. You can start
+goroutines for all concurrent activities. They can loop forever or block for as
+long as they need waiting for timers, IO or any unpredictable event. Go will
+interleave and schedule them efficiently onto the available parallel hardware.
+
+For example: in the `electron` API, you can send a message and wait for it to be
+acknowledged in a single function. All the information about the message, why
+you sent it, and what to do when it is acknowledged can be held in local
+variables, all the code is in a simple sequence. Other goroutines in your
+program can be sending and receiving messages concurrently, they are not
+blocked.
+
+In the `proton` API, an event handler that sends a message must return
+*immediately*, it cannot block the event loop to wait for
+acknowledgement. Acknowledgement is a separate event, so the code for handling
+it is in a different event handler. Context information about the message has to
+be stored in some non-local variable that both functions can find. This makes
+the code harder to follow.
+
+The `proton` API is important because it is the foundation for the `electron`
+API, and may be useful for programs that need to be close to the original C
+library for some reason. However the `electron` API hides the event-driven
+details behind simple, sequential, concurrent-safe methods that can be called
+from arbitrary goroutines. Under the covers, data is passed through channels to
+dedicated `proton` goroutines so user goroutines can work concurrently with the
+proton event-loop.
 
 ## New to Go?
 


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


[10/50] [abbrv] qpid-proton git commit: PROTON-1011: Go example of event driven broker. Package renaming and some new features.

Posted by ac...@apache.org.
PROTON-1011: Go example of event driven broker. Package renaming and some new features.

New pacakges names:

- qpid.apache.org/amqp - amqp/Go data mapping
- qpid.apache.org/proton - faithful wrapper of proton C library
- qpid.apache.org/electron - alternative, procedural, concurrent-safe Go API

Simplified broker examples, complete proton and electron brokers for comparison.

- Send blocks for credit, added SendTimeout.
- Fixed some shut-down issues
- Session flow control.
- Additional unit tests


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

Branch: refs/heads/go1
Commit: 478ba4ea1e7a2c5e60ac8f64d6756f2e6658663b
Parents: 2789615
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Sep 29 17:29:22 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Oct 8 00:30:09 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt                      |  15 +-
 examples/go/README.md                           |  24 +-
 examples/go/broker.go                           | 161 ------
 examples/go/electron/broker.go                  | 148 +++++
 examples/go/electron/receive.go                 | 122 ++++
 examples/go/electron/send.go                    | 123 ++++
 examples/go/example_test.go                     |   6 +-
 examples/go/proton/broker.go                    | 299 ++++++++++
 examples/go/receive.go                          | 119 ----
 examples/go/send.go                             | 121 ----
 examples/go/util/queue.go                       |  89 +--
 examples/go/util/util.go                        |   2 +-
 proton-c/bindings/go/CMakeLists.txt             |   4 +-
 proton-c/bindings/go/README.md                  | 151 +----
 .../bindings/go/src/qpid.apache.org/README.md   | 105 ++++
 .../bindings/go/src/qpid.apache.org/amqp/doc.go |  34 ++
 .../go/src/qpid.apache.org/amqp/error.go        |  66 +++
 .../go/src/qpid.apache.org/amqp/interop         |   1 +
 .../go/src/qpid.apache.org/amqp/interop_test.go | 381 +++++++++++++
 .../go/src/qpid.apache.org/amqp/marshal.go      | 250 +++++++++
 .../go/src/qpid.apache.org/amqp/message.go      | 347 ++++++++++++
 .../go/src/qpid.apache.org/amqp/message_test.go | 166 ++++++
 .../go/src/qpid.apache.org/amqp/types.go        | 198 +++++++
 .../go/src/qpid.apache.org/amqp/unmarshal.go    | 556 +++++++++++++++++++
 .../bindings/go/src/qpid.apache.org/amqp/url.go |  96 ++++
 .../go/src/qpid.apache.org/amqp/url_test.go     |  51 ++
 .../src/qpid.apache.org/electron/connection.go  | 192 +++++++
 .../src/qpid.apache.org/electron/container.go   |  71 +++
 .../go/src/qpid.apache.org/electron/doc.go      |  57 ++
 .../go/src/qpid.apache.org/electron/endpoint.go |  68 +++
 .../go/src/qpid.apache.org/electron/handler.go  | 176 ++++++
 .../go/src/qpid.apache.org/electron/link.go     | 242 ++++++++
 .../qpid.apache.org/electron/messaging_test.go  | 412 ++++++++++++++
 .../go/src/qpid.apache.org/electron/receiver.go | 232 ++++++++
 .../go/src/qpid.apache.org/electron/sender.go   | 319 +++++++++++
 .../go/src/qpid.apache.org/electron/session.go  |  98 ++++
 .../go/src/qpid.apache.org/electron/time.go     |  81 +++
 .../go/src/qpid.apache.org/internal/error.go    | 118 ++++
 .../src/qpid.apache.org/internal/flexchannel.go |  82 +++
 .../internal/flexchannel_test.go                |  89 +++
 .../go/src/qpid.apache.org/internal/safemap.go  |  57 ++
 .../go/src/qpid.apache.org/internal/uuid.go     |  70 +++
 .../go/src/qpid.apache.org/proton/README.md     |  12 -
 .../go/src/qpid.apache.org/proton/amqp/doc.go   |  34 --
 .../go/src/qpid.apache.org/proton/amqp/error.go |  66 ---
 .../go/src/qpid.apache.org/proton/amqp/interop  |   1 -
 .../qpid.apache.org/proton/amqp/interop_test.go | 381 -------------
 .../src/qpid.apache.org/proton/amqp/marshal.go  | 250 ---------
 .../src/qpid.apache.org/proton/amqp/message.go  | 347 ------------
 .../qpid.apache.org/proton/amqp/message_test.go | 166 ------
 .../go/src/qpid.apache.org/proton/amqp/types.go | 198 -------
 .../qpid.apache.org/proton/amqp/unmarshal.go    | 556 -------------------
 .../go/src/qpid.apache.org/proton/amqp/url.go   |  96 ----
 .../src/qpid.apache.org/proton/amqp/url_test.go |  51 --
 .../proton/concurrent/connection.go             | 213 -------
 .../proton/concurrent/container.go              |  71 ---
 .../qpid.apache.org/proton/concurrent/doc.go    |  46 --
 .../proton/concurrent/endpoint.go               |  87 ---
 .../proton/concurrent/handler.go                | 137 -----
 .../qpid.apache.org/proton/concurrent/link.go   | 232 --------
 .../proton/concurrent/messaging_test.go         | 205 -------
 .../proton/concurrent/receiver.go               | 241 --------
 .../qpid.apache.org/proton/concurrent/sender.go | 190 -------
 .../proton/concurrent/session.go                | 114 ----
 .../qpid.apache.org/proton/concurrent/time.go   |  71 ---
 .../go/src/qpid.apache.org/proton/doc.go        |  49 +-
 .../go/src/qpid.apache.org/proton/engine.go     | 218 ++++----
 .../go/src/qpid.apache.org/proton/handlers.go   |  22 +-
 .../qpid.apache.org/proton/internal/error.go    | 121 ----
 .../proton/internal/flexchannel.go              |  82 ---
 .../proton/internal/flexchannel_test.go         |  89 ---
 .../qpid.apache.org/proton/internal/safemap.go  |  57 --
 .../src/qpid.apache.org/proton/internal/uuid.go |  70 ---
 .../go/src/qpid.apache.org/proton/message.go    |  17 +-
 .../go/src/qpid.apache.org/proton/wrappers.go   |  25 +-
 .../src/qpid.apache.org/proton/wrappers_gen.go  |   2 +-
 76 files changed, 5534 insertions(+), 4982 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 873180d..1b68ebe 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -18,10 +18,11 @@
 #
 
 if(BUILD_GO)
-  set(examples receive send broker)
+  set(examples electron/receive electron/send electron/broker proton/broker)
 
   foreach(example ${examples})
-    add_custom_target(go-example-${example} ALL
+    string(REPLACE / - target ${example})
+    add_custom_target(go-example-${target} ALL
       COMMAND ${GO_BUILD} ${GO_EXAMPLE_FLAGS} -o ${CMAKE_CURRENT_BINARY_DIR}/${example} ${CMAKE_CURRENT_SOURCE_DIR}/${example}.go
       DEPENDS go-packages qpid-proton)
   endforeach()
@@ -30,8 +31,14 @@ if(BUILD_GO)
       DEPENDS go-packages qpid-proton)
 
   add_test(
-    NAME go_example_test
-    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -broker broker)
+    NAME go_example_electron_test
+    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -broker broker
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/electron)
+
+  add_test(
+    NAME go_example_proton_test
+    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -broker ../proton/broker
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/electron)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/README.md
----------------------------------------------------------------------
diff --git a/examples/go/README.md b/examples/go/README.md
index c0bfd85..0114d0e 100644
--- a/examples/go/README.md
+++ b/examples/go/README.md
@@ -2,22 +2,30 @@
 
 There are 3 Go packages for proton:
 
-- qpid.apache.org/proton/concurrent: Easy-to-use, concurrent API for concurrent clients and servers.
-- qpid.apache.org/proton/amqp: Convert AMQP messages and data to and from Go data types.
+- qpid.apache.org/electron: Concurrent, procedural API for messaging clients and servers.
 - qpid.apache.org/proton: Direct access to the event-driven, concurrent-unsafe proton library.
+- qpid.apache.org/amqp: Convert AMQP messages and data to and from Go data types.
 
-Most applications should use the `concurrent` package. The `proton` package is
-for applications that need low-level access to the proton library.
+`proton` and `electron` are alternative APIs for sending messages. `proton` is a
+direct wrapping of the concurrent-unsafe, event-driven C proton API. `electron`
+is a procedural, concurrent-safe interface that may be more convenient and
+familiar for Go programmers. The examples `proton/broker.go` and
+`electron/broker.go` give an illustration of how the APIs differ.
 
 ## Example programs
 
-- [receive.go](receive.go) receive from many connections concurrently.
-- [send.go](send.go) send to many connections concurrently.
+electron
+- [receive.go](electron/receive.go) receive from many connections concurrently.
+- [send.go](electron/send.go) send to many connections concurrently.
+- [broker.go](electron/broker.go) a simple broker using the electron API
+
+proton
+- [broker.go](proton/broker.go) a simple broker using the proton API
 
 ## Using the Go packages
 
-Use `go get qpid.apache.org/proton/concurrent` or check out the proton
-repository and set your GOPATH environment variable to include
+Use `go get qpid.apache.org/electron` or check out the proton repository and set
+your GOPATH environment variable to include
 `/<path-to-proton>/proton-c/bindings/go`
 
 The proton Go packages include C code so the cgo compiler needs to be able to

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/broker.go b/examples/go/broker.go
deleted file mode 100644
index 47d0a76..0000000
--- a/examples/go/broker.go
+++ /dev/null
@@ -1,161 +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.
-*/
-
-//
-// This is a simple AMQP broker implemented using the concurrent interface.
-//
-// It maintains a set of named in-memory queues of messages. Clients can send
-// messages to queues or subscribe to receive messages from them.
-//
-//
-
-package main
-
-import (
-	"./util"
-	"flag"
-	"fmt"
-	"log"
-	"net"
-	"os"
-	"qpid.apache.org/proton/concurrent"
-)
-
-// Usage and command-line flags
-func usage() {
-	fmt.Fprintf(os.Stderr, `
-Usage: %s
-A simple broker-like demo. Queues are created automatically for sender or receiver addrsses.
-`, os.Args[0])
-	flag.PrintDefaults()
-}
-
-var addr = flag.String("addr", ":amqp", "Listening address")
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-	b := newBroker()
-	err := b.listen(*addr)
-	util.ExitIf(err)
-}
-
-type broker struct {
-	container concurrent.Container
-	queues    util.QueueMap
-}
-
-func newBroker() *broker {
-	return &broker{
-		container: concurrent.NewContainer(""),
-		queues:    util.MakeQueueMap(),
-	}
-}
-
-// Listen for incoming connections
-func (b *broker) listen(addr string) (err error) {
-	listener, err := net.Listen("tcp", addr)
-	if err != nil {
-		return err
-	}
-	log.Printf("Listening on %s\n", listener.Addr())
-	defer listener.Close()
-	for {
-		conn, err := listener.Accept()
-		if err != nil {
-			return err
-		}
-		c, err := b.container.Connection(conn)
-		if err != nil {
-			return err
-		}
-		// Make this a server connection. Must be done before Open()
-		c.Server() // Server-side protocol negotiation.
-		c.Listen() // Enable remotely-opened endpoints.
-		if err := c.Open(); err != nil {
-			return err
-		}
-		util.Debugf("accept %s\n", c)
-		// Accept remotely-opened endpoints on the connection
-		go b.accept(c)
-	}
-}
-
-// accept remotely-opened endpoints (Session, Sender and Receiver)
-func (b *broker) accept(c concurrent.Connection) {
-	for ep, err := c.Accept(); err == nil; ep, err = c.Accept() {
-		switch ep := ep.(type) {
-		case concurrent.Session:
-			util.Debugf("accept session %s\n", ep)
-			ep.Open()
-		case concurrent.Sender:
-			util.Debugf("accept sender %s\n", ep)
-			ep.Open()
-			go b.sender(ep)
-		case concurrent.Receiver:
-			util.Debugf("accept receiver %s\n", ep)
-			ep.SetCapacity(100, true) // Pre-fetch 100 messages
-			ep.Open()
-			go b.receiver(ep)
-		}
-	}
-}
-
-// sender pops from a the queue in the sender's Source address and send messages.
-func (b *broker) sender(sender concurrent.Sender) {
-	qname := sender.Settings().Source
-	if qname == "" {
-		log.Printf("invalid consumer, no source address: %s", sender)
-		return
-	}
-	q := b.queues.Get(qname)
-	for {
-		m := <-q.Pop
-		if m == nil {
-			break
-		}
-		if sm, err := sender.Send(m); err == nil {
-			sm.Forget() // FIXME aconway 2015-09-24: Ignore acknowledgements
-			util.Debugf("send %s: %s\n", sender, util.FormatMessage(m))
-		} else {
-			util.Debugf("send error %s: %s\n", sender, err)
-			q.Putback <- m
-			break
-		}
-	}
-}
-
-func (b *broker) receiver(receiver concurrent.Receiver) {
-	qname := receiver.Settings().Target
-	if qname == "" {
-		log.Printf("invalid producer, no target address: %s", receiver)
-		return
-	}
-	q := b.queues.Get(qname)
-	for {
-		if rm, err := receiver.Receive(); err == nil {
-			util.Debugf("recv %s: %s\n", receiver, util.FormatMessage(rm.Message))
-			q.Push <- rm.Message
-			rm.Accept()
-		} else {
-			util.Debugf("recv error %s: %s\n", receiver, err)
-			break
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/electron/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/broker.go b/examples/go/electron/broker.go
new file mode 100644
index 0000000..4b877df
--- /dev/null
+++ b/examples/go/electron/broker.go
@@ -0,0 +1,148 @@
+/*
+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.
+*/
+
+//
+// This is a simple AMQP broker implemented using the procedural electron package.
+//
+// It maintains a set of named in-memory queues of messages. Clients can send
+// messages to queues or subscribe to receive messages from them.
+//
+
+package main
+
+import (
+	"../util"
+	"flag"
+	"fmt"
+	"net"
+	"os"
+	"qpid.apache.org/electron"
+)
+
+// Usage and command-line flags
+func usage() {
+	fmt.Fprintf(os.Stderr, `
+Usage: %s
+A simple broker-like demo. Queues are created automatically for sender or receiver addrsses.
+`, os.Args[0])
+	flag.PrintDefaults()
+}
+
+var addr = flag.String("addr", ":amqp", "Listening address")
+var credit = flag.Int("credit", 100, "Receiver credit window")
+var qsize = flag.Int("qsize", 1000, "Max queue size")
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	b := newBroker()
+	listener, err := net.Listen("tcp", *addr)
+	util.ExitIf(err)
+	defer listener.Close()
+	fmt.Printf("Listening on %s\n", listener.Addr())
+
+	// Loop accepting new connections.
+	for {
+		conn, err := listener.Accept()
+		if err != nil {
+			util.Debugf("Accept error: %s", err)
+			continue
+		}
+		if err := b.connection(conn); err != nil {
+			if err != nil {
+				util.Debugf("Connection error: %s", err)
+				continue
+			}
+		}
+	}
+}
+
+type broker struct {
+	queues    util.Queues
+	container electron.Container
+}
+
+func newBroker() *broker {
+	return &broker{util.MakeQueues(*qsize), electron.NewContainer("")}
+}
+
+// connection creates a new AMQP connection for a net.Conn.
+func (b *broker) connection(conn net.Conn) error {
+	c, err := b.container.Connection(conn)
+	if err != nil {
+		return err
+	}
+	c.Server()         // Enable server-side protocol negotiation.
+	c.Listen(b.accept) // Call accept() for remotely-opened endpoints.
+	if err := c.Open(); err != nil {
+		return err
+	}
+	util.Debugf("Accepted %s", c)
+	return nil
+}
+
+// accept remotely-opened endpoints (Session, Sender and Receiver)
+// and start goroutines to service them.
+func (b *broker) accept(ep electron.Endpoint) error {
+	switch ep := ep.(type) {
+	case electron.Sender:
+		util.Debugf("%s opened", ep)
+		go b.sender(ep)
+	case electron.Receiver:
+		util.Debugf("%s opened", ep)
+		ep.SetCapacity(100, true) // Pre-fetch 100 messages
+		go b.receiver(ep)
+	}
+	return nil
+}
+
+// sender pops messages from a queue and sends them.
+func (b *broker) sender(sender electron.Sender) {
+	q := b.queues.Get(sender.Source())
+	for {
+		m, ok := <-q
+		if !ok { // Queue closed
+			return
+		}
+		if err := sender.SendForget(m); err == nil {
+			util.Debugf("send %s: %s", sender, util.FormatMessage(m))
+		} else {
+			util.Debugf("send error %s: %s", sender, err)
+			q <- m // Put it back on the queue.
+			break
+		}
+	}
+}
+
+// receiver receives messages and pushes to the queue named by the receivers's
+// Target address
+func (b *broker) receiver(receiver electron.Receiver) {
+	q := b.queues.Get(receiver.Target())
+	for {
+		if rm, err := receiver.Receive(); err == nil {
+			util.Debugf("%s: received %s", receiver, util.FormatMessage(rm.Message))
+			q <- rm.Message
+			rm.Accept()
+		} else {
+			util.Debugf("%s: error %s", receiver, err)
+			break
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/electron/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/receive.go b/examples/go/electron/receive.go
new file mode 100644
index 0000000..7639375
--- /dev/null
+++ b/examples/go/electron/receive.go
@@ -0,0 +1,122 @@
+/*
+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 main
+
+import (
+	"../util"
+	"flag"
+	"fmt"
+	"log"
+	"net"
+	"os"
+	"path"
+	"qpid.apache.org/amqp"
+	"qpid.apache.org/electron"
+	"sync"
+)
+
+// Usage and command-line flags
+func usage() {
+	fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
+Receive messages from all the listed URLs concurrently and print them.
+`, os.Args[0])
+	flag.PrintDefaults()
+}
+
+var count = flag.Uint64("count", 1, "Stop after receiving this many messages.")
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	urls := flag.Args() // Non-flag arguments are URLs to receive from
+	if len(urls) == 0 {
+		log.Println("No URL provided")
+		usage()
+		os.Exit(1)
+	}
+
+	messages := make(chan amqp.Message) // Channel for messages from goroutines to main()
+	stop := make(chan struct{})         // Closing this channel means the program is stopping.
+	var wait sync.WaitGroup             // Used by main() to wait for all goroutines to end.
+	wait.Add(len(urls))                 // Wait for one goroutine per URL.
+
+	_, prog := path.Split(os.Args[0])
+	container := electron.NewContainer(fmt.Sprintf("%v:%v", prog, os.Getpid()))
+	connections := make(chan electron.Connection, len(urls)) // Connections to close on exit
+
+	// Start a goroutine to for each URL to receive messages and send them to the messages channel.
+	// main() receives and prints them.
+	for _, urlStr := range urls {
+		util.Debugf("Connecting to %s\n", urlStr)
+		go func(urlStr string) { // Start the goroutine
+
+			defer wait.Done()                 // Notify main() when this goroutine is done.
+			url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
+			util.ExitIf(err)
+
+			// Open a new connection
+			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
+			util.ExitIf(err)
+			c, err := container.Connection(conn)
+			util.ExitIf(err)
+			util.ExitIf(c.Open())
+			connections <- c // Save connection so we can Close() when main() ends
+
+			// Create a Receiver using the path of the URL as the source address
+			r, err := c.Receiver(electron.Source(url.Path))
+			util.ExitIf(err)
+
+			// Loop receiving messages and sending them to the main() goroutine
+			for {
+				rm, err := r.Receive()
+				if err == electron.Closed {
+					return
+				}
+				util.ExitIf(err)
+				select { // Send m to main() or stop
+				case messages <- rm.Message: // Send to main()
+				case <-stop: // The program is stopping.
+					return
+				}
+			}
+		}(urlStr)
+	}
+
+	// All goroutines are started, we are receiving messages.
+	fmt.Printf("Listening on %d connections\n", len(urls))
+
+	// print each message until the count is exceeded.
+	for i := uint64(0); i < *count; i++ {
+		m := <-messages
+		util.Debugf("%s\n", util.FormatMessage(m))
+	}
+	fmt.Printf("Received %d messages\n", *count)
+
+	// Close all connections, this will interrupt goroutines blocked in Receiver.Receive()
+	for i := 0; i < len(urls); i++ {
+		c := <-connections
+		util.Debugf("close %s", c)
+		c.Close(nil)
+	}
+	close(stop) // Signal all goroutines to stop.
+	wait.Wait() // Wait for all goroutines to finish.
+	close(messages)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/electron/send.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/send.go b/examples/go/electron/send.go
new file mode 100644
index 0000000..94a77e7
--- /dev/null
+++ b/examples/go/electron/send.go
@@ -0,0 +1,123 @@
+/*
+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 main
+
+import (
+	"../util"
+	"flag"
+	"fmt"
+	"log"
+	"net"
+	"os"
+	"path"
+	"qpid.apache.org/amqp"
+	"qpid.apache.org/electron"
+	"sync"
+)
+
+// Usage and command-line flags
+func usage() {
+	fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
+Send messages to each URL concurrently with body "<url-path>-<n>" where n is the message number.
+`, os.Args[0])
+	flag.PrintDefaults()
+}
+
+var count = flag.Int64("count", 1, "Send this may messages per address.")
+
+type sent struct {
+	name        string
+	sentMessage electron.SentMessage
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	urls := flag.Args() // Non-flag arguments are URLs to receive from
+	if len(urls) == 0 {
+		log.Println("No URL provided")
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	sentChan := make(chan sent) // Channel to receive all the delivery receipts.
+	var wait sync.WaitGroup     // Used by main() to wait for all goroutines to end.
+	wait.Add(len(urls))         // Wait for one goroutine per URL.
+
+	_, prog := path.Split(os.Args[0])
+	container := electron.NewContainer(fmt.Sprintf("%v:%v", prog, os.Getpid()))
+	var connections []electron.Connection // Store connctions to close on exit
+
+	// Start a goroutine for each URL to send messages.
+	for _, urlStr := range urls {
+		util.Debugf("Connecting to %v\n", urlStr)
+		go func(urlStr string) {
+
+			defer wait.Done()                 // Notify main() that this goroutine is done.
+			url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
+			util.ExitIf(err)
+
+			// Open a new connection
+			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
+			util.ExitIf(err)
+			c, err := container.Connection(conn)
+			util.ExitIf(err)
+			err = c.Open()
+			util.ExitIf(err)
+			connections = append(connections, c) // Save connection so it will be closed when main() ends
+
+			// Create a Sender using the path of the URL as the AMQP address
+			s, err := c.Sender(electron.Target(url.Path))
+			util.ExitIf(err)
+
+			// Loop sending messages.
+			for i := int64(0); i < *count; i++ {
+				m := amqp.NewMessage()
+				body := fmt.Sprintf("%v-%v", url.Path, i)
+				m.Marshal(body)
+				sentMessage, err := s.Send(m)
+				util.ExitIf(err)
+				sentChan <- sent{body, sentMessage}
+			}
+		}(urlStr)
+	}
+
+	// Wait for all the acknowledgements
+	expect := int(*count) * len(urls)
+	util.Debugf("Started senders, expect %v acknowledgements\n", expect)
+	for i := 0; i < expect; i++ {
+		d := <-sentChan
+		disposition, err := d.sentMessage.Disposition()
+		if err != nil {
+			util.Debugf("acknowledgement[%v] %v error: %v\n", i, d.name, err)
+		} else {
+			util.Debugf("acknowledgement[%v]  %v (%v)\n", i, d.name, disposition)
+		}
+	}
+	fmt.Printf("Received all %v acknowledgements\n", expect)
+
+	wait.Wait()                     // Wait for all goroutines to finish.
+	for _, c := range connections { // Close all connections
+		if c != nil {
+			c.Close(nil)
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
index 2afd95c..a4d7d80 100644
--- a/examples/go/example_test.go
+++ b/examples/go/example_test.go
@@ -110,14 +110,14 @@ func checkEqual(want interface{}, got interface{}) error {
 // 'go build' uses the installed copy of the proton Go libraries, which may be out of date.
 func checkStaleLibs(t *testing.T) {
 	var stale []string
-	pp := "qpid.apache.org/proton"
-	for _, p := range []string{pp, pp + "/amqp", pp + "/concurrent"} {
+	pp := "qpid.apache.org"
+	for _, p := range []string{pp + "/proton", pp + "/amqp", pp + "/electron"} {
 		out, err := exec.Command("go", "list", "-f", "{{.Stale}}", p).CombinedOutput()
 		if err != nil {
 			t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))
 		}
 		if string(out) != "false\n" {
-			stale = append(stale, pp)
+			stale = append(stale, p)
 		}
 	}
 	if len(stale) > 0 {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/proton/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/proton/broker.go b/examples/go/proton/broker.go
new file mode 100644
index 0000000..dbb4a82
--- /dev/null
+++ b/examples/go/proton/broker.go
@@ -0,0 +1,299 @@
+/*
+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.
+*/
+
+//
+// This is a simple AMQP broker implemented using the event-driven proton package.
+//
+// It maintains a set of named in-memory queues of messages. Clients can send
+// messages to queues or subscribe to receive messages from them.
+//
+
+package main
+
+import (
+	"../util"
+	"flag"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"qpid.apache.org/amqp"
+	"qpid.apache.org/proton"
+)
+
+// Usage and command-line flags
+func usage() {
+	fmt.Fprintf(os.Stderr, `
+Usage: %s
+A simple broker-like demo. Queues are created automatically for sender or receiver addrsses.
+`, os.Args[0])
+	flag.PrintDefaults()
+}
+
+var addr = flag.String("addr", ":amqp", "Listening address")
+var credit = flag.Int("credit", 100, "Receiver credit window")
+var qsize = flag.Int("qsize", 1000, "Max queue size")
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	b := newBroker()
+	listener, err := net.Listen("tcp", *addr)
+	util.ExitIf(err)
+	defer listener.Close()
+	fmt.Printf("Listening on %s\n", listener.Addr())
+
+	// Loop accepting new connections.
+	for {
+		conn, err := listener.Accept()
+		if err != nil {
+			util.Debugf("Accept error: %s", err)
+			continue
+		}
+		if err := b.connection(conn); err != nil {
+			if err != nil {
+				util.Debugf("Connection error: %s", err)
+				continue
+			}
+		}
+	}
+}
+
+type broker struct {
+	queues util.Queues
+}
+
+func newBroker() *broker {
+	return &broker{util.MakeQueues(*qsize)}
+}
+
+// connection creates a new AMQP connection for a net.Conn.
+func (b *broker) connection(conn net.Conn) error {
+	delegator := proton.NewMessagingDelegator(newHandler(&b.queues, *credit))
+	// We want to accept messages when they are enqueued, not just when they
+	// are received, so we turn off auto-accept and prefetch by the handler.
+	delegator.Prefetch = 0
+	delegator.AutoAccept = false
+	engine, err := proton.NewEngine(conn, delegator)
+	if err != nil {
+		return err
+	}
+	engine.Server() // Enable server-side protocol negotiation.
+	go func() {     // Start goroutine to run the engine event loop
+		engine.Run()
+		util.Debugf("Closed %s", engine)
+	}()
+	util.Debugf("Accepted %s", engine)
+	return nil
+}
+
+// receiver is a channel to buffer messages waiting to go on the queue.
+type receiver chan receivedMessage
+
+// receivedMessage is a message and the corresponding delivery for acknowledgement.
+type receivedMessage struct {
+	delivery proton.Delivery
+	message  amqp.Message
+}
+
+// sender is a signal channel, closed when we are done sending.
+type sender chan struct{}
+
+// handler handles AMQP events. There is one handler per connection.  The
+// handler does not need to be concurrent-safe as proton will serialize all
+// calls to a handler. We will use channels to communicate from the handler
+// to goroutines sending and receiving messages.
+type handler struct {
+	queues    *util.Queues
+	credit    int // Credit window for receiver flow control.
+	receivers map[proton.Link]receiver
+	senders   map[proton.Link]sender
+}
+
+func newHandler(queues *util.Queues, credit int) *handler {
+	return &handler{
+		queues,
+		credit,
+		make(map[proton.Link]receiver),
+		make(map[proton.Link]sender),
+	}
+}
+
+// Handle an AMQP event.
+func (h *handler) HandleMessagingEvent(t proton.MessagingEvent, e proton.Event) {
+	switch t {
+
+	case proton.MLinkOpening:
+		l := e.Link()
+		var err error
+		if l.IsReceiver() {
+			err = h.receiver(l)
+		} else { // IsSender()
+			err = h.sender(l)
+		}
+		if err == nil {
+			util.Debugf("%s opened", l)
+		} else {
+			util.Debugf("%s open error: %s", l, err)
+			proton.CloseError(l, err)
+		}
+
+	case proton.MLinkClosing:
+		l := e.Link()
+		if r, ok := h.receivers[l]; ok {
+			close(r)
+			delete(h.receivers, l)
+		} else if s, ok := h.senders[l]; ok {
+			close(s)
+			delete(h.senders, l)
+		}
+		util.Debugf("%s closed", l)
+
+	case proton.MSendable:
+		l := e.Link()
+		q := h.queues.Get(l.RemoteSource().Address())
+		if n, err := h.sendAll(e.Link(), q); err == nil && n > 0 {
+			// Still have credit, start a watcher.
+			go h.sendWatch(e.Link(), q)
+		}
+
+	case proton.MMessage:
+		l := e.Link()
+		d := e.Delivery()
+		m, err := d.Message() // Must decode message immediately before link state changes.
+		if err != nil {
+			util.Debugf("%s error decoding message: %s", e.Link(), err)
+			proton.CloseError(l, err)
+		} else {
+			// This will not block, AMQP credit prevents us from overflowing the buffer.
+			h.receivers[l] <- receivedMessage{d, m}
+			util.Debugf("%s received %s", l, util.FormatMessage(m))
+		}
+
+	case proton.MConnectionClosing, proton.MDisconnected:
+		for l, r := range h.receivers {
+			close(r)
+			delete(h.receivers, l)
+		}
+		for l, s := range h.senders {
+			close(s)
+			delete(h.senders, l)
+		}
+	}
+}
+
+// receiver is called by the handler when a receiver link opens.
+//
+// It sets up data structures in the handler and then starts a goroutine
+// to receive messages and put them on a queue.
+func (h *handler) receiver(l proton.Link) error {
+	q := h.queues.Get(l.RemoteTarget().Address())
+	buffer := make(receiver, h.credit)
+	h.receivers[l] = buffer
+	l.Flow(cap(buffer)) // credit==cap(buffer) so we won't overflow the buffer.
+	go h.runReceive(l, buffer, q)
+	return nil
+}
+
+// runReceive moves messages from buffer to queue
+func (h *handler) runReceive(l proton.Link, buffer receiver, q util.Queue) {
+	for rm := range buffer {
+		q <- rm.message
+		rm2 := rm // Save in temp var for injected closure
+		err := l.Connection().Injecter().Inject(func() {
+			rm2.delivery.Accept()
+			l.Flow(1)
+		})
+		if err != nil {
+			util.Debugf("%s receive error: %s", l, err)
+			proton.CloseError(l, err)
+		}
+	}
+}
+
+// sender is called by the handler when a sender link opens.
+// It sets up a sender structures in the handler.
+func (h *handler) sender(l proton.Link) error {
+	h.senders[l] = make(sender)
+	return nil
+}
+
+// send one message in handler context, assumes we have credit.
+func (h *handler) send(l proton.Link, m amqp.Message, q util.Queue) error {
+	delivery, err := l.Send(m)
+	if err != nil {
+		h.closeSender(l, err)
+		return err
+	}
+	delivery.Settle() // Pre-settled, unreliable.
+	util.Debugf("%s sent %s", l, util.FormatMessage(m))
+	return nil
+}
+
+// sendAll sends as many messages as possible without blocking, call in handler context.
+// Returns the number of credits left, >0 means we ran out of messages.
+func (h *handler) sendAll(l proton.Link, q util.Queue) (int, error) {
+	for l.Credit() > 0 {
+		select {
+		case m, ok := <-q:
+			if ok { // Got a message
+				if err := h.send(l, m, q); err != nil {
+					return 0, err
+				}
+			} else { // Queue is closed
+				l.Close()
+				return 0, io.EOF
+			}
+		default: // Queue empty
+			return l.Credit(), nil
+		}
+	}
+	return l.Credit(), nil
+}
+
+// sendWatch watches the queue for more messages and re-runs sendAll.
+// Run in a separate goroutine, so must inject handler functions.
+func (h *handler) sendWatch(l proton.Link, q util.Queue) {
+	select {
+	case m, ok := <-q:
+		l.Connection().Injecter().Inject(func() {
+			if ok {
+				if h.send(l, m, q) != nil {
+					return
+				}
+				if n, err := h.sendAll(l, q); err != nil {
+					return
+				} else if n > 0 {
+					go h.sendWatch(l, q) // Start a new watcher.
+				}
+			}
+		})
+	case <-h.senders[l]: // Closed
+		return
+	}
+}
+
+// closeSender closes a sender link and signals goroutines processing that sender.
+func (h *handler) closeSender(l proton.Link, err error) {
+	util.Debugf("%s sender closed: %s", l, err)
+	proton.CloseError(l, err)
+	close(h.senders[l])
+	delete(h.senders, l)
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/receive.go b/examples/go/receive.go
deleted file mode 100644
index 86244d7..0000000
--- a/examples/go/receive.go
+++ /dev/null
@@ -1,119 +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.
-*/
-
-package main
-
-import (
-	"./util"
-	"flag"
-	"fmt"
-	"log"
-	"net"
-	"os"
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/concurrent"
-	"sync"
-)
-
-// Usage and command-line flags
-func usage() {
-	fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
-Receive messages from all the listed URLs concurrently and print them.
-`, os.Args[0])
-	flag.PrintDefaults()
-}
-
-var count = flag.Uint64("count", 1, "Stop after receiving this many messages.")
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-
-	urls := flag.Args() // Non-flag arguments are URLs to receive from
-	if len(urls) == 0 {
-		log.Println("No URL provided")
-		usage()
-		os.Exit(1)
-	}
-
-	messages := make(chan amqp.Message) // Channel for messages from goroutines to main()
-	stop := make(chan struct{})         // Closing this channel means the program is stopping.
-	var wait sync.WaitGroup             // Used by main() to wait for all goroutines to end.
-	wait.Add(len(urls))                 // Wait for one goroutine per URL.
-
-	container := concurrent.NewContainer("")
-	connections := make(chan concurrent.Connection, len(urls)) // Connections to close on exit
-
-	// Start a goroutine to for each URL to receive messages and send them to the messages channel.
-	// main() receives and prints them.
-	for _, urlStr := range urls {
-		util.Debugf("Connecting to %s\n", urlStr)
-		go func(urlStr string) { // Start the goroutine
-
-			defer wait.Done()                 // Notify main() when this goroutine is done.
-			url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
-			util.ExitIf(err)
-
-			// Open a new connection
-			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
-			util.ExitIf(err)
-			c, err := container.Connection(conn)
-			util.ExitIf(err)
-			util.ExitIf(c.Open())
-			connections <- c // Save connection so we can Close() when main() ends
-
-			// Create a Receiver using the path of the URL as the source address
-			r, err := c.Receiver(url.Path)
-			util.ExitIf(err)
-
-			// Loop receiving messages and sending them to the main() goroutine
-			for {
-				rm, err := r.Receive()
-				if err == concurrent.Closed {
-					return
-				}
-				util.ExitIf(err)
-				select { // Send m to main() or stop
-				case messages <- rm.Message: // Send to main()
-				case <-stop: // The program is stopping.
-					return
-				}
-			}
-		}(urlStr)
-	}
-
-	// All goroutines are started, we are receiving messages.
-	fmt.Printf("Listening on %d connections\n", len(urls))
-
-	// print each message until the count is exceeded.
-	for i := uint64(0); i < *count; i++ {
-		m := <-messages
-		util.Debugf("%s\n", util.FormatMessage(m))
-	}
-	fmt.Printf("Received %d messages\n", *count)
-
-	// Close all connections, this will interrupt goroutines blocked in Receiver.Receive()
-	for i := 0; i < len(urls); i++ {
-		c := <-connections
-		c.Disconnect(nil) // FIXME aconway 2015-09-25: Close
-	}
-	close(stop) // Signal all goroutines to stop.
-	wait.Wait() // Wait for all goroutines to finish.
-	close(messages)
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/send.go
----------------------------------------------------------------------
diff --git a/examples/go/send.go b/examples/go/send.go
deleted file mode 100644
index edac2ae..0000000
--- a/examples/go/send.go
+++ /dev/null
@@ -1,121 +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.
-*/
-
-package main
-
-import (
-	"./util"
-	"flag"
-	"fmt"
-	"log"
-	"net"
-	"os"
-	"qpid.apache.org/proton/amqp"
-	"qpid.apache.org/proton/concurrent"
-	"sync"
-)
-
-// Usage and command-line flags
-func usage() {
-	fmt.Fprintf(os.Stderr, `Usage: %s url [url ...]
-Send messages to each URL concurrently with body "<url-path>-<n>" where n is the message number.
-`, os.Args[0])
-	flag.PrintDefaults()
-}
-
-var count = flag.Int64("count", 1, "Send this may messages per address.")
-
-type sent struct {
-	name        string
-	sentMessage concurrent.SentMessage
-}
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-
-	urls := flag.Args() // Non-flag arguments are URLs to receive from
-	if len(urls) == 0 {
-		log.Println("No URL provided")
-		flag.Usage()
-		os.Exit(1)
-	}
-
-	sentChan := make(chan sent) // Channel to receive all the delivery receipts.
-	var wait sync.WaitGroup     // Used by main() to wait for all goroutines to end.
-	wait.Add(len(urls))         // Wait for one goroutine per URL.
-
-	container := concurrent.NewContainer("")
-	var connections []concurrent.Connection // Store connctions to close on exit
-
-	// Start a goroutine for each URL to send messages.
-	for _, urlStr := range urls {
-		util.Debugf("Connecting to %v\n", urlStr)
-		go func(urlStr string) {
-
-			defer wait.Done()                 // Notify main() that this goroutine is done.
-			url, err := amqp.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults.
-			util.ExitIf(err)
-
-			// Open a new connection
-			conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port"
-			util.ExitIf(err)
-			c, err := container.Connection(conn)
-			util.ExitIf(err)
-			err = c.Open()
-			util.ExitIf(err)
-			connections = append(connections, c) // Save connection so it will be closed when main() ends
-
-			// Create a Sender using the path of the URL as the AMQP address
-			s, err := c.Sender(url.Path)
-			util.ExitIf(err)
-
-			// Loop sending messages.
-			for i := int64(0); i < *count; i++ {
-				m := amqp.NewMessage()
-				body := fmt.Sprintf("%v-%v", url.Path, i)
-				m.Marshal(body)
-				sentMessage, err := s.Send(m)
-				util.ExitIf(err)
-				sentChan <- sent{body, sentMessage}
-			}
-		}(urlStr)
-	}
-
-	// Wait for all the acknowledgements
-	expect := int(*count) * len(urls)
-	util.Debugf("Started senders, expect %v acknowledgements\n", expect)
-	for i := 0; i < expect; i++ {
-		d := <-sentChan
-		disposition, err := d.sentMessage.Disposition()
-		if err != nil {
-			util.Debugf("acknowledgement[%v] %v error: %v\n", i, d.name, err)
-		} else {
-			util.Debugf("acknowledgement[%v]  %v (%v)\n", i, d.name, disposition)
-		}
-	}
-	fmt.Printf("Received all %v acknowledgements\n", expect)
-
-	wait.Wait()                     // Wait for all goroutines to finish.
-	for _, c := range connections { // Close all connections
-		if c != nil {
-			c.Close(nil)
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/util/queue.go
----------------------------------------------------------------------
diff --git a/examples/go/util/queue.go b/examples/go/util/queue.go
index 075c4d2..d844c0d 100644
--- a/examples/go/util/queue.go
+++ b/examples/go/util/queue.go
@@ -20,87 +20,32 @@ under the License.
 package util
 
 import (
-	"container/list"
-	"qpid.apache.org/proton/amqp"
+	"qpid.apache.org/amqp"
 	"sync"
 )
 
-// Queue is a concurrent-safe queue of amqp.Message.
-type Queue struct {
-	name     string
-	messages list.List // List of amqp.Message
-	// Send to Push to push a message onto back of queue
-	Push chan amqp.Message
-	// Receive from Pop to pop a message from the front of the queue.
-	Pop chan amqp.Message
-	// Send to Putback to put an unsent message back on the front of the queue.
-	Putback chan amqp.Message
-}
+// Use a buffered channel as a very simple queue.
+type Queue chan amqp.Message
 
-func NewQueue(name string) *Queue {
-	q := &Queue{
-		name:    name,
-		Push:    make(chan amqp.Message),
-		Pop:     make(chan amqp.Message),
-		Putback: make(chan amqp.Message),
-	}
-	go q.run()
-	return q
+// Concurrent-safe map of queues.
+type Queues struct {
+	queueSize int
+	m         map[string]Queue
+	lock      sync.Mutex
 }
 
-// Close the queue. Any remaining messages on Pop can still be received.
-func (q *Queue) Close() { close(q.Push); close(q.Putback) }
-
-// Run runs the queue, returns when q.Close() is called.
-func (q *Queue) run() {
-	defer close(q.Pop)
-	for {
-		var pop chan amqp.Message
-		var front amqp.Message
-		if el := q.messages.Front(); el != nil {
-			front = el.Value.(amqp.Message)
-			pop = q.Pop // Only select for pop if there is something to pop.
-		}
-		select {
-		case m, ok := <-q.Push:
-			if !ok {
-				return
-			}
-			Debugf("%s push: %s\n", q.name, FormatMessage(m))
-			q.messages.PushBack(m)
-		case m, ok := <-q.Putback:
-			Debugf("%s put-back: %s\n", q.name, FormatMessage(m))
-			if !ok {
-				return
-			}
-			q.messages.PushFront(m)
-		case pop <- front:
-			Debugf("%s pop: %s\n", q.name, FormatMessage(front))
-			q.messages.Remove(q.messages.Front())
-		}
-	}
+func MakeQueues(queueSize int) Queues {
+	return Queues{queueSize: queueSize, m: make(map[string]Queue)}
 }
 
-// QueueMap is a concurrent-safe map of queues that creates new queues
-// on demand.
-type QueueMap struct {
-	lock sync.Mutex
-	m    map[string]*Queue
-}
-
-func MakeQueueMap() QueueMap { return QueueMap{m: make(map[string]*Queue)} }
-
-func (qm *QueueMap) Get(name string) *Queue {
-	if name == "" {
-		panic("Attempt to get queue with no name")
-	}
-	qm.lock.Lock()
-	defer qm.lock.Unlock()
-	q := qm.m[name]
+// Create a queue if not found.
+func (qs *Queues) Get(name string) Queue {
+	qs.lock.Lock()
+	defer qs.lock.Unlock()
+	q := qs.m[name]
 	if q == nil {
-		q = NewQueue(name)
-		qm.m[name] = q
-		Debugf("queue %s create", name)
+		q = make(Queue, qs.queueSize)
+		qs.m[name] = q
 	}
 	return q
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/examples/go/util/util.go
----------------------------------------------------------------------
diff --git a/examples/go/util/util.go b/examples/go/util/util.go
index 72c6646..f158386 100644
--- a/examples/go/util/util.go
+++ b/examples/go/util/util.go
@@ -27,7 +27,7 @@ import (
 	"log"
 	"os"
 	"path"
-	"qpid.apache.org/proton/amqp"
+	"qpid.apache.org/amqp"
 )
 
 // Debug flag "-debug" enables debug output with Debugf

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index 0631eae..d24bf2e 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -45,8 +45,8 @@ if (BUILD_GO)
 
   # Install packages in the source tree, go tools aren't friendly otherwise.
   # All build output goes in git-ignored pkg or bin subdirectories.
-  set(qgo "qpid.apache.org/proton")
-  set(packages ${qgo} ${qgo}/amqp ${qgo}/concurrent ${qgo}/internal)
+  set(q "qpid.apache.org")
+  set(packages ${q}/amqp ${q}/internal ${q}/proton ${q}/electron)
   add_custom_target(go-packages ALL
     COMMAND ${GO_INSTALL} ${packages}
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/README.md b/proton-c/bindings/go/README.md
deleted file mode 100644
index 14ccf0f..0000000
--- a/proton-c/bindings/go/README.md
+++ /dev/null
@@ -1,150 +0,0 @@
-# Go binding for proton
-
-This is a a [Go](http://golang.org) binding for proton.
-The API is subject to change but is stabilizing.
-
-Feedback is strongly encouraged:
-
-- Email <pr...@qpid.apache.org>
-- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.
-
-The package documentation is available at: <http://godoc.org/qpid.apache.org/proton>
-
-See the [examples](https://github.com/apache/qpid-proton/blob/master/examples/cpp/README.mdw)
-for working examples and practical instructions on how to get started.
-
-The rest of this page discusses the high-level goals and design issues.
-
-## Goals
-
-The API should
-
-- be idiomatic, unsurprising, and easy to use for Go developers.
-- support client and server development.
-- make simple tasks simple.
-- provide deep access to AMQP protocol when that is required.
-
-There are two types of developer we want to support
-
-1. Go developers using AMQP as a message transport:
-   - Straightforward conversions between Go built-in types and AMQP types.
-   - Easy message exchange via Go channels to support use in goroutines.
-
-2. AMQP-aware developers using Go as an implementation language:
-   - Go types to exactly represent all AMQP types and encoding details.
-   - Full access to detailed AMQP concepts: sessions, links, deliveries etc.
-
-## Status
-
-There are 3 go packages for proton:
-
-- qpid.apache.org/proton/amqp: converts AMQP messages and data types to and from Go data types.
-- qpid.apache.org/proton/concurrent: easy-to-use, concurrent API for clients and servers.
-- qpid.apache.org/proton: full low-level access to the proton engine.
-
-The `amqp` package provides conversions between AMQP and Go data types that are
-used by the other two packages.
-
-The `concurrent` package provides a simple procedural API that can be used with
-goroutines to construct concurrent AMQP clients and servers.
-
-The `proton` package is a concurrency-unsafe, event-driven API. It is a very
-thin wrapper providing almost direct access to the underlying proton C API.
-
-The `concurrent` package will probably be more familiar and convenient to Go
-programmers for most use cases. The `proton` package may be more familiar if
-you have used proton in other languages.
-
-Note the `concurrent` package itself is implemented in terms of the `proton`
-package. It takes care of running concurrency-unsafe `proton` code in dedicated
-goroutines and setting up channels to move data between user and proton
-goroutines safely. It hides all this complexity behind a simple procedural
-interface rather than presenting an event-driven interface.
-
-See the [examples](../../../examples/go/README.md) for a better illustration of the APIs.
-
-### Why two APIs?
-
-Go is a concurrent language and encourages applications to be divided into
-concurrent *goroutines*. It provides traditional locking but it encourages the
-use *channels* to communicate between goroutines without explicit locks:
-
-  "Share memory by communicating, don't communicate by sharing memory"
-
-The idea is that a given value is only operated on by one goroutine at a time,
-but values can easily be passed from one goroutine to another.
-
-Go literature distinguishes between:
-
-- *concurrency*: "keeping track of things that could be done in parallel"
-- *parallelism*: "actually doing things in parallel"
-
-The application expresses concurrency by starting goroutines for potentially
-concurrent tasks. The Go run-times schedule the activity of goroutines onto a
-small number (possibly one) of actual parallel executions.
-
-Even with *no* parallelism, concurrency lets the Go run-times *order* work with
-respect to events like file descriptors being readable/writable, channels having
-data, timers firing etc. Go automatically takes care of switching out goroutines
-that block or sleep so it is normal to write code in terms of blocking calls.
-
-Event-driven programming (such as poll, epoll, select or the `proton` package)
-also channels unpredictably ordered events to actions in one or a small pool of
-execution threads. However this requires a different style of programming:
-"event-driven" or "reactive" programming. Go developers call it "inside-out"
-programming. In an event-driven architecture blocking is a big problem as it
-consumes a scarce thread of execution, so actions that take time to complete
-have to be re-structured in terms of future event delivery.
-
-The promise of Go is that you can express your application in concurrent,
-procedural terms with simple blocking calls and the Go run-times will turn it
-inside-out for you. Write as many goroutines as you want, and let Go interleave
-and schedule them efficiently.
-
-For example: the Go equivalent of listening for connections is a goroutine with
-a simple endless loop that calls a blocking Listen() function and starts a
-goroutine for each new connection. Each connection has its own goroutine that
-deals with just that connection till it closes.
-
-The benefit is that the variables and logic live closer together. Once you're in
-a goroutine, you have everything you need in local variables, and they are
-preserved across blocking calls. There's no need to store details in context
-objects that you have to look up when handling a later event to figure out how
-to continue where you left off.
-
-The `proton` API is important because it is close to the original proton-C
-reactive API and gives you direct access to the underlying library. However it
-is un-Go-like in it's event-driven nature, and it requires care as methods on
-values associated with the same underlying proton engine are not
-concurrent-safe.
-
-The `concurrent` API hides the event-driven details behind a simple blocking API
-that can be safely called from arbitrary goroutines. Under the covers data is
-passed through channels to dedicated goroutines running separate `proton` event
-loops for each connection.
-
-### Design of the concurrent API
-
-Code from the `proton` package runs _only_ in a dedicated goroutine (per
-connection). This makes it safe to use proton C data structures associated with
-that connection.
-
-Code in the `concurrent` package can run in any goroutine, and holds `proton`
-package values with proton object pointers.  To use those values, it "injects" a
-function into the proton goroutine via a special channel. Injected functions
-can use temporary channels to allow the calling code to wait for results. Such
-waiting is only for the local event-loop, not across network calls.
-
-The API exposes blocking calls returning normal error values. The user can write
-simple blocking code or start their own goroutine loops and channels as
-appropriate. Details of our internal channel use and error handling are hidden,
-which simplifies the API and gives us more implementation flexibility.
-
-## New to Go?
-
-If you are new to Go then these are a good place to start:
-
-- [A Tour of Go](http://tour.golang.org)
-- [Effective Go](http://golang.org/doc/effective_go.html)
-
-Then look at the tools and library docs at <http://golang.org> as you need them.
diff --git a/proton-c/bindings/go/README.md b/proton-c/bindings/go/README.md
new file mode 120000
index 0000000..38521ba
--- /dev/null
+++ b/proton-c/bindings/go/README.md
@@ -0,0 +1 @@
+src/qpid.apache.org/README.md
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/README.md
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/README.md b/proton-c/bindings/go/src/qpid.apache.org/README.md
new file mode 100644
index 0000000..b99047d
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/README.md
@@ -0,0 +1,105 @@
+# Qpid Go Libraries for AMQP
+
+These packages provide [Go](http://golang.org) support for sending and receiving AMQP
+messages in client or server applications.
+
+Package documentation is available at: <http://godoc.org/qpid.apache.org/>
+
+See the [examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
+for working examples and practical instructions on how to get started.
+
+Feedback is encouraged at:
+
+- Email <pr...@qpid.apache.org>
+- Create issues <https://issues.apache.org/jira/browse/PROTON>, attach patches to an issue.
+
+## Status
+
+There are 3 go packages for proton:
+
+`qpid.apache.org/electron`:  procedural, concurrent-safe Go library for AMQP messaging.
+A simple procedural API that can easily be used with goroutines and channels to construct
+concurrent AMQP clients and servers.
+
+`qpid.apache.org/proton`: event-driven, concurrent-unsafe Go library for AMQP messaging.
+A simple port into Go of the Proton C library. Its event-driven, single-threaded nature
+may be off-putting for Go programmers, hence the electron API.
+
+`qpid.apache.org/amqp`: converts AMQP messages and data types to and from Go data types.
+Used by both the proton and electron packages to represent AMQP types.
+
+See the
+[examples](https://github.com/apache/qpid-proton/blob/master/examples/go/README.md)
+for an illustration of the APIs, in particular compare `proton/broker.go` and
+`electron/broker.go` which illustrate the different API approaches to the same
+task (a simple broker.)
+
+
+### Why two APIs?
+
+Go is a concurrent language and encourages applications to be divided into
+concurrent *goroutines*. It provides traditional locking but it encourages the
+use *channels* to communicate between goroutines without explicit locks:
+
+  "Share memory by communicating, don't communicate by sharing memory"
+
+The idea is that a given value is only operated on by one goroutine at a time,
+but values can easily be passed from one goroutine to another.
+
+Go literature distinguishes between:
+
+- *concurrency*: "keeping track of things that could be done in parallel"
+- *parallelism*: "actually doing things in parallel"
+
+The application expresses concurrency by starting goroutines for potentially
+concurrent tasks. The Go run-times schedule the activity of goroutines onto a
+small number (possibly one) of actual parallel executions.
+
+Even with *no* parallelism, concurrency lets the Go run-times *order* work with
+respect to events like file descriptors being readable/writable, channels having
+data, timers firing etc. Go automatically takes care of switching out goroutines
+that block or sleep so it is normal to write code in terms of blocking calls.
+
+Event-driven programming (such as poll, epoll, select or the `proton` package)
+also channels unpredictably ordered events to actions in one or a small pool of
+execution threads. However this requires a different style of programming:
+"event-driven" or "reactive" programming. Go developers call it "inside-out"
+programming. In an event-driven architecture blocking is a big problem as it
+consumes a scarce thread of execution, so actions that take time to complete
+have to be re-structured in terms of future event delivery.
+
+The promise of Go is that you can express your application in concurrent,
+procedural terms with simple blocking calls and the Go run-times will turn it
+inside-out for you. Write as many goroutines as you want, and let Go interleave
+and schedule them efficiently.
+
+For example: the Go equivalent of listening for connections is a goroutine with
+a simple endless loop that calls a blocking Listen() function and starts a
+goroutine for each new connection. Each connection has its own goroutine that
+deals with just that connection till it closes.
+
+The benefit is that the variables and logic live closer together. Once you're in
+a goroutine, you have everything you need in local variables, and they are
+preserved across blocking calls. There's no need to store details in context
+objects that you have to look up when handling a later event to figure out how
+to continue where you left off.
+
+The `proton` API is important because it is close to the original proton-C
+reactive API and gives you direct access to the underlying library. However it
+is un-Go-like in it's event-driven nature, and it requires care as methods on
+values associated with the same underlying proton engine are not
+concurrent-safe.
+
+The `electron` API hides the event-driven details behind a simple blocking API
+that can be safely called from arbitrary goroutines. Under the covers data is
+passed through channels to dedicated goroutines running separate `proton` event
+loops for each connection.
+
+## New to Go?
+
+If you are new to Go then these are a good place to start:
+
+- [A Tour of Go](http://tour.golang.org)
+- [Effective Go](http://golang.org/doc/effective_go.html)
+
+Then look at the tools and library docs at <http://golang.org> as you need them.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/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
new file mode 100644
index 0000000..323c344
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/doc.go
@@ -0,0 +1,34 @@
+/*
+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 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.
+
+AMQP is an open standard for inter-operable message exchange, see <http://www.amqp.org/>
+*/
+package amqp
+
+// #cgo LDFLAGS: -lqpid-proton
+import "C"
+
+// This file is just for the package comment.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/error.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/error.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/error.go
new file mode 100644
index 0000000..868dbf3
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/error.go
@@ -0,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 amqp
+
+import (
+	"fmt"
+	"reflect"
+)
+
+// Error is an AMQP error condition. It has a name and a description.
+// It implements the Go error interface so can be returned as an error value.
+//
+// You can pass amqp.Error to methods that pass an error to a remote endpoint,
+// this gives you full control over what the remote endpoint will see.
+//
+// You can also pass any Go error to such functions, the remote peer
+// will see the equivalent of MakeError(error)
+//
+type Error struct{ Name, Description string }
+
+// Error implements the Go error interface for AMQP error errors.
+func (c Error) Error() string { return fmt.Sprintf("proton %s: %s", c.Name, c.Description) }
+
+// Errorf makes a Error with name and formatted description as per fmt.Sprintf
+func Errorf(name, format string, arg ...interface{}) Error {
+	return Error{name, fmt.Sprintf(format, arg...)}
+}
+
+// MakeError makes an AMQP error from a go error using the Go error type as the name
+// and the err.Error() string as the description.
+func MakeError(err error) Error {
+	return Error{reflect.TypeOf(err).Name(), err.Error()}
+}
+
+var (
+	InternalError      = "amqp:internal-error"
+	NotFound           = "amqp:not-found"
+	UnauthorizedAccess = "amqp:unauthorized-access"
+	DecodeError        = "amqp:decode-error"
+	ResourceLimit      = "amqp:resource-limit"
+	NotAllowed         = "amqp:not-allowed"
+	InvalidField       = "amqp:invalid-field"
+	NotImplemented     = "amqp:not-implemented"
+	ResourceLocked     = "amqp:resource-locked"
+	PreerrorFailed     = "amqp:preerror-failed"
+	ResourceDeleted    = "amqp:resource-deleted"
+	IllegalState       = "amqp:illegal-state"
+	FrameSizeTooSmall  = "amqp:frame-size-too-small"
+)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/interop
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/interop b/proton-c/bindings/go/src/qpid.apache.org/amqp/interop
new file mode 120000
index 0000000..ad6fcad
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/interop
@@ -0,0 +1 @@
+../../../../../../tests/interop
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/interop_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/interop_test.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/interop_test.go
new file mode 100644
index 0000000..b36ef64
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/interop_test.go
@@ -0,0 +1,381 @@
+/*
+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 that conversion of Go type to/from AMQP is compatible with other
+// bindings.
+//
+package amqp
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func checkEqual(want interface{}, got interface{}) error {
+	if !reflect.DeepEqual(want, got) {
+		return fmt.Errorf("%#v != %#v", want, got)
+	}
+	return nil
+}
+
+func getReader(name string) (r io.Reader) {
+	r, err := os.Open("interop/" + name + ".amqp")
+	if err != nil {
+		panic(fmt.Errorf("Can't open %#v: %v", name, err))
+	}
+	return
+}
+
+func remaining(d *Decoder) string {
+	remainder, _ := ioutil.ReadAll(io.MultiReader(d.Buffered(), d.reader))
+	return string(remainder)
+}
+
+// checkDecode: want is the expected value, gotPtr is a pointer to a
+// instance of the same type for Decode.
+func checkDecode(d *Decoder, want interface{}, gotPtr interface{}, t *testing.T) {
+
+	if err := d.Decode(gotPtr); err != nil {
+		t.Error("Decode failed", err)
+		return
+	}
+	got := reflect.ValueOf(gotPtr).Elem().Interface()
+	if err := checkEqual(want, got); err != nil {
+		t.Error("Decode bad value:", err)
+		return
+	}
+
+	// Try round trip encoding
+	bytes, err := Marshal(want, nil)
+	if err != nil {
+		t.Error("Marshal failed", err)
+		return
+	}
+	n, err := Unmarshal(bytes, gotPtr)
+	if err != nil {
+		t.Error("Unmarshal failed", err)
+		return
+	}
+	if err := checkEqual(n, len(bytes)); err != nil {
+		t.Error("Bad unmarshal length", err)
+		return
+	}
+	got = reflect.ValueOf(gotPtr).Elem().Interface()
+	if err = checkEqual(want, got); err != nil {
+		t.Error("Bad unmarshal value", err)
+		return
+	}
+}
+
+func TestUnmarshal(t *testing.T) {
+	bytes, err := ioutil.ReadAll(getReader("strings"))
+	if err != nil {
+		t.Error(err)
+	}
+	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
+		var got string
+		n, err := Unmarshal(bytes, &got)
+		if err != nil {
+			t.Error(err)
+		}
+		if want != got {
+			t.Errorf("%#v != %#v", want, got)
+		}
+		bytes = bytes[n:]
+	}
+}
+
+func TestPrimitivesExact(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	// Decoding into exact types
+	var b bool
+	checkDecode(d, true, &b, t)
+	checkDecode(d, false, &b, t)
+	var u8 uint8
+	checkDecode(d, uint8(42), &u8, t)
+	var u16 uint16
+	checkDecode(d, uint16(42), &u16, t)
+	var i16 int16
+	checkDecode(d, int16(-42), &i16, t)
+	var u32 uint32
+	checkDecode(d, uint32(12345), &u32, t)
+	var i32 int32
+	checkDecode(d, int32(-12345), &i32, t)
+	var u64 uint64
+	checkDecode(d, uint64(12345), &u64, t)
+	var i64 int64
+	checkDecode(d, int64(-12345), &i64, t)
+	var f32 float32
+	checkDecode(d, float32(0.125), &f32, t)
+	var f64 float64
+	checkDecode(d, float64(0.125), &f64, t)
+}
+
+func TestPrimitivesCompatible(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	// Decoding into compatible types
+	var b bool
+	var i int
+	var u uint
+	var f float64
+	checkDecode(d, true, &b, t)
+	checkDecode(d, false, &b, t)
+	checkDecode(d, uint(42), &u, t)
+	checkDecode(d, uint(42), &u, t)
+	checkDecode(d, -42, &i, t)
+	checkDecode(d, uint(12345), &u, t)
+	checkDecode(d, -12345, &i, t)
+	checkDecode(d, uint(12345), &u, t)
+	checkDecode(d, -12345, &i, t)
+	checkDecode(d, 0.125, &f, t)
+	checkDecode(d, 0.125, &f, t)
+}
+
+// checkDecodeValue: want is the expected value, decode into a reflect.Value
+func checkDecodeInterface(d *Decoder, want interface{}, t *testing.T) {
+
+	var got, got2 interface{}
+	if err := d.Decode(&got); err != nil {
+		t.Error("Decode failed", err)
+		return
+	}
+	if err := checkEqual(want, got); err != nil {
+		t.Error(err)
+		return
+	}
+	// Try round trip encoding
+	bytes, err := Marshal(got, nil)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	n, err := Unmarshal(bytes, &got2)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if err := checkEqual(n, len(bytes)); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := checkEqual(want, got2); err != nil {
+		t.Error(err)
+		return
+	}
+}
+
+func TestPrimitivesInterface(t *testing.T) {
+	d := NewDecoder(getReader("primitives"))
+	checkDecodeInterface(d, true, t)
+	checkDecodeInterface(d, false, t)
+	checkDecodeInterface(d, uint8(42), t)
+	checkDecodeInterface(d, uint16(42), t)
+	checkDecodeInterface(d, int16(-42), t)
+	checkDecodeInterface(d, uint32(12345), t)
+	checkDecodeInterface(d, int32(-12345), t)
+	checkDecodeInterface(d, uint64(12345), t)
+	checkDecodeInterface(d, int64(-12345), t)
+	checkDecodeInterface(d, float32(0.125), t)
+	checkDecodeInterface(d, float64(0.125), t)
+}
+
+func TestStrings(t *testing.T) {
+	d := NewDecoder(getReader("strings"))
+	// Test decoding as plain Go strings
+	for _, want := range []string{"abc\000defg", "abcdefg", "abcdefg", "", "", ""} {
+		var got string
+		checkDecode(d, want, &got, t)
+	}
+	remains := remaining(d)
+	if remains != "" {
+		t.Errorf("leftover: %s", remains)
+	}
+
+	// Test decoding as specific string types
+	d = NewDecoder(getReader("strings"))
+	var bytes []byte
+	var str, sym string
+	checkDecode(d, []byte("abc\000defg"), &bytes, t)
+	checkDecode(d, "abcdefg", &str, t)
+	checkDecode(d, "abcdefg", &sym, t)
+	checkDecode(d, make([]byte, 0), &bytes, t)
+	checkDecode(d, "", &str, t)
+	checkDecode(d, "", &sym, t)
+	remains = remaining(d)
+	if remains != "" {
+		t.Fatalf("leftover: %s", remains)
+	}
+
+	// Test some error handling
+	d = NewDecoder(getReader("strings"))
+	var s string
+	err := d.Decode(s)
+	if err == nil {
+		t.Fatal("Expected error")
+	}
+	if !strings.Contains(err.Error(), "not a pointer") {
+		t.Error(err)
+	}
+	var i int
+	err = d.Decode(&i)
+	if !strings.Contains(err.Error(), "cannot unmarshal") {
+		t.Error(err)
+	}
+	_, err = Unmarshal([]byte{}, nil)
+	if !strings.Contains(err.Error(), "not enough data") {
+		t.Error(err)
+	}
+	_, err = Unmarshal([]byte("foobar"), nil)
+	if !strings.Contains(err.Error(), "invalid-argument") {
+		t.Error(err)
+	}
+}
+
+func TestEncodeDecode(t *testing.T) {
+	type data struct {
+		s  string
+		i  int
+		u8 uint8
+		b  bool
+		f  float32
+		v  interface{}
+	}
+
+	in := data{"foo", 42, 9, true, 1.234, "thing"}
+
+	buf := bytes.Buffer{}
+	e := NewEncoder(&buf)
+	if err := e.Encode(in.s); err != nil {
+		t.Error(err)
+	}
+	if err := e.Encode(in.i); err != nil {
+		t.Error(err)
+	}
+	if err := e.Encode(in.u8); err != nil {
+		t.Error(err)
+	}
+	if err := e.Encode(in.b); err != nil {
+		t.Error(err)
+	}
+	if err := e.Encode(in.f); err != nil {
+		t.Error(err)
+	}
+	if err := e.Encode(in.v); err != nil {
+		t.Error(err)
+	}
+
+	var out data
+	d := NewDecoder(&buf)
+	if err := d.Decode(&out.s); err != nil {
+		t.Error(err)
+	}
+	if err := d.Decode(&out.i); err != nil {
+		t.Error(err)
+	}
+	if err := d.Decode(&out.u8); err != nil {
+		t.Error(err)
+	}
+	if err := d.Decode(&out.b); err != nil {
+		t.Error(err)
+	}
+	if err := d.Decode(&out.f); err != nil {
+		t.Error(err)
+	}
+	if err := d.Decode(&out.v); err != nil {
+		t.Error(err)
+	}
+
+	if err := checkEqual(in, out); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestMap(t *testing.T) {
+	d := NewDecoder(getReader("maps"))
+
+	// Generic map
+	var m Map
+	checkDecode(d, Map{"one": int32(1), "two": int32(2), "three": int32(3)}, &m, t)
+
+	// Interface as map
+	var i interface{}
+	checkDecode(d, Map{int32(1): "one", int32(2): "two", int32(3): "three"}, &i, t)
+
+	d = NewDecoder(getReader("maps"))
+	// Specific typed map
+	var m2 map[string]int
+	checkDecode(d, map[string]int{"one": 1, "two": 2, "three": 3}, &m2, t)
+
+	// Nested map
+	m = Map{int64(1): "one", "two": int32(2), true: Map{uint8(1): true, uint8(2): false}}
+	bytes, err := Marshal(m, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = Unmarshal(bytes, &i)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = checkEqual(m, i); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestList(t *testing.T) {
+	d := NewDecoder(getReader("lists"))
+	var l List
+	checkDecode(d, List{int32(32), "foo", true}, &l, t)
+	checkDecode(d, List{}, &l, t)
+}
+
+// TODO aconway 2015-09-08: the message.amqp file seems to be incorrectly coded as
+// as an AMQP string *inside* an AMQP binary?? Skip the test for now.
+func TODO_TestMessage(t *testing.T) {
+	bytes, err := ioutil.ReadAll(getReader("message"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	m, err := DecodeMessage(bytes)
+	if err != nil {
+		t.Fatal(err)
+	} else {
+		if err := checkEqual(m.Body(), "hello"); err != nil {
+			t.Error(err)
+		}
+	}
+
+	m2 := NewMessageWith("hello")
+	bytes2, err := m2.Encode(nil)
+	if err != nil {
+		t.Error(err)
+	} else {
+		if err = checkEqual(bytes, bytes2); err != nil {
+			t.Error(err)
+		}
+	}
+}
+
+// TODO aconway 2015-03-13: finish the full interop test

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/478ba4ea/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
new file mode 100644
index 0000000..666b4f6
--- /dev/null
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/marshal.go
@@ -0,0 +1,250 @@
+/*
+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
+
+// #include <proton/codec.h>
+import "C"
+
+import (
+	"io"
+	"qpid.apache.org/internal"
+	"reflect"
+	"unsafe"
+)
+
+func dataError(prefix string, data *C.pn_data_t) error {
+	err := internal.PnError(unsafe.Pointer(C.pn_data_error(data)))
+	if err != nil {
+		err = internal.Errorf("%s: %s", prefix, err.(internal.Error))
+	}
+	return err
+}
+
+/*
+Marshal encodes a Go value as AMQP data in buffer.
+If buffer is nil, or is not large enough, a new buffer  is created.
+
+Returns the buffer used for encoding with len() adjusted to the actual size of data.
+
+Go types are encoded as follows
+
+ +-------------------------------------+--------------------------------------------+
+ |Go type                              |AMQP type                                   |
+ +-------------------------------------+--------------------------------------------+
+ |bool                                 |bool                                        |
+ +-------------------------------------+--------------------------------------------+
+ |int8, int16, int32, int64 (int)      |byte, short, int, long (int or long)        |
+ +-------------------------------------+--------------------------------------------+
+ |uint8, uint16, uint32, uint64 (uint) |ubyte, ushort, uint, ulong (uint or ulong)  |
+ +-------------------------------------+--------------------------------------------+
+ |float32, float64                     |float, double.                              |
+ +-------------------------------------+--------------------------------------------+
+ |string                               |string                                      |
+ +-------------------------------------+--------------------------------------------+
+ |[]byte, Binary                       |binary                                      |
+ +-------------------------------------+--------------------------------------------+
+ |Symbol                               |symbol                                      |
+ +-------------------------------------+--------------------------------------------+
+ |interface{}                          |the contained type                          |
+ +-------------------------------------+--------------------------------------------+
+ |nil                                  |null                                        |
+ +-------------------------------------+--------------------------------------------+
+ |map[K]T                              |map with K and T converted as above         |
+ +-------------------------------------+--------------------------------------------+
+ |Map                                  |map, may have mixed types for keys, values  |
+ +-------------------------------------+--------------------------------------------+
+ |[]T                                  |list with T converted as above              |
+ +-------------------------------------+--------------------------------------------+
+ |List                                 |list, may have mixed types  values          |
+ +-------------------------------------+--------------------------------------------+
+
+The following Go types cannot be marshaled: uintptr, function, interface, channel
+
+TODO
+
+Go types: array, slice, struct, complex64/128.
+
+AMQP types: decimal32/64/128, char, timestamp, uuid, array, multi-section message bodies.
+
+Described types.
+
+*/
+func Marshal(v interface{}, buffer []byte) (outbuf []byte, err error) {
+	defer doRecover(&err)
+	data := C.pn_data(0)
+	defer C.pn_data_free(data)
+	marshal(v, data)
+	encode := func(buf []byte) ([]byte, error) {
+		n := int(C.pn_data_encode(data, cPtr(buf), cLen(buf)))
+		switch {
+		case n == int(C.PN_OVERFLOW):
+			return buf, overflow
+		case n < 0:
+			return buf, dataError("marshal error", data)
+		default:
+			return buf[:n], nil
+		}
+	}
+	return encodeGrow(buffer, encode)
+}
+
+const minEncode = 256
+
+// overflow is returned when an encoding function can't fit data in the buffer.
+var overflow = internal.Errorf("buffer too small")
+
+// encodeFn encodes into buffer[0:len(buffer)].
+// Returns buffer with length adjusted for data encoded.
+// If buffer too small, returns overflow as error.
+type encodeFn func(buffer []byte) ([]byte, error)
+
+// encodeGrow calls encode() into buffer, if it returns overflow grows the buffer.
+// Returns the final buffer.
+func encodeGrow(buffer []byte, encode encodeFn) ([]byte, error) {
+	if buffer == nil || len(buffer) == 0 {
+		buffer = make([]byte, minEncode)
+	}
+	var err error
+	for buffer, err = encode(buffer); err == overflow; buffer, err = encode(buffer) {
+		buffer = make([]byte, 2*len(buffer))
+	}
+	return buffer, err
+}
+
+func marshal(v interface{}, data *C.pn_data_t) {
+	switch v := v.(type) {
+	case nil:
+		C.pn_data_put_null(data)
+	case bool:
+		C.pn_data_put_bool(data, C.bool(v))
+	case int8:
+		C.pn_data_put_byte(data, C.int8_t(v))
+	case int16:
+		C.pn_data_put_short(data, C.int16_t(v))
+	case int32:
+		C.pn_data_put_int(data, C.int32_t(v))
+	case int64:
+		C.pn_data_put_long(data, C.int64_t(v))
+	case int:
+		if unsafe.Sizeof(0) == 8 {
+			C.pn_data_put_long(data, C.int64_t(v))
+		} else {
+			C.pn_data_put_int(data, C.int32_t(v))
+		}
+	case uint8:
+		C.pn_data_put_ubyte(data, C.uint8_t(v))
+	case uint16:
+		C.pn_data_put_ushort(data, C.uint16_t(v))
+	case uint32:
+		C.pn_data_put_uint(data, C.uint32_t(v))
+	case uint64:
+		C.pn_data_put_ulong(data, C.uint64_t(v))
+	case uint:
+		if unsafe.Sizeof(0) == 8 {
+			C.pn_data_put_ulong(data, C.uint64_t(v))
+		} else {
+			C.pn_data_put_uint(data, C.uint32_t(v))
+		}
+	case float32:
+		C.pn_data_put_float(data, C.float(v))
+	case float64:
+		C.pn_data_put_double(data, C.double(v))
+	case string:
+		C.pn_data_put_string(data, pnBytes([]byte(v)))
+	case []byte:
+		C.pn_data_put_binary(data, pnBytes(v))
+	case Binary:
+		C.pn_data_put_binary(data, pnBytes([]byte(v)))
+	case Symbol:
+		C.pn_data_put_symbol(data, pnBytes([]byte(v)))
+	case Map: // Special map type
+		C.pn_data_put_map(data)
+		C.pn_data_enter(data)
+		for key, val := range v {
+			marshal(key, data)
+			marshal(val, data)
+		}
+		C.pn_data_exit(data)
+	default:
+		switch reflect.TypeOf(v).Kind() {
+		case reflect.Map:
+			putMap(data, v)
+		case reflect.Slice:
+			putList(data, v)
+		default:
+			panic(internal.Errorf("cannot marshal %s to AMQP", reflect.TypeOf(v)))
+		}
+	}
+	err := dataError("marshal", data)
+	if err != nil {
+		panic(err)
+	}
+	return
+}
+
+func clearMarshal(v interface{}, data *C.pn_data_t) {
+	C.pn_data_clear(data)
+	marshal(v, data)
+}
+
+func putMap(data *C.pn_data_t, v interface{}) {
+	mapValue := reflect.ValueOf(v)
+	C.pn_data_put_map(data)
+	C.pn_data_enter(data)
+	for _, key := range mapValue.MapKeys() {
+		marshal(key.Interface(), data)
+		marshal(mapValue.MapIndex(key).Interface(), data)
+	}
+	C.pn_data_exit(data)
+}
+
+func putList(data *C.pn_data_t, v interface{}) {
+	listValue := reflect.ValueOf(v)
+	C.pn_data_put_list(data)
+	C.pn_data_enter(data)
+	for i := 0; i < listValue.Len(); i++ {
+		marshal(listValue.Index(i).Interface(), data)
+	}
+	C.pn_data_exit(data)
+}
+
+// Encoder encodes AMQP values to an io.Writer
+type Encoder struct {
+	writer io.Writer
+	buffer []byte
+}
+
+// New encoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{w, make([]byte, minEncode)}
+}
+
+func (e *Encoder) Encode(v interface{}) (err error) {
+	e.buffer, err = Marshal(v, e.buffer)
+	if err == nil {
+		e.writer.Write(e.buffer)
+	}
+	return err
+}
+
+func replace(data *C.pn_data_t, v interface{}) {
+	C.pn_data_clear(data)
+	marshal(v, data)
+}


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


[13/50] [abbrv] qpid-proton git commit: PROTON-997: Peel HandlerExceptions if they contain a python exception

Posted by ac...@apache.org.
PROTON-997: Peel HandlerExceptions if they contain a python exception

fixup for commit a82681a4 that was a bit too eager


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

Branch: refs/heads/go1
Commit: f6444b2a10550485c363a5bfcd3f5fc1c11f3e22
Parents: 6091e9e
Author: Bozo Dragojevic <bo...@digiverse.si>
Authored: Thu Oct 8 17:40:28 2015 +0200
Committer: Bozo Dragojevic <bo...@digiverse.si>
Committed: Thu Oct 8 17:54:24 2015 +0200

----------------------------------------------------------------------
 proton-j/src/main/resources/creactor.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/f6444b2a/proton-j/src/main/resources/creactor.py
----------------------------------------------------------------------
diff --git a/proton-j/src/main/resources/creactor.py b/proton-j/src/main/resources/creactor.py
index 51f7cdc..95fd020 100644
--- a/proton-j/src/main/resources/creactor.py
+++ b/proton-j/src/main/resources/creactor.py
@@ -68,9 +68,7 @@ def peel_handler_exception(meth):
         return meth()
     except HandlerException, he:
         cause = he.cause
-        if hasattr(cause, "value"):
-            cause = cause.value
-        t = type(cause)
+        t = getattr(cause, "type", cause.__class__)
         info = sys.exc_info()
         _compat.raise_(t, cause, info[2]) 
 


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


[28/50] [abbrv] qpid-proton git commit: NO-JIRA: give the example connections a container-id

Posted by ac...@apache.org.
NO-JIRA: give the example connections a container-id


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

Branch: refs/heads/go1
Commit: 2057d0397618fb1d68dd973026a01b13e143cc9b
Parents: 6f977fa
Author: Robert Gemmell <ro...@apache.org>
Authored: Fri Oct 16 15:39:23 2015 +0100
Committer: Robert Gemmell <ro...@apache.org>
Committed: Fri Oct 16 15:39:23 2015 +0100

----------------------------------------------------------------------
 .../java/src/main/java/org/apache/qpid/proton/examples/Drain.java | 1 -
 .../src/main/java/org/apache/qpid/proton/examples/Driver.java     | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2057d039/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Drain.java
----------------------------------------------------------------------
diff --git a/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Drain.java b/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Drain.java
index 0bdc76f..8b93886 100644
--- a/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Drain.java
+++ b/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Drain.java
@@ -25,7 +25,6 @@ import java.util.List;
 
 import org.apache.qpid.proton.engine.BaseHandler;
 import org.apache.qpid.proton.engine.Collector;
-import org.apache.qpid.proton.engine.Connection;
 import org.apache.qpid.proton.engine.Delivery;
 import org.apache.qpid.proton.engine.Event;
 import org.apache.qpid.proton.engine.Link;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2057d039/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Driver.java
----------------------------------------------------------------------
diff --git a/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Driver.java b/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Driver.java
index 8b4bcf0..7412dc6 100644
--- a/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Driver.java
+++ b/examples/engine/java/src/main/java/org/apache/qpid/proton/examples/Driver.java
@@ -38,6 +38,7 @@ import java.nio.channels.Selector;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
+import java.util.UUID;
 
 
 /**
@@ -111,6 +112,8 @@ public class Driver extends BaseHandler
     public void onConnectionLocalOpen(Event evt) {
         Connection conn = evt.getConnection();
         if (conn.getRemoteState() == EndpointState.UNINITIALIZED) {
+            // Give the connection a [random] container-id
+            conn.setContainer(UUID.randomUUID().toString());
             try {
                 new Connector(conn);
             } catch (IOException e) {


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


[35/50] [abbrv] qpid-proton git commit: NO-JIRA: c++: replace head/next pointer chasing with C++ begin(), end() ranges.

Posted by ac...@apache.org.
NO-JIRA: c++: replace head/next pointer chasing with C++ begin(), end() ranges.


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

Branch: refs/heads/go1
Commit: e547d134e53b7ec5510b514727ae59d45ffd76e4
Parents: 4e9afbb
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 20 10:34:31 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 20 10:34:31 2015 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp                         |  5 +-
 .../bindings/cpp/include/proton/connection.hpp  | 10 +--
 .../bindings/cpp/include/proton/endpoint.hpp    | 68 +++++++++++++++++++-
 proton-c/bindings/cpp/include/proton/link.hpp   |  8 +--
 .../bindings/cpp/include/proton/session.hpp     |  3 +
 proton-c/bindings/cpp/src/connection.cpp        |  9 ++-
 proton-c/bindings/cpp/src/endpoint.cpp          | 17 ++++-
 proton-c/bindings/cpp/src/link.cpp              |  4 +-
 proton-c/bindings/cpp/src/messaging_adapter.cpp |  3 +-
 proton-c/bindings/cpp/src/session.cpp           | 10 +++
 10 files changed, 115 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index c37f45c..080bc9c 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -173,12 +173,11 @@ class broker : public proton::messaging_handler {
     }
 
     void remove_stale_consumers(proton::connection &connection) {
-        proton::link *l = connection.link_head(proton::endpoint::REMOTE_ACTIVE);
-        while (l) {
+        proton::link_range r = connection.find_links(proton::endpoint::REMOTE_ACTIVE);
+        for (proton::link_iterator l = r.begin(); l != r.end(); ++l) {
             if (l->sender()) {
                 unsubscribe(*l->sender());
             }
-            l = l->next(proton::endpoint::REMOTE_ACTIVE);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/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 2732802..c7ce447 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -66,11 +66,11 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
     /** Create a receiver on default_session() with target=addr and optional handler h */
     PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
-    /** Get the first link on this connection matching the state mask.
-     * Return 0 if none. Don't delete returned pointer.
-     * @see link::next, endpoint::state
-     */
-    PN_CPP_EXTERN link* link_head(endpoint::state mask);
+    /** Return links on this connection matching the state mask. */
+    PN_CPP_EXTERN link_range find_links(endpoint::state mask);
+
+    /** Return sessions on this connection matching the state mask. */
+    PN_CPP_EXTERN session_range find_sessions(endpoint::state mask);
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/include/proton/endpoint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp
index 51560e0..9fb5368 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -29,6 +29,8 @@ namespace proton {
 class handler;
 class connection;
 class transport;
+class session;
+class link;
 
 /** endpoint is a base class for session, connection and link */
 class endpoint
@@ -42,7 +44,7 @@ class endpoint
      * then a match occurs if any of the local or remote flags are set
      * respectively.
      *
-     * @see connection::link_head, connection::session_head, link::next, session::next
+     * @see connection::links, connection::sessions
      */
     typedef int state;
 
@@ -55,12 +57,72 @@ class endpoint
     PN_CPP_EXTERN static const int REMOTE_CLOSED;   ///< Remote endpoint has been closed
     PN_CPP_EXTERN static const int LOCAL_MASK;      ///< Mask including all LOCAL_ bits (UNINIT, ACTIVE, CLOSED)
     PN_CPP_EXTERN static const int REMOTE_MASK;     ///< Mask including all REMOTE_ bits (UNINIT, ACTIVE, CLOSED)
-     ///@}
+    ///@}
 
     // TODO: condition, remote_condition, update_condition, get/handler
+
+};
+
+///@cond INTERNAL
+template <class T, class D> class iter_base {
+  public:
+    typedef T value_type;
+
+    T& operator*() const { return *ptr_; }
+    T* operator->() const { return ptr_; }
+    operator bool() const { return ptr_; }
+    bool operator !() const { return !ptr_; }
+    iter_base<T, D>& operator++() { static_cast<D*>(this)->advance(); return *this; }
+    iter_base<T, D>& operator++(int) { iter_base<T, D> x(*this); ++(*this); return x; }
+    bool operator==(const iter_base<T, D>& x) const { return ptr_ == x.ptr_; }
+    bool operator!=(const iter_base<T, D>& x) const { return ptr_ != x.ptr_; }
+
+  protected:
+    explicit iter_base(T* p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
+    T* ptr_;
+    endpoint::state state_;
+};
+
+template<class I> class range {
+  public:
+    typedef I iterator;
+
+    explicit range(I begin = I(), I end = I()) : begin_(begin), end_(end) {}
+    I begin() const { return begin_; }
+    I end() const { return end_; }
+  private:
+    I begin_, end_;
+};
+///@endcond INTERNAL
+
+///@ An iterator for a range of sessions.
+class session_iterator : public iter_base<session, session_iterator> {
+ public:
+    explicit session_iterator(session* p = 0, endpoint::state s = 0) : iter_base(p, s) {}
+  private:
+    PN_CPP_EXTERN void advance();
+  friend class iter_base<session, session_iterator>;
+};
+
+///@ A range of sessions.
+typedef range<session_iterator> session_range;
+
+///@ An iterator for a range of links.
+class link_iterator : public iter_base<link, link_iterator> {
+  public:
+    explicit link_iterator(link* p = 0, endpoint::state s = 0) :
+        iter_base(p, s), session_(0) {}
+    explicit link_iterator(const link_iterator& i, session *ssn) :
+        iter_base(i.ptr_, i.state_), session_(ssn) {}
+  private:
+    PN_CPP_EXTERN void advance();
+    session* session_;
+  friend class iter_base<link, link_iterator>;
 };
 
+///@ A range of links.
+typedef range<link_iterator> link_range;
 
 }
 
-#endif  /*!PROTON_CPP_ENDPOINT_H*/
+#endif  /*!PROTON_CPP_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/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 8146f33..4e502e1 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -77,14 +77,12 @@ class link : public counted_facade<pn_link_t, link, endpoint>
     /** Link name */
     PN_CPP_EXTERN std::string name();
 
-    /** Next link that matches state mask. @see endpoint::state.
-     * @return 0 if none, do not delete returned pointer
-     */
-    PN_CPP_EXTERN link* next(endpoint::state mask);
-
     /** Connection that owns this link */
     PN_CPP_EXTERN class connection &connection();
 
+    /** Session that owns this link */
+    PN_CPP_EXTERN class session &session();
+
     /** Set a custom handler for this link. */
     PN_CPP_EXTERN void handler(class handler &);
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/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 7fe3e8d..b3dc446 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -76,6 +76,9 @@ class session : public counted_facade<pn_session_t, session, endpoint>
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state();
+
+    /** Return the links on this session matching the state mask. */
+    PN_CPP_EXTERN link_range find_links(endpoint::state mask);
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp
index 8f27a01..19657fd 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -53,8 +53,13 @@ container& connection::container() {
     return container_context(pn_object_reactor(pn_cast(this)));
 }
 
-link* connection::link_head(endpoint::state mask) {
-    return link::cast(pn_link_head(pn_cast(this), mask));
+link_range connection::find_links(endpoint::state mask)  {
+    return link_range(link_iterator(link::cast(pn_link_head(pn_cast(this), mask))));
+}
+
+session_range connection::find_sessions(endpoint::state mask) {
+    return session_range(
+        session_iterator(session::cast(pn_session_head(pn_cast(this), mask))));
 }
 
 session& connection::open_session() { return *session::cast(pn_session(pn_cast(this))); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/endpoint.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/endpoint.cpp b/proton-c/bindings/cpp/src/endpoint.cpp
index ed14937..7f65054 100644
--- a/proton-c/bindings/cpp/src/endpoint.cpp
+++ b/proton-c/bindings/cpp/src/endpoint.cpp
@@ -19,10 +19,15 @@
  *
  */
 
-#include "proton/endpoint.hpp"
 #include "proton/connection.hpp"
+#include "proton/endpoint.hpp"
+#include "proton/session.hpp"
+#include "proton/link.hpp"
 #include "proton/transport.hpp"
+
 #include "proton/connection.h"
+#include "proton/session.h"
+#include "proton/link.h"
 
 namespace proton {
 
@@ -35,4 +40,14 @@ const int endpoint::REMOTE_CLOSED = PN_REMOTE_CLOSED;
 const int endpoint::LOCAL_MASK = PN_LOCAL_MASK;
 const int endpoint::REMOTE_MASK = PN_REMOTE_MASK;
 
+void session_iterator::advance() {
+    ptr_ = session::cast(pn_session_next(pn_cast(ptr_), (pn_state_t) state_));
+}
+
+void link_iterator::advance() {
+    do {
+        ptr_ = link::cast(pn_link_next(pn_cast(ptr_), (pn_state_t) state_));
+    } while (session_ && &ptr_->session() != session_);
+}
+
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp
index 8afad6d..45c23aa 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -67,8 +67,8 @@ class connection &link::connection() {
     return *connection::cast(pn_session_connection(pn_link_session(pn_cast(this))));
 }
 
-link* link::next(endpoint::state mask) {
-    return link::cast(pn_link_next(pn_cast(this), (pn_state_t) mask));
+class session &link::session() {
+    return *session::cast(pn_link_session(pn_cast(this)));
 }
 
 void link::handler(class handler &h) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/messaging_adapter.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp
index 7235244..f155a8d 100644
--- a/proton-c/bindings/cpp/src/messaging_adapter.cpp
+++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp
@@ -76,7 +76,8 @@ void messaging_adapter::on_delivery(event &e) {
                 messaging_event mevent(messaging_event::MESSAGE, *pe);
                 pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk));
                 struct connection_context& ctx = connection_context::get(pnc);
-                // Reusable per-connection message.  Avoid expensive heap malloc/free overhead.
+                // Reusable per-connection message.
+                // Avoid expensive heap malloc/free overhead.
                 // See PROTON-998
                 class message &msg(ctx.event_message);
                 mevent.message_ = &msg;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e547d134/proton-c/bindings/cpp/src/session.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/session.cpp b/proton-c/bindings/cpp/src/session.cpp
index fd5df6f..468e4b8 100644
--- a/proton-c/bindings/cpp/src/session.cpp
+++ b/proton-c/bindings/cpp/src/session.cpp
@@ -75,4 +75,14 @@ receiver& session::open_receiver(const std::string &addr, bool dynamic, handler
 }
 
 endpoint::state session::state() { return pn_session_state(pn_cast(this)); }
+
+link_range session::find_links(endpoint::state mask)  {
+    link_range r(connection().find_links(mask));
+    link_iterator i(r.begin(), this);
+    if (i && this != &i->session())
+        ++i;
+    return link_range(i);
 }
+
+} // namespace proton
+


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


[16/50] [abbrv] qpid-proton git commit: NO-JIRA: c++ binding: remove incorrect messaging_handler events.

Posted by ac...@apache.org.
NO-JIRA: c++ binding: remove incorrect messaging_handler events.

Removed on_abort, on_commit, on_fetch and on_quit. They are not messaging events,
they are example application events from the python tx_recv_interactive example that
were mistakenly added to the handler.


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

Branch: refs/heads/go1
Commit: 8112f5f09515d611c1bea9bce8256516cb5845e9
Parents: 4f6d9fb
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 9 07:32:52 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 9 07:42:44 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/include/proton/messaging_handler.hpp | 4 ----
 proton-c/bindings/cpp/src/messaging_handler.cpp            | 4 ----
 2 files changed, 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8112f5f0/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 af5d78b..e19739e 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
@@ -51,16 +51,13 @@ class messaging_handler : public proton_handler
 
     ///@name Over-ride these member functions to handle events
     ///@{
-    PN_CPP_EXTERN virtual void on_abort(event &e);
     PN_CPP_EXTERN virtual void on_accepted(event &e);
-    PN_CPP_EXTERN virtual void on_commit(event &e);
     PN_CPP_EXTERN virtual void on_connection_closed(event &e);
     PN_CPP_EXTERN virtual void on_connection_closing(event &e);
     PN_CPP_EXTERN virtual void on_connection_error(event &e);
     PN_CPP_EXTERN virtual void on_connection_opening(event &e);
     PN_CPP_EXTERN virtual void on_connection_opened(event &e);
     PN_CPP_EXTERN virtual void on_disconnected(event &e);
-    PN_CPP_EXTERN virtual void on_fetch(event &e);
     PN_CPP_EXTERN virtual void on_id_loaded(event &e);
     PN_CPP_EXTERN virtual void on_link_closed(event &e);
     PN_CPP_EXTERN virtual void on_link_closing(event &e);
@@ -68,7 +65,6 @@ class messaging_handler : public proton_handler
     PN_CPP_EXTERN virtual void on_link_opened(event &e);
     PN_CPP_EXTERN virtual void on_link_opening(event &e);
     PN_CPP_EXTERN virtual void on_message(event &e);
-    PN_CPP_EXTERN virtual void on_quit(event &e);
     PN_CPP_EXTERN virtual void on_record_inserted(event &e);
     PN_CPP_EXTERN virtual void on_records_loaded(event &e);
     PN_CPP_EXTERN virtual void on_rejected(event &e);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/8112f5f0/proton-c/bindings/cpp/src/messaging_handler.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_handler.cpp b/proton-c/bindings/cpp/src/messaging_handler.cpp
index d8b0262..cd580f4 100644
--- a/proton-c/bindings/cpp/src/messaging_handler.cpp
+++ b/proton-c/bindings/cpp/src/messaging_handler.cpp
@@ -81,16 +81,13 @@ void messaging_handler::create_helpers() {
 
 messaging_handler::~messaging_handler(){}
 
-void messaging_handler::on_abort(event &e) { on_unhandled(e); }
 void messaging_handler::on_accepted(event &e) { on_unhandled(e); }
-void messaging_handler::on_commit(event &e) { on_unhandled(e); }
 void messaging_handler::on_connection_closed(event &e) { on_unhandled(e); }
 void messaging_handler::on_connection_closing(event &e) { on_unhandled(e); }
 void messaging_handler::on_connection_error(event &e) { on_unhandled(e); }
 void messaging_handler::on_connection_opened(event &e) { on_unhandled(e); }
 void messaging_handler::on_connection_opening(event &e) { on_unhandled(e); }
 void messaging_handler::on_disconnected(event &e) { on_unhandled(e); }
-void messaging_handler::on_fetch(event &e) { on_unhandled(e); }
 void messaging_handler::on_id_loaded(event &e) { on_unhandled(e); }
 void messaging_handler::on_link_closed(event &e) { on_unhandled(e); }
 void messaging_handler::on_link_closing(event &e) { on_unhandled(e); }
@@ -98,7 +95,6 @@ void messaging_handler::on_link_error(event &e) { on_unhandled(e); }
 void messaging_handler::on_link_opened(event &e) { on_unhandled(e); }
 void messaging_handler::on_link_opening(event &e) { on_unhandled(e); }
 void messaging_handler::on_message(event &e) { on_unhandled(e); }
-void messaging_handler::on_quit(event &e) { on_unhandled(e); }
 void messaging_handler::on_record_inserted(event &e) { on_unhandled(e); }
 void messaging_handler::on_records_loaded(event &e) { on_unhandled(e); }
 void messaging_handler::on_rejected(event &e) { on_unhandled(e); }


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


[15/50] [abbrv] qpid-proton git commit: PROTON-1017: Add a (ignored) test

Posted by ac...@apache.org.
PROTON-1017: Add a (ignored) 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/4f6d9fb5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/4f6d9fb5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/4f6d9fb5

Branch: refs/heads/go1
Commit: 4f6d9fb5345c24b8d4f4dd5a1d79c0f8e0fb79c8
Parents: f6444b2
Author: Bozo Dragojevic <bo...@digiverse.si>
Authored: Fri Oct 9 09:26:51 2015 +0200
Committer: Bozo Dragojevic <bo...@digiverse.si>
Committed: Fri Oct 9 09:29:37 2015 +0200

----------------------------------------------------------------------
 .../systemtests/ProtonEngineExampleTest.java    | 75 ++++++++++++++++++++
 1 file changed, 75 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4f6d9fb5/proton-j/src/test/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
----------------------------------------------------------------------
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java b/proton-j/src/test/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
index a24bbdd..21a9210 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/systemtests/ProtonEngineExampleTest.java
@@ -43,6 +43,7 @@ import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
 import org.apache.qpid.proton.engine.Delivery;
 import org.apache.qpid.proton.engine.Receiver;
 import org.apache.qpid.proton.message.Message;
+import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -303,6 +304,80 @@ public class ProtonEngineExampleTest extends EngineTestBase
         LOGGER.fine(bold("======== Done!"));
     }
 
+    @Ignore("This test does not have a fix yet")
+    @Test
+    public void testPROTON_1017() throws Exception
+    {
+        LOGGER.fine(bold("======== About to create transports"));
+
+        getClient().transport = Proton.transport();
+        ProtocolTracerEnabler.setProtocolTracer(getClient().transport, TestLoggingHelper.CLIENT_PREFIX);
+
+        getServer().transport = Proton.transport();
+        ProtocolTracerEnabler.setProtocolTracer(getServer().transport, "            " + TestLoggingHelper.SERVER_PREFIX);
+
+        doOutputInputCycle();
+
+        getClient().connection = Proton.connection();
+        getClient().transport.bind(getClient().connection);
+
+        getServer().connection = Proton.connection();
+        getServer().transport.bind(getServer().connection);
+
+
+
+        LOGGER.fine(bold("======== About to open connections"));
+        getClient().connection.open();
+        getServer().connection.open();
+
+        doOutputInputCycle();
+
+
+
+        LOGGER.fine(bold("======== About to open and close client session"));
+        getClient().session = getClient().connection.session();
+        getClient().session.open();
+        getClient().session.close();
+        pumpClientToServer();
+
+        getServer().session = getServer().connection.sessionHead(of(UNINITIALIZED), of(CLOSED));
+        assertEndpointState(getServer().session, UNINITIALIZED, CLOSED);
+
+        getServer().session.open();
+        assertEndpointState(getServer().session, ACTIVE, CLOSED);
+
+        getServer().session.close();
+        assertEndpointState(getServer().session, CLOSED, CLOSED);
+
+        pumpServerToClient();
+        assertEndpointState(getClient().session, CLOSED, CLOSED);
+
+
+        LOGGER.fine(bold("======== About to close client's connection"));
+
+        getClient().connection.close();
+
+        pumpClientToServer();
+
+
+        LOGGER.fine(bold("======== Server about to process client's connection closure"));
+
+        assertEquals(CLOSED, getServer().connection.getRemoteState());
+        getServer().connection.close();
+
+        pumpServerToClient();
+
+
+        LOGGER.fine(bold("======== Checking client has nothing more to pump"));
+
+
+        assertClientHasNothingToOutput();
+
+        LOGGER.fine(bold("======== Done!"));
+    }
+
+
+
     /**
      * Simulates creating a local terminus using the properties supplied by the remote link endpoint.
      *


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


[21/50] [abbrv] qpid-proton git commit: NO-JIRA: Fix go code to work under gccgo as well as golang go.

Posted by ac...@apache.org.
NO-JIRA: Fix go code to work under gccgo as well as golang go.

Problem with -race detection under gccgo, disabled.
Go test current directory: golang does not change directory, gccgo changes to test directory.
Fix enum type mismatch seen in Travis builds.
Added go version message to CMake configuration to help with future issues.

Also fixed a race condition in the 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/40630b6c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/40630b6c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/40630b6c

Branch: refs/heads/go1
Commit: 40630b6c7bee7e720541f49c2d4c6b0f9e7a02a9
Parents: 6859fa3
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Oct 8 14:42:44 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 12 16:01:33 2015 -0400

----------------------------------------------------------------------
 examples/go/CMakeLists.txt                      |  7 +-
 examples/go/electron/broker.go                  |  2 +-
 examples/go/electron/receive.go                 | 28 +++----
 examples/go/electron/send.go                    | 11 +--
 examples/go/electron/util                       |  1 +
 examples/go/example_test.go                     |  4 +-
 examples/go/proton/broker.go                    |  2 +-
 examples/go/proton/util                         |  1 +
 examples/go/util/util.go                        |  3 +-
 proton-c/bindings/go/CMakeLists.txt             | 80 ++++++++++----------
 .../go/src/qpid.apache.org/amqp/types.go        |  5 +-
 .../go/src/qpid.apache.org/amqp/unmarshal.go    |  6 +-
 .../qpid.apache.org/electron/messaging_test.go  |  4 +
 13 files changed, 83 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 1b68ebe..76487fd 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -32,13 +32,12 @@ if(BUILD_GO)
 
   add_test(
     NAME go_example_electron_test
-    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -broker broker
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/electron)
+    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker broker)
+
 
   add_test(
     NAME go_example_proton_test
-    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -broker ../proton/broker
-    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/electron)
+    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/example_test -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/electron/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/broker.go b/examples/go/electron/broker.go
index 4b877df..0ecfb92 100644
--- a/examples/go/electron/broker.go
+++ b/examples/go/electron/broker.go
@@ -27,7 +27,7 @@ under the License.
 package main
 
 import (
-	"../util"
+	"./util"
 	"flag"
 	"fmt"
 	"net"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/electron/receive.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/receive.go b/examples/go/electron/receive.go
index 7639375..e450a75 100644
--- a/examples/go/electron/receive.go
+++ b/examples/go/electron/receive.go
@@ -20,7 +20,7 @@ under the License.
 package main
 
 import (
-	"../util"
+	"./util"
 	"flag"
 	"fmt"
 	"log"
@@ -54,9 +54,10 @@ func main() {
 	}
 
 	messages := make(chan amqp.Message) // Channel for messages from goroutines to main()
-	stop := make(chan struct{})         // Closing this channel means the program is stopping.
-	var wait sync.WaitGroup             // Used by main() to wait for all goroutines to end.
-	wait.Add(len(urls))                 // Wait for one goroutine per URL.
+	defer close(messages)
+
+	var wait sync.WaitGroup // Used by main() to wait for all goroutines to end.
+	wait.Add(len(urls))     // Wait for one goroutine per URL.
 
 	_, prog := path.Split(os.Args[0])
 	container := electron.NewContainer(fmt.Sprintf("%v:%v", prog, os.Getpid()))
@@ -87,14 +88,14 @@ func main() {
 			// Loop receiving messages and sending them to the main() goroutine
 			for {
 				rm, err := r.Receive()
-				if err == electron.Closed {
-					return
-				}
-				util.ExitIf(err)
-				select { // Send m to main() or stop
-				case messages <- rm.Message: // Send to main()
-				case <-stop: // The program is stopping.
+				switch err {
+				case electron.Closed:
+					util.Debugf("closed %s", urlStr)
 					return
+				case nil:
+					messages <- rm.Message
+				default:
+					log.Fatal(err)
 				}
 			}
 		}(urlStr)
@@ -105,8 +106,9 @@ func main() {
 
 	// print each message until the count is exceeded.
 	for i := uint64(0); i < *count; i++ {
+		util.Debugf("pre (%d/%d)\n", i, *count)
 		m := <-messages
-		util.Debugf("%s\n", util.FormatMessage(m))
+		util.Debugf("%s (%d/%d)\n", util.FormatMessage(m), i, *count)
 	}
 	fmt.Printf("Received %d messages\n", *count)
 
@@ -116,7 +118,5 @@ func main() {
 		util.Debugf("close %s", c)
 		c.Close(nil)
 	}
-	close(stop) // Signal all goroutines to stop.
 	wait.Wait() // Wait for all goroutines to finish.
-	close(messages)
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/electron/send.go
----------------------------------------------------------------------
diff --git a/examples/go/electron/send.go b/examples/go/electron/send.go
index 94a77e7..6b7aec1 100644
--- a/examples/go/electron/send.go
+++ b/examples/go/electron/send.go
@@ -20,7 +20,7 @@ under the License.
 package main
 
 import (
-	"../util"
+	"./util"
 	"flag"
 	"fmt"
 	"log"
@@ -64,7 +64,7 @@ func main() {
 
 	_, prog := path.Split(os.Args[0])
 	container := electron.NewContainer(fmt.Sprintf("%v:%v", prog, os.Getpid()))
-	var connections []electron.Connection // Store connctions to close on exit
+	connections := make(chan electron.Connection, len(urls)) // Connctions to close on exit
 
 	// Start a goroutine for each URL to send messages.
 	for _, urlStr := range urls {
@@ -82,7 +82,7 @@ func main() {
 			util.ExitIf(err)
 			err = c.Open()
 			util.ExitIf(err)
-			connections = append(connections, c) // Save connection so it will be closed when main() ends
+			connections <- c // Save connection so we can Close() when main() ends
 
 			// Create a Sender using the path of the URL as the AMQP address
 			s, err := c.Sender(electron.Target(url.Path))
@@ -114,8 +114,9 @@ func main() {
 	}
 	fmt.Printf("Received all %v acknowledgements\n", expect)
 
-	wait.Wait()                     // Wait for all goroutines to finish.
-	for _, c := range connections { // Close all connections
+	wait.Wait() // Wait for all goroutines to finish.
+	close(connections)
+	for c := range connections { // Close all connections
 		if c != nil {
 			c.Close(nil)
 		}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/electron/util
----------------------------------------------------------------------
diff --git a/examples/go/electron/util b/examples/go/electron/util
new file mode 120000
index 0000000..40c3fc5
--- /dev/null
+++ b/examples/go/electron/util
@@ -0,0 +1 @@
+../util
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/example_test.go
----------------------------------------------------------------------
diff --git a/examples/go/example_test.go b/examples/go/example_test.go
index a4d7d80..1e497b9 100644
--- a/examples/go/example_test.go
+++ b/examples/go/example_test.go
@@ -32,6 +32,7 @@ import (
 	"net"
 	"os"
 	"os/exec"
+	"path"
 	"path/filepath"
 	"reflect"
 	"strings"
@@ -133,7 +134,7 @@ func exampleCommand(t *testing.T, prog string, arg ...string) (cmd *exec.Cmd) {
 		args = append(args, "-debug=true")
 	}
 	args = append(args, arg...)
-	prog, err := filepath.Abs(prog)
+	prog, err := filepath.Abs(path.Join(*dir, prog))
 	fatalIf(t, err)
 	if _, err := os.Stat(prog); err == nil {
 		cmd = exec.Command(prog, args...)
@@ -271,6 +272,7 @@ var debug = flag.Bool("debug", false, "Debugging output from examples")
 var brokerName = flag.String("broker", "broker", "Name of broker executable to run")
 var count = flag.Int("count", 3, "Count of messages to send in tests")
 var connections = flag.Int("connections", 3, "Number of connections to make in tests")
+var dir = flag.String("dir", "", "Directory containing example sources or binaries")
 var expected int
 
 func TestMain(m *testing.M) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/proton/broker.go
----------------------------------------------------------------------
diff --git a/examples/go/proton/broker.go b/examples/go/proton/broker.go
index dbb4a82..75f14f5 100644
--- a/examples/go/proton/broker.go
+++ b/examples/go/proton/broker.go
@@ -27,7 +27,7 @@ under the License.
 package main
 
 import (
-	"../util"
+	"./util"
 	"flag"
 	"fmt"
 	"io"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/proton/util
----------------------------------------------------------------------
diff --git a/examples/go/proton/util b/examples/go/proton/util
new file mode 120000
index 0000000..40c3fc5
--- /dev/null
+++ b/examples/go/proton/util
@@ -0,0 +1 @@
+../util
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/examples/go/util/util.go
----------------------------------------------------------------------
diff --git a/examples/go/util/util.go b/examples/go/util/util.go
index f158386..5118467 100644
--- a/examples/go/util/util.go
+++ b/examples/go/util/util.go
@@ -46,8 +46,7 @@ func Debugf(format string, data ...interface{}) {
 // Simple error handling for demo.
 func ExitIf(err error) {
 	if err != nil {
-		log.Println(err)
-		os.Exit(1)
+		log.Fatal(err)
 	}
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/proton-c/bindings/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/CMakeLists.txt b/proton-c/bindings/go/CMakeLists.txt
index d24bf2e..11a3b78 100644
--- a/proton-c/bindings/go/CMakeLists.txt
+++ b/proton-c/bindings/go/CMakeLists.txt
@@ -17,52 +17,54 @@
 # under the License.
 #
 
+# Go version
+execute_process(COMMAND ${GO_EXE} version OUTPUT_VARIABLE go_out)
+message(STATUS "Found Go: ${go_out}")
+
 set(GO_BUILD_FLAGS "" CACHE STRING "Flags for 'go build'")
-set(GO_TEST_FLAGS "-v -race" CACHE STRING "Flags for 'go test'")
+
+# Flags that differ for golang go and gcc go.
+if (go_out MATCHES "gccgo")
+  # TODO aconway 2015-10-08: import cycles with -race under gccgo, investigate.
+  set(GO_TEST_FLAGS "-v" CACHE STRING "Flags for 'go test'")
+  set(GO_RPATH_FLAGS -gccgoflags "-Wl,-rpath=${CMAKE_BINARY_DIR}/proton-c")
+else()
+  set(GO_TEST_FLAGS "-v -race" CACHE STRING "Flags for 'go test'")
+  set(GO_RPATH_FLAGS -ldflags "-r ${CMAKE_BINARY_DIR}/proton-c")
+endif()
 
 separate_arguments(GO_BUILD_FLAGS)
 separate_arguments(GO_TEST_FLAGS)
 
-if (BUILD_GO)
-  # Following are CACHE INTERNAL so examples/CMakeLists.txt can see them.
-  set(GO_ENV ${env_py} --
-    "GOPATH=${CMAKE_CURRENT_SOURCE_DIR}"
-    "CGO_CFLAGS=-I${CMAKE_SOURCE_DIR}/proton-c/include"
-    "CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/proton-c"
-    ${GO_EXE} CACHE INTERNAL "Run go with environment set")
-
-  # Set rpath so test and example executables will use the proton library from this build.
-  execute_process(COMMAND ${GO_EXE} version OUTPUT_VARIABLE go_out)
-  if (go_out MATCHES "gccgo")
-    set(GO_RPATH_FLAGS -gccgoflags "-Wl,-rpath=${CMAKE_BINARY_DIR}/proton-c")
-  else()
-    set(GO_RPATH_FLAGS -ldflags "-r ${CMAKE_BINARY_DIR}/proton-c")
-  endif()
-
-  set(GO_BUILD ${GO_ENV} build ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} CACHE INTERNAL "Run go build")
-  set(GO_INSTALL ${GO_ENV} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
-  set(GO_TEST ${GO_ENV} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
+# Following are CACHE INTERNAL so examples/CMakeLists.txt can see them.
+set(GO_ENV ${env_py} --
+  "GOPATH=${CMAKE_CURRENT_SOURCE_DIR}"
+  "CGO_CFLAGS=-I${CMAKE_SOURCE_DIR}/proton-c/include"
+  "CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/proton-c"
+  ${GO_EXE} CACHE INTERNAL "Run go with environment set")
 
-  # Install packages in the source tree, go tools aren't friendly otherwise.
-  # All build output goes in git-ignored pkg or bin subdirectories.
-  set(q "qpid.apache.org")
-  set(packages ${q}/amqp ${q}/internal ${q}/proton ${q}/electron)
-  add_custom_target(go-packages ALL
-    COMMAND ${GO_INSTALL} ${packages}
-    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-    DEPENDS qpid-proton)
+set(GO_BUILD ${GO_ENV} build ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} CACHE INTERNAL "Run go build")
+set(GO_INSTALL ${GO_ENV} install ${GO_BUILD_FLAGS} CACHE INTERNAL "Run go install")
+set(GO_TEST ${GO_ENV} test ${GO_BUILD_FLAGS} ${GO_RPATH_FLAGS} ${GO_TEST_FLAGS} CACHE INTERNAL "Run go test")
 
-  add_test(
-    NAME go_test_packages
-    COMMAND ${GO_TEST} ${packages}
-    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
+# Install packages in the source tree, go tools aren't friendly otherwise.
+# All build output goes in git-ignored pkg or bin subdirectories.
+set(q "qpid.apache.org")
+set(packages ${q}/amqp ${q}/internal ${q}/proton ${q}/electron)
+add_custom_target(go-packages ALL
+  COMMAND ${GO_INSTALL} ${packages}
+  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+  DEPENDS qpid-proton)
 
-  list(APPEND ADDITIONAL_MAKE_CLEAN_FILES
-    ${CMAKE_CURRENT_SOURCE_DIR}/pkg
-    ${CMAKE_CURRENT_SOURCE_DIR}/bin)
+add_test(
+  NAME go_test_packages
+  COMMAND ${GO_TEST} ${packages}
+  WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
 
-  set (GO_INSTALL_DIR ${SHARE_INSTALL_DIR}/gocode/src CACHE PATH "Installation directory for Go code")
-  mark_as_advanced (GO_INSTALL_DIR)
-  install(DIRECTORY src/qpid.apache.org DESTINATION ${GO_INSTALL_DIR} COMPONENT Go)
+list(APPEND ADDITIONAL_MAKE_CLEAN_FILES
+  ${CMAKE_CURRENT_SOURCE_DIR}/pkg
+  ${CMAKE_CURRENT_SOURCE_DIR}/bin)
 
-endif(BUILD_GO)
+set (GO_INSTALL_DIR ${SHARE_INSTALL_DIR}/gocode/src CACHE PATH "Installation directory for Go code")
+mark_as_advanced (GO_INSTALL_DIR)
+install(DIRECTORY src/qpid.apache.org DESTINATION ${GO_INSTALL_DIR} COMPONENT Go)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
index 131c974..796da66 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/types.go
@@ -84,9 +84,10 @@ func (t Type) String() string {
 		return "list"
 	case C.PN_MAP:
 		return "map"
-	case C.PN_INVALID:
-		return "no-data"
 	default:
+		if uint32(t) == uint32(C.PN_INVALID) {
+			return "no-data"
+		}
 		return fmt.Sprintf("unknown-type(%d)", t)
 	}
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
index 61c6d3f..751921d 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/amqp/unmarshal.go
@@ -446,7 +446,8 @@ func rewindUnmarshal(v interface{}, data *C.pn_data_t) {
 func getInterface(data *C.pn_data_t, v *interface{}) {
 	pnType := C.pn_data_type(data)
 	switch pnType {
-	case C.PN_NULL, C.PN_INVALID: // No data.
+	// Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t
+	case C.PN_NULL, C.pn_type_t(C.PN_INVALID): // No data.
 		*v = nil
 	case C.PN_BOOL:
 		*v = bool(C.pn_data_get_bool(data))
@@ -512,7 +513,8 @@ func getMap(data *C.pn_data_t, v interface{}) {
 				}
 			}
 		}
-	case C.PN_INVALID: // Leave the map empty
+		// Note PN_INVALID is defined outside the enum, older Go versions don't consider it a C.pn_type_t
+	case C.pn_type_t(C.PN_INVALID): // Leave the map empty
 	default:
 		panic(newUnmarshalError(pnType, v))
 	}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/40630b6c/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
index 474bad7..3b315cd 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/messaging_test.go
@@ -117,8 +117,11 @@ func TestClientSendServerReceive(t *testing.T) {
 	for i := 0; i < nLinks; i++ {
 		for j := 0; j < nMessages; j++ {
 			var sm SentMessage
+
 			// Client send
+			sendDone := make(chan struct{})
 			go func() {
+				defer close(sendDone)
 				m := amqp.NewMessageWith(fmt.Sprintf("foobar%v-%v", i, j))
 				var err error
 				sm, err = s[i].Send(m)
@@ -137,6 +140,7 @@ func TestClientSendServerReceive(t *testing.T) {
 			}
 
 			// Should not be acknowledged on client yet
+			<-sendDone
 			if d, err := sm.DispositionTimeout(0); err != Timeout || NoDisposition != d {
 				t.Errorf("want [no-disposition/timeout] got [%v/%v]", d, err)
 			}


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


[37/50] [abbrv] qpid-proton git commit: NO-JIRA: c++ const correctness and other minor fixes.

Posted by ac...@apache.org.
NO-JIRA: c++ const correctness and other minor fixes.

- Made inspector functions const
- Removed link_prefix, generated generated link names are XXX + "@" + container.id()
- Removed redundant terminus::has_* functions.
- Removed redundant 'acking' class


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

Branch: refs/heads/go1
Commit: cf221b45793fd1d1e12a4f470483c5b4fc2ad39d
Parents: d72f161
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 20 13:22:09 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 20 14:22:40 2015 -0400

----------------------------------------------------------------------
 examples/cpp/server_direct.cpp                  |  2 +-
 proton-c/bindings/cpp/include/proton/acking.hpp | 50 --------------------
 .../cpp/include/proton/blocking_connection.hpp  |  4 +-
 .../cpp/include/proton/blocking_sender.hpp      |  2 +-
 .../bindings/cpp/include/proton/connection.hpp  | 12 ++---
 .../bindings/cpp/include/proton/container.hpp   | 13 ++---
 proton-c/bindings/cpp/include/proton/data.hpp   |  2 +-
 .../bindings/cpp/include/proton/delivery.hpp    | 12 ++---
 .../bindings/cpp/include/proton/endpoint.hpp    | 20 ++++----
 proton-c/bindings/cpp/include/proton/event.hpp  | 14 +++---
 proton-c/bindings/cpp/include/proton/link.hpp   | 41 +++++++---------
 .../bindings/cpp/include/proton/message.hpp     | 16 ++++---
 .../bindings/cpp/include/proton/reactor.hpp     |  2 +-
 .../cpp/include/proton/request_response.hpp     |  2 +-
 .../bindings/cpp/include/proton/session.hpp     | 14 +++---
 .../bindings/cpp/include/proton/terminus.hpp    | 10 ++--
 .../bindings/cpp/include/proton/transport.hpp   |  2 +-
 .../bindings/cpp/src/blocking_connection.cpp    |  4 +-
 proton-c/bindings/cpp/src/blocking_sender.cpp   |  2 +-
 proton-c/bindings/cpp/src/connection.cpp        | 12 ++---
 proton-c/bindings/cpp/src/container.cpp         |  7 +--
 proton-c/bindings/cpp/src/container_impl.cpp    |  2 +-
 proton-c/bindings/cpp/src/container_impl.hpp    |  1 -
 proton-c/bindings/cpp/src/data.cpp              |  2 +
 proton-c/bindings/cpp/src/delivery.cpp          | 13 ++---
 proton-c/bindings/cpp/src/event.cpp             | 14 +++---
 proton-c/bindings/cpp/src/link.cpp              | 31 ++++++------
 proton-c/bindings/cpp/src/message.cpp           |  4 +-
 proton-c/bindings/cpp/src/messaging_event.cpp   | 12 ++---
 proton-c/bindings/cpp/src/messaging_event.hpp   | 12 ++---
 proton-c/bindings/cpp/src/proton_event.cpp      | 14 +++---
 proton-c/bindings/cpp/src/proton_event.hpp      | 16 +++----
 proton-c/bindings/cpp/src/request_response.cpp  |  2 +-
 proton-c/bindings/cpp/src/session.cpp           |  6 +--
 proton-c/bindings/cpp/src/terminus.cpp          | 10 ++--
 proton-c/bindings/cpp/src/transport.cpp         |  2 +-
 36 files changed, 165 insertions(+), 219 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 2b6d8e2..76bb5ad 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -63,7 +63,7 @@ class server : public proton::messaging_handler {
 
     void on_link_opening(proton::event& e) {
         proton::link& link = e.link();
-        if (link.sender() && link.has_remote_source() && link.remote_source().dynamic()) {
+        if (link.sender() && link.remote_source().dynamic()) {
             link.source().address(generate_address());
             senders[link.source().address()] = link.sender()->ptr();
         }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/acking.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/acking.hpp b/proton-c/bindings/cpp/include/proton/acking.hpp
deleted file mode 100644
index 8a6d75b..0000000
--- a/proton-c/bindings/cpp/include/proton/acking.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef PROTON_CPP_ACKING_H
-#define PROTON_CPP_ACKING_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/export.hpp"
-#include "proton/delivery.hpp"
-
-namespace proton {
-
-
-/** acking provides simple functions to acknowledge, or settle, a delivery */
-class acking
-{
-  public:
-    /** accept a delivery */
-    PN_CPP_EXTERN virtual void accept(delivery &d);
-    /** reject a delivery */
-    PN_CPP_EXTERN virtual void reject(delivery &d);
-    /** release a delivery. Mark it delivery::MODIFIED if it has already been delivered,
-     * delivery::RELEASED otherwise.
-     */
-    PN_CPP_EXTERN virtual void release(delivery &d, bool delivered=true);
-    /** settle a delivery with the given delivery::state */
-    PN_CPP_EXTERN virtual void settle(delivery &d, delivery::state s = delivery::REJECTED);
-};
-
-
-}
-
-#endif  /*!PROTON_CPP_ACKING_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
index f7787cb..87e9b2e 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -42,8 +42,8 @@ class blocking_connection
     PN_CPP_EXTERN blocking_connection(const proton::url &url, duration timeout = duration::FOREVER);
     PN_CPP_EXTERN ~blocking_connection();
     PN_CPP_EXTERN void close();
-    PN_CPP_EXTERN duration timeout();
-    PN_CPP_EXTERN class connection& connection();
+    PN_CPP_EXTERN duration timeout() const;
+    PN_CPP_EXTERN class connection& connection() const;
 
   private:
     blocking_connection(const blocking_connection&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
index 713ae6d..b7c2697 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
@@ -42,7 +42,7 @@ class blocking_sender : public blocking_link
     PN_CPP_EXTERN delivery& send(const message &msg);
     PN_CPP_EXTERN delivery& send(const message &msg, duration timeout);
 
-    PN_CPP_EXTERN class sender& sender();
+    PN_CPP_EXTERN class sender& sender() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 c7ce447..efbd549 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -39,9 +39,9 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
 {
   public:
     ///@name getters @{
-    PN_CPP_EXTERN class transport& transport();
-    PN_CPP_EXTERN class container& container();
-    PN_CPP_EXTERN std::string hostname();
+    PN_CPP_EXTERN class transport& transport() const;
+    PN_CPP_EXTERN class container& container() const;
+    PN_CPP_EXTERN std::string host() const;
     ///@}
 
     /** Initiate local open, not complete till messaging_handler::on_connection_opened()
@@ -67,13 +67,13 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
     PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Return links on this connection matching the state mask. */
-    PN_CPP_EXTERN link_range find_links(endpoint::state mask);
+    PN_CPP_EXTERN link_range find_links(endpoint::state mask) const;
 
     /** Return sessions on this connection matching the state mask. */
-    PN_CPP_EXTERN session_range find_sessions(endpoint::state mask);
+    PN_CPP_EXTERN session_range find_sessions(endpoint::state mask) const;
 
     /** Get the endpoint state */
-    PN_CPP_EXTERN endpoint::state state();
+    PN_CPP_EXTERN endpoint::state state() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 ddb12e9..059416f 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -43,6 +43,9 @@ class container_impl;
 
 /**
  * Top level container for connections and other objects, runs the event loop.
+ *
+ * Note that by default, links belonging to the container have generated link-names
+ * of the form
  */
 class container
 {
@@ -71,16 +74,10 @@ class container
     PN_CPP_EXTERN receiver& open_receiver(const url &);
 
     /// Identifier for the container
-    PN_CPP_EXTERN std::string id();
-
-    /// Set the prefix to be used when generating link names. @see proton::session
-    PN_CPP_EXTERN void link_prefix(const std::string&);
-
-    /// Get the prefix to be used when generating link names. @see proton::session
-    PN_CPP_EXTERN std::string link_prefix();
+    PN_CPP_EXTERN std::string id() const;
 
     /// The reactor associated with this container.
-    PN_CPP_EXTERN class reactor& reactor();
+    PN_CPP_EXTERN class reactor& reactor() const;
 
     // Schedule a timer task event in delay milliseconds.
     PN_CPP_EXTERN task& schedule(int delay, handler *h = 0);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/data.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp
index 17e55fb..bbc49c2 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -59,7 +59,7 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN class decoder& decoder();
 
     /** Type of the current value*/
-    PN_CPP_EXTERN type_id type() { return decoder().type(); }
+    PN_CPP_EXTERN type_id type() const;
 
     /** Get the current value, don't move the decoder pointer. */
     template<class T> void get(T &t) { decoder() >> t; decoder().backup(); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 1bd1dea..08389c9 100644
--- a/proton-c/bindings/cpp/include/proton/delivery.hpp
+++ b/proton-c/bindings/cpp/include/proton/delivery.hpp
@@ -43,7 +43,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
     };  // AMQP spec 3.4 delivery State
 
     /** Return true if the delivery has been settled. */
-    PN_CPP_EXTERN bool settled();
+    PN_CPP_EXTERN bool settled() const;
 
     /** Settle the delivery, informs the remote end. */
     PN_CPP_EXTERN void settle();
@@ -72,7 +72,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * A delivery is considered readable if it is the current delivery on
      * an incoming link.
      */
-    PN_CPP_EXTERN bool partial();
+    PN_CPP_EXTERN bool partial() const;
 
     /**
      * Check if a delivery is writable.
@@ -80,7 +80,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * A delivery is considered writable if it is the current delivery on
      * an outgoing link, and the link has positive credit.
      */
-    PN_CPP_EXTERN bool writable();
+    PN_CPP_EXTERN bool writable() const;
 
     /**
      * Check if a delivery is readable.
@@ -88,7 +88,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * A delivery is considered readable if it is the current delivery on
      * an incoming link.
      */
-    PN_CPP_EXTERN bool readable();
+    PN_CPP_EXTERN bool readable() const;
 
     /**
      * Check if a delivery is updated.
@@ -97,7 +97,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * new disposition for the delivery. Once a delivery becomes updated,
      * it will remain so until clear() is called.
      */
-    PN_CPP_EXTERN bool updated();
+    PN_CPP_EXTERN bool updated() const;
 
     /**
      * Clear the updated flag for a delivery.
@@ -107,7 +107,7 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
     /**
      * Get the remote disposition state for a delivery.
      */
-    PN_CPP_EXTERN state remote_state();
+    PN_CPP_EXTERN state remote_state() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/endpoint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp
index 9fb5368..e31fce6 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -49,14 +49,14 @@ class endpoint
     typedef int state;
 
     /// endpoint state bit values @{
-    PN_CPP_EXTERN static const int LOCAL_UNINIT;    ///< Local endpoint is un-initialized
-    PN_CPP_EXTERN static const int REMOTE_UNINIT;   ///< Remote endpoint is un-initialized
-    PN_CPP_EXTERN static const int LOCAL_ACTIVE;    ///< Local endpoint is active
-    PN_CPP_EXTERN static const int REMOTE_ACTIVE;   ///< Remote endpoint is active
-    PN_CPP_EXTERN static const int LOCAL_CLOSED;    ///< Local endpoint has been closed
-    PN_CPP_EXTERN static const int REMOTE_CLOSED;   ///< Remote endpoint has been closed
-    PN_CPP_EXTERN static const int LOCAL_MASK;      ///< Mask including all LOCAL_ bits (UNINIT, ACTIVE, CLOSED)
-    PN_CPP_EXTERN static const int REMOTE_MASK;     ///< Mask including all REMOTE_ bits (UNINIT, ACTIVE, CLOSED)
+    PN_CPP_EXTERN static const state LOCAL_UNINIT;    ///< Local endpoint is un-initialized
+    PN_CPP_EXTERN static const state REMOTE_UNINIT;   ///< Remote endpoint is un-initialized
+    PN_CPP_EXTERN static const state LOCAL_ACTIVE;    ///< Local endpoint is active
+    PN_CPP_EXTERN static const state REMOTE_ACTIVE;   ///< Remote endpoint is active
+    PN_CPP_EXTERN static const state LOCAL_CLOSED;    ///< Local endpoint has been closed
+    PN_CPP_EXTERN static const state REMOTE_CLOSED;   ///< Remote endpoint has been closed
+    PN_CPP_EXTERN static const state LOCAL_MASK;      ///< Mask including all LOCAL_ bits (UNINIT, ACTIVE, CLOSED)
+    PN_CPP_EXTERN static const state REMOTE_MASK;     ///< Mask including all REMOTE_ bits (UNINIT, ACTIVE, CLOSED)
     ///@}
 
     // TODO: condition, remote_condition, update_condition, get/handler
@@ -112,11 +112,11 @@ class link_iterator : public iter_base<link, link_iterator> {
   public:
     explicit link_iterator(link* p = 0, endpoint::state s = 0) :
         iter_base(p, s), session_(0) {}
-    explicit link_iterator(const link_iterator& i, session *ssn) :
+    explicit link_iterator(const link_iterator& i, const session *ssn) :
         iter_base(i.ptr_, i.state_), session_(ssn) {}
   private:
     PN_CPP_EXTERN void advance();
-    session* session_;
+    const session* session_;
   friend class iter_base<link, link_iterator>;
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event.hpp b/proton-c/bindings/cpp/include/proton/event.hpp
index 82f6cb6..65d8c7b 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -46,19 +46,19 @@ class event {
     virtual PN_CPP_EXTERN std::string name() const = 0;
 
     /// Get container.
-    virtual PN_CPP_EXTERN class container &container();
+    virtual PN_CPP_EXTERN class container &container() const;
     /// Get connection.
-    virtual PN_CPP_EXTERN class connection &connection();
+    virtual PN_CPP_EXTERN class connection &connection() const;
     /// Get sender @throws error if no sender.
-    virtual PN_CPP_EXTERN class sender& sender();
+    virtual PN_CPP_EXTERN class sender& sender() const;
     /// Get receiver @throws error if no receiver.
-    virtual PN_CPP_EXTERN class receiver& receiver();
+    virtual PN_CPP_EXTERN class receiver& receiver() const;
     /// Get link @throws error if no link.
-    virtual PN_CPP_EXTERN class link& link();
+    virtual PN_CPP_EXTERN class link& link() const;
     /// Get delivey @throws error if no delivery.
-    virtual PN_CPP_EXTERN class delivery& delivery();
+    virtual PN_CPP_EXTERN class delivery& delivery() const;
     /** Get message @throws error if no message. */
-    virtual PN_CPP_EXTERN class message &message();
+    virtual PN_CPP_EXTERN class message &message() const;
 
   protected:
     PN_CPP_EXTERN event();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 4e502e1..b4b40e0 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -51,37 +51,32 @@ class link : public counted_facade<pn_link_t, link, endpoint>
 
     /** Return sender if this link is a sender, 0 if not. */
     PN_CPP_EXTERN class sender* sender();
+    PN_CPP_EXTERN const class sender* sender() const;
+
     /** Return receiver if this link is a receiver, 0 if not. */
     PN_CPP_EXTERN class receiver* receiver();
+    PN_CPP_EXTERN const class receiver* receiver() const;
+
     /** Credit available on the link */
-    PN_CPP_EXTERN int credit();
-
-    /** True if link has source */
-    PN_CPP_EXTERN bool has_source();
-    /** True if link has target */
-    PN_CPP_EXTERN bool has_target();
-    /** True if link has remote source */
-    PN_CPP_EXTERN bool has_remote_source();
-    /** True if link has remote target */
-    PN_CPP_EXTERN bool has_remote_target();
-
-    /** Local source of the link. @throw error if !has_source() */
-    PN_CPP_EXTERN terminus& source();
-    /** Local target of the link. @throw error if !has_target() */
-    PN_CPP_EXTERN terminus& target();
-    /** Remote source of the link. @throw error if !has_remote_source() */
-    PN_CPP_EXTERN terminus& remote_source();
-    /** Remote target of the link. @throw error if !has_remote_target() */
-    PN_CPP_EXTERN terminus& remote_target();
+    PN_CPP_EXTERN int credit() const;
+
+    /** Local source of the link. */
+    PN_CPP_EXTERN terminus& source() const;
+    /** Local target of the link. */
+    PN_CPP_EXTERN terminus& target() const;
+    /** Remote source of the link. */
+    PN_CPP_EXTERN terminus& remote_source() const;
+    /** Remote target of the link. */
+    PN_CPP_EXTERN terminus& remote_target() const;
 
     /** Link name */
-    PN_CPP_EXTERN std::string name();
+    PN_CPP_EXTERN std::string name() const;
 
     /** Connection that owns this link */
-    PN_CPP_EXTERN class connection &connection();
+    PN_CPP_EXTERN class connection &connection() const;
 
     /** Session that owns this link */
-    PN_CPP_EXTERN class session &session();
+    PN_CPP_EXTERN class session &session() const;
 
     /** Set a custom handler for this link. */
     PN_CPP_EXTERN void handler(class handler &);
@@ -90,7 +85,7 @@ class link : public counted_facade<pn_link_t, link, endpoint>
     PN_CPP_EXTERN void detach_handler();
 
     /** Get the endpoint state */
-    PN_CPP_EXTERN endpoint::state state();
+    PN_CPP_EXTERN endpoint::state state() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 92086d1..14eb9a8 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -56,11 +56,12 @@ class message
     ///@name Message properties
     ///@{
 
-    /// Globally unique identifier, can be an a string, an unsigned long, a uuid or a binary value.
+    ///@ Set message identifier, can be a string, unsigned long, uuid or binary.
     PN_CPP_EXTERN void id(const data& id);
-    /// Globally unique identifier, can be an a string, an unsigned long, a uuid or a binary value.
-    PN_CPP_EXTERN const data& id() const;
+    ///@ Get message identifier
     PN_CPP_EXTERN data& id();
+    ///@ Get message identifier reference, allows modification in-place.
+    PN_CPP_EXTERN const data& id() const;
 
     PN_CPP_EXTERN void user(const std::string &user);
     PN_CPP_EXTERN std::string user() const;
@@ -74,10 +75,11 @@ class message
     PN_CPP_EXTERN void reply_to(const std::string &s);
     PN_CPP_EXTERN std::string reply_to() const;
 
-    /// Correlation identifier, can be an a string, an unsigned long, a uuid or a binary value.
+    /// Get correlation identifier, can be a string, unsigned long, uuid or binary.
     PN_CPP_EXTERN void correlation_id(const data&);
-    /// Correlation identifier, can be an a string, an unsigned long, a uuid or a binary value.
+    /// Get correlation identifier.
     PN_CPP_EXTERN const data& correlation_id() const;
+    /// Get correlation identifier reference, allows modification in-place.
     PN_CPP_EXTERN data& correlation_id();
 
     PN_CPP_EXTERN void content_type(const std::string &s);
@@ -86,8 +88,8 @@ class message
     PN_CPP_EXTERN void content_encoding(const std::string &s);
     PN_CPP_EXTERN std::string content_encoding() const;
 
-    PN_CPP_EXTERN void expiry(amqp_timestamp t);
-    PN_CPP_EXTERN amqp_timestamp expiry() const;
+    PN_CPP_EXTERN void expiry_time(amqp_timestamp t);
+    PN_CPP_EXTERN amqp_timestamp expiry_time() const;
 
     PN_CPP_EXTERN void creation_time(amqp_timestamp t);
     PN_CPP_EXTERN amqp_timestamp creation_time() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/reactor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/reactor.hpp b/proton-c/bindings/cpp/include/proton/reactor.hpp
index b9e9427..8508e20 100644
--- a/proton-c/bindings/cpp/include/proton/reactor.hpp
+++ b/proton-c/bindings/cpp/include/proton/reactor.hpp
@@ -56,7 +56,7 @@ class reactor : public facade<pn_reactor_t, reactor> {
     PN_CPP_EXTERN void stop();
 
     /// Identifier for the container
-    PN_CPP_EXTERN std::string id();
+    PN_CPP_EXTERN std::string id() const;
 
     /// Get timeout, process() will return if there is no activity within the timeout.
     PN_CPP_EXTERN duration timeout();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/request_response.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/request_response.hpp b/proton-c/bindings/cpp/include/proton/request_response.hpp
index 9bc4392..957c91a 100644
--- a/proton-c/bindings/cpp/include/proton/request_response.hpp
+++ b/proton-c/bindings/cpp/include/proton/request_response.hpp
@@ -48,7 +48,7 @@ class request_response
      */
     PN_CPP_EXTERN message call(message &request);
     /** Return the dynamic address of our receiver. */
-    PN_CPP_EXTERN std::string reply_to();
+    PN_CPP_EXTERN std::string reply_to() const;
 
   private:
     blocking_connection &connection_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 b3dc446..0e6aa69 100644
--- a/proton-c/bindings/cpp/include/proton/session.hpp
+++ b/proton-c/bindings/cpp/include/proton/session.hpp
@@ -52,19 +52,19 @@ class session : public counted_facade<pn_session_t, session, endpoint>
     PN_CPP_EXTERN void close();
 
     /// Get connection
-    PN_CPP_EXTERN class connection &connection();
+    PN_CPP_EXTERN class connection &connection() const;
 
     /** An un-opened receiver link, you can set link properties before calling open().
      *
-     *@param name must be unique within a container, if empty a unique name is
-     * generated beginning with connection().container().link_prefix()
+     *@param name if specified must be unique, by default the container generates a name
+     * of the form: <hex-digits> + "@" + container.id()
      */
     PN_CPP_EXTERN receiver& create_receiver(const std::string& name=std::string());
 
     /** An un-opened sender link, you can set link properties before calling open().
      *
-     *@param name must be unique within a container, if empty a unique name is
-     * generated beginning with connection().container().link_prefix()
+     *@param name if specified must be unique, by default the container generates a name
+     * of the form: <hex-digits> + "@" + container.id()
      */
     PN_CPP_EXTERN sender& create_sender(const std::string& name=std::string());
 
@@ -75,10 +75,10 @@ class session : public counted_facade<pn_session_t, session, endpoint>
     PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Get the endpoint state */
-    PN_CPP_EXTERN endpoint::state state();
+    PN_CPP_EXTERN endpoint::state state() const;
 
     /** Return the links on this session matching the state mask. */
-    PN_CPP_EXTERN link_range find_links(endpoint::state mask);
+    PN_CPP_EXTERN link_range find_links(endpoint::state mask) const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/terminus.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/terminus.hpp b/proton-c/bindings/cpp/include/proton/terminus.hpp
index e058e84..86b56f7 100644
--- a/proton-c/bindings/cpp/include/proton/terminus.hpp
+++ b/proton-c/bindings/cpp/include/proton/terminus.hpp
@@ -59,15 +59,15 @@ class terminus : public counted_facade<pn_terminus_t, terminus>
         MOVE = PN_DIST_MODE_MOVE
     };
 
-    PN_CPP_EXTERN type_t type();
+    PN_CPP_EXTERN type_t type() const;
     PN_CPP_EXTERN void type(type_t);
-    PN_CPP_EXTERN expiry_policy_t expiry_policy();
+    PN_CPP_EXTERN expiry_policy_t expiry_policy() const;
     PN_CPP_EXTERN void expiry_policy(expiry_policy_t);
-    PN_CPP_EXTERN distribution_mode_t distribution_mode();
+    PN_CPP_EXTERN distribution_mode_t distribution_mode() const;
     PN_CPP_EXTERN void distribution_mode(distribution_mode_t);
-    PN_CPP_EXTERN std::string address();
+    PN_CPP_EXTERN std::string address() const;
     PN_CPP_EXTERN void address(const std::string &);
-    PN_CPP_EXTERN bool dynamic();
+    PN_CPP_EXTERN bool dynamic() const;
     PN_CPP_EXTERN void dynamic(bool);
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/include/proton/transport.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/transport.hpp b/proton-c/bindings/cpp/include/proton/transport.hpp
index c909166..3d602b7 100644
--- a/proton-c/bindings/cpp/include/proton/transport.hpp
+++ b/proton-c/bindings/cpp/include/proton/transport.hpp
@@ -36,7 +36,7 @@ class connection;
 class transport : public counted_facade<pn_transport_t, transport>
 {
   public:
-    class connection* connection();
+    class connection* connection() const;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/blocking_connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection.cpp b/proton-c/bindings/cpp/src/blocking_connection.cpp
index 6b0308c..d830872 100644
--- a/proton-c/bindings/cpp/src/blocking_connection.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection.cpp
@@ -32,8 +32,8 @@ blocking_connection::~blocking_connection() {}
 
 void blocking_connection::close() { impl_->close(); }
 
-duration blocking_connection::timeout() { return impl_->container_->reactor().timeout(); }
+duration blocking_connection::timeout() const { return impl_->container_->reactor().timeout(); }
 
-connection& blocking_connection::connection() { return *impl_->connection_; }
+connection& blocking_connection::connection() const { return *impl_->connection_; }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/blocking_sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_sender.cpp b/proton-c/bindings/cpp/src/blocking_sender.cpp
index 1fca30b..43480d6 100644
--- a/proton-c/bindings/cpp/src/blocking_sender.cpp
+++ b/proton-c/bindings/cpp/src/blocking_sender.cpp
@@ -63,6 +63,6 @@ delivery& blocking_sender::send(const message &msg) {
     return send(msg, connection_.timeout());
 }
 
-sender& blocking_sender::sender() { return *link_->sender(); }
+sender& blocking_sender::sender() const { return *link_->sender(); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp
index 19657fd..1b35e03 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -37,7 +37,7 @@
 
 namespace proton {
 
-transport &connection::transport() {
+transport &connection::transport() const {
     return *transport::cast(pn_connection_transport(pn_cast(this)));
 }
 
@@ -45,19 +45,19 @@ void connection::open() { pn_connection_open(pn_cast(this)); }
 
 void connection::close() { pn_connection_close(pn_cast(this)); }
 
-std::string connection::hostname() {
+std::string connection::host() const {
     return std::string(pn_connection_get_hostname(pn_cast(this)));
 }
 
-container& connection::container() {
+container& connection::container() const {
     return container_context(pn_object_reactor(pn_cast(this)));
 }
 
-link_range connection::find_links(endpoint::state mask)  {
+link_range connection::find_links(endpoint::state mask) const {
     return link_range(link_iterator(link::cast(pn_link_head(pn_cast(this), mask))));
 }
 
-session_range connection::find_sessions(endpoint::state mask) {
+session_range connection::find_sessions(endpoint::state mask) const {
     return session_range(
         session_iterator(session::cast(pn_session_head(pn_cast(this), mask))));
 }
@@ -82,6 +82,6 @@ receiver& connection::open_receiver(const std::string &addr, bool dynamic, handl
     return default_session().open_receiver(addr, dynamic, h);
 }
 
-endpoint::state connection::state() { return pn_connection_state(pn_cast(this)); }
+endpoint::state connection::state() const { return pn_connection_state(pn_cast(this)); }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/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 9b681b9..13f12d9 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -49,9 +49,9 @@ container::~container() {}
 
 connection& container::connect(const url &host, handler *h) { return impl_->connect(host, h); }
 
-reactor &container::reactor() { return *impl_->reactor_; }
+reactor &container::reactor() const { return *impl_->reactor_; }
 
-std::string container::id() { return impl_->id_; }
+std::string container::id() const { return impl_->id_; }
 
 void container::run() { impl_->reactor_->run(); }
 
@@ -67,9 +67,6 @@ acceptor& container::listen(const proton::url &url) {
     return impl_->listen(url);
 }
 
-void container::link_prefix(const std::string& s) { impl_->prefix_ = s; }
-std::string  container::link_prefix() { return impl_->prefix_; }
-
 task& container::schedule(int delay, handler *h) { return impl_->schedule(delay, h); }
 
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index cb32d75..fc97a3e 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -186,7 +186,7 @@ acceptor& container_impl::listen(const proton::url& url) {
 std::string container_impl::next_link_name() {
     std::ostringstream s;
     // TODO aconway 2015-09-01: atomic operation
-    s << prefix_ << std::hex << ++link_id_;
+    s << std::hex << ++link_id_ << "@" << id_;
     return s.str();
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index 76d30fb..ec356e2 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -68,7 +68,6 @@ class container_impl
     pn_unique_ptr<handler> flow_controller_;
     std::string id_;
     uint64_t link_id_;
-    std::string prefix_;
 
   friend class container;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/data.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/data.cpp b/proton-c/bindings/cpp/src/data.cpp
index ad82040..53b8c37 100644
--- a/proton-c/bindings/cpp/src/data.cpp
+++ b/proton-c/bindings/cpp/src/data.cpp
@@ -39,6 +39,8 @@ pn_unique_ptr<data> data::create() { return pn_unique_ptr<data>(cast(::pn_data(0
 encoder& data::encoder() { return reinterpret_cast<class encoder&>(*this); }
 decoder& data::decoder() { return reinterpret_cast<class decoder&>(*this); }
 
+type_id data::type() const { return reinterpret_cast<const class decoder&>(*this).type(); }
+
 namespace {
 
 // Compare nodes, return -1 if a<b, 0 if a==b, +1 if a>b

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/delivery.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/delivery.cpp b/proton-c/bindings/cpp/src/delivery.cpp
index b292c70..d02904f 100644
--- a/proton-c/bindings/cpp/src/delivery.cpp
+++ b/proton-c/bindings/cpp/src/delivery.cpp
@@ -24,7 +24,7 @@
 
 namespace proton {
 
-bool delivery::settled() { return pn_delivery_settled(pn_cast(this)); }
+bool delivery::settled() const { return pn_delivery_settled(pn_cast(this)); }
 
 void delivery::settle() { pn_delivery_settle(pn_cast(this)); }
 
@@ -35,10 +35,11 @@ void delivery::settle(delivery::state state) {
     settle();
 }
 
-bool delivery::partial()  { return pn_delivery_partial(pn_cast(this)); }
-bool delivery::readable() { return pn_delivery_readable(pn_cast(this)); }
-bool delivery::writable() { return pn_delivery_writable(pn_cast(this)); }
-bool delivery::updated()  { return pn_delivery_updated(pn_cast(this)); }
+bool delivery::partial()  const { return pn_delivery_partial(pn_cast(this)); }
+bool delivery::readable() const { return pn_delivery_readable(pn_cast(this)); }
+bool delivery::writable() const { return pn_delivery_writable(pn_cast(this)); }
+bool delivery::updated()  const { return pn_delivery_updated(pn_cast(this)); }
+
 void delivery::clear()  { pn_delivery_clear(pn_cast(this)); }
-delivery::state delivery::remote_state() { return state(pn_delivery_remote_state(pn_cast(this))); }
+delivery::state delivery::remote_state() const { return state(pn_delivery_remote_state(pn_cast(this))); }
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/event.cpp b/proton-c/bindings/cpp/src/event.cpp
index 84927c4..d79df33 100644
--- a/proton-c/bindings/cpp/src/event.cpp
+++ b/proton-c/bindings/cpp/src/event.cpp
@@ -38,32 +38,32 @@ event::event() {}
 
 event::~event() {}
 
-container &event::container() {
+container &event::container() const {
     // Subclasses to override as appropriate
     throw error(MSG("No container context for event"));
 }
 
-connection &event::connection() {
+connection &event::connection() const {
     throw error(MSG("No connection context for event"));
 }
 
-sender& event::sender() {
+sender& event::sender() const {
     throw error(MSG("No sender context for event"));
 }
 
-receiver& event::receiver() {
+receiver& event::receiver() const {
     throw error(MSG("No receiver context for event"));
 }
 
-link& event::link() {
+link& event::link() const {
     throw error(MSG("No link context for event"));
 }
 
-delivery& event::delivery() {
+delivery& event::delivery() const {
     throw error(MSG("No link context for event"));
 }
 
-class message &event::message() {
+class message &event::message() const {
     throw error(MSG("No message associated with event"));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp
index 45c23aa..23345b5 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -47,27 +47,30 @@ receiver* link::receiver() {
     return pn_link_is_receiver(pn_cast(this)) ? reinterpret_cast<class receiver*>(this) : 0;
 }
 
-int link::credit() {
-    return pn_link_credit(pn_cast(this));
+const sender* link::sender() const {
+    return pn_link_is_sender(pn_cast(this)) ? reinterpret_cast<const class sender*>(this) : 0;
+}
+
+const receiver* link::receiver() const {
+    return pn_link_is_receiver(pn_cast(this)) ? reinterpret_cast<const class receiver*>(this) : 0;
 }
 
-bool link::has_source() { return pn_link_source(pn_cast(this)); }
-bool link::has_target() { return pn_link_target(pn_cast(this)); }
-bool link::has_remote_source() { return pn_link_remote_source(pn_cast(this)); }
-bool link::has_remote_target() { return pn_link_remote_target(pn_cast(this)); }
+int link::credit() const {
+    return pn_link_credit(pn_cast(this));
+}
 
-terminus& link::source() { return *terminus::cast(pn_link_source(pn_cast(this))); }
-terminus& link::target() { return *terminus::cast(pn_link_target(pn_cast(this))); }
-terminus& link::remote_source() { return *terminus::cast(pn_link_remote_source(pn_cast(this))); }
-terminus& link::remote_target() { return *terminus::cast(pn_link_remote_target(pn_cast(this))); }
+terminus& link::source() const { return *terminus::cast(pn_link_source(pn_cast(this))); }
+terminus& link::target() const { return *terminus::cast(pn_link_target(pn_cast(this))); }
+terminus& link::remote_source() const { return *terminus::cast(pn_link_remote_source(pn_cast(this))); }
+terminus& link::remote_target() const { return *terminus::cast(pn_link_remote_target(pn_cast(this))); }
 
-std::string link::name() { return std::string(pn_link_name(pn_cast(this)));}
+std::string link::name() const { return std::string(pn_link_name(pn_cast(this)));}
 
-class connection &link::connection() {
+class connection &link::connection() const {
     return *connection::cast(pn_session_connection(pn_link_session(pn_cast(this))));
 }
 
-class session &link::session() {
+class session &link::session() const {
     return *session::cast(pn_link_session(pn_cast(this)));
 }
 
@@ -83,5 +86,5 @@ void link::detach_handler() {
     pn_record_set_handler(record, 0);
 }
 
-endpoint::state link::state() { return pn_link_state(pn_cast(this)); }
+endpoint::state link::state() const { return pn_link_state(pn_cast(this)); }
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/message.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/message.cpp b/proton-c/bindings/cpp/src/message.cpp
index b056cd7..79c15b8 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -132,10 +132,10 @@ std::string message::content_encoding() const {
     return s ? std::string(s) : std::string();
 }
 
-void message::expiry(amqp_timestamp t) {
+void message::expiry_time(amqp_timestamp t) {
     pn_message_set_expiry_time(message_, t.milliseconds);
 }
-amqp_timestamp message::expiry() const {
+amqp_timestamp message::expiry_time() const {
     return amqp_timestamp(pn_message_get_expiry_time(message_));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index a9347d1..3e59b1c 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -55,7 +55,7 @@ messaging_event::~messaging_event() {}
 
 messaging_event::event_type messaging_event::type() const { return type_; }
 
-connection &messaging_event::connection() {
+connection &messaging_event::connection() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::connection();
     if (parent_event_)
@@ -63,7 +63,7 @@ connection &messaging_event::connection() {
     throw error(MSG("No connection context for event"));
 }
 
-sender& messaging_event::sender() {
+sender& messaging_event::sender() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::sender();
     if (parent_event_)
@@ -71,7 +71,7 @@ sender& messaging_event::sender() {
     throw error(MSG("No sender context for event"));
 }
 
-receiver& messaging_event::receiver() {
+receiver& messaging_event::receiver() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::receiver();
     if (parent_event_)
@@ -79,7 +79,7 @@ receiver& messaging_event::receiver() {
     throw error(MSG("No receiver context for event"));
 }
 
-link& messaging_event::link() {
+link& messaging_event::link() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::link();
     if (parent_event_)
@@ -87,7 +87,7 @@ link& messaging_event::link() {
     throw error(MSG("No link context for event"));
 }
 
-delivery& messaging_event::delivery() {
+delivery& messaging_event::delivery() const {
     if (type_ == messaging_event::PROTON)
         return proton_event::delivery();
     if (parent_event_)
@@ -95,7 +95,7 @@ delivery& messaging_event::delivery() {
     throw error(MSG("No delivery context for event"));
 }
 
-message &messaging_event::message() {
+message &messaging_event::message() const {
     if (type_ != messaging_event::MESSAGE || !parent_event_)
         throw error(MSG("event type does not provide message"));
     return *message_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.hpp b/proton-c/bindings/cpp/src/messaging_event.hpp
index 1f73477..84cf3f3 100644
--- a/proton-c/bindings/cpp/src/messaging_event.hpp
+++ b/proton-c/bindings/cpp/src/messaging_event.hpp
@@ -88,12 +88,12 @@ class messaging_event : public proton_event
     ~messaging_event();
 
     virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class connection &connection();
-    virtual PN_CPP_EXTERN class sender& sender();
-    virtual PN_CPP_EXTERN class receiver& receiver();
-    virtual PN_CPP_EXTERN class link& link();
-    virtual PN_CPP_EXTERN class delivery& delivery();
-    virtual PN_CPP_EXTERN class message& message();
+    virtual PN_CPP_EXTERN class connection &connection() const;
+    virtual PN_CPP_EXTERN class sender& sender() const;
+    virtual PN_CPP_EXTERN class receiver& receiver() const;
+    virtual PN_CPP_EXTERN class link& link() const;
+    virtual PN_CPP_EXTERN class delivery& delivery() const;
+    virtual PN_CPP_EXTERN class message& message() const;
 
     PN_CPP_EXTERN event_type type() const;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/proton_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.cpp b/proton-c/bindings/cpp/src/proton_event.cpp
index 80e678e..649d908 100644
--- a/proton-c/bindings/cpp/src/proton_event.cpp
+++ b/proton-c/bindings/cpp/src/proton_event.cpp
@@ -46,34 +46,34 @@ int proton_event::type() const { return type_; }
 
 std::string proton_event::name() const { return pn_event_type_name(pn_event_type_t(type_)); }
 
-pn_event_t *proton_event::pn_event() { return pn_event_; }
+pn_event_t *proton_event::pn_event() const { return pn_event_; }
 
-container &proton_event::container() { return container_; }
+container &proton_event::container() const { return container_; }
 
-connection &proton_event::connection() {
+connection &proton_event::connection() const {
     pn_connection_t *conn = pn_event_connection(pn_event());
     if (!conn)
         throw error(MSG("No connection context for this event"));
     return *connection::cast(conn);
 }
 
-link& proton_event::link() {
+link& proton_event::link() const {
     class link *lnk = link::cast(pn_event_link(pn_event()));
     if (!lnk) throw error(MSG("No link context for this event"));
     return *lnk;
 }
 
-sender& proton_event::sender() {
+sender& proton_event::sender() const {
     if (!link().sender()) throw error(MSG("No sender context for this event"));
     return *link().sender();
 }
 
-receiver& proton_event::receiver() {
+receiver& proton_event::receiver() const {
     if (!link().receiver()) throw error(MSG("No receiver context for this event"));
     return *link().receiver();
 }
 
-delivery& proton_event::delivery() {
+delivery& proton_event::delivery() const {
     class delivery *dlv = delivery::cast(pn_event_delivery(pn_event()));
     if (!dlv) throw error(MSG("No delivery context for this event"));
     return *dlv;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/proton_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proton_event.hpp b/proton-c/bindings/cpp/src/proton_event.hpp
index f71af55..66b8ed9 100644
--- a/proton-c/bindings/cpp/src/proton_event.hpp
+++ b/proton-c/bindings/cpp/src/proton_event.hpp
@@ -273,22 +273,22 @@ class proton_event : public event
     ///@}
 
     virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class container &container();
-    virtual PN_CPP_EXTERN class connection &connection();
-    virtual PN_CPP_EXTERN class sender& sender();
-    virtual PN_CPP_EXTERN class receiver& receiver();
-    virtual PN_CPP_EXTERN class link& link();
-    virtual PN_CPP_EXTERN class delivery& delivery();
+    virtual PN_CPP_EXTERN class container &container() const;
+    virtual PN_CPP_EXTERN class connection &connection() const;
+    virtual PN_CPP_EXTERN class sender& sender() const;
+    virtual PN_CPP_EXTERN class receiver& receiver() const;
+    virtual PN_CPP_EXTERN class link& link() const;
+    virtual PN_CPP_EXTERN class delivery& delivery() const;
 
     /** Get type of event */
     PN_CPP_EXTERN event_type type() const;
 
-    PN_CPP_EXTERN pn_event_t* pn_event();
+    PN_CPP_EXTERN pn_event_t* pn_event() const;
 
   protected:
     PN_CPP_EXTERN proton_event(pn_event_t *ce, proton_event::event_type t, class container &c);
   private:
-    pn_event_t *pn_event_;
+    mutable pn_event_t *pn_event_;
     event_type type_;
     class container &container_;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/request_response.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/request_response.cpp b/proton-c/bindings/cpp/src/request_response.cpp
index 9b8207c..38a701c 100644
--- a/proton-c/bindings/cpp/src/request_response.cpp
+++ b/proton-c/bindings/cpp/src/request_response.cpp
@@ -50,7 +50,7 @@ message request_response::call(message &request) {
     return response;
 }
 
-std::string request_response::reply_to() {
+std::string request_response::reply_to() const {
     return receiver_->receiver().remote_source().address();
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/session.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/session.cpp b/proton-c/bindings/cpp/src/session.cpp
index 468e4b8..6d0d955 100644
--- a/proton-c/bindings/cpp/src/session.cpp
+++ b/proton-c/bindings/cpp/src/session.cpp
@@ -33,7 +33,7 @@ void session::open() {
     pn_session_open(pn_cast(this));
 }
 
-connection &session::connection() {
+connection &session::connection() const {
     return *proton::connection::cast(pn_session_connection(pn_cast(this)));
 }
 
@@ -74,9 +74,9 @@ receiver& session::open_receiver(const std::string &addr, bool dynamic, handler
     return rcv;
 }
 
-endpoint::state session::state() { return pn_session_state(pn_cast(this)); }
+endpoint::state session::state() const { return pn_session_state(pn_cast(this)); }
 
-link_range session::find_links(endpoint::state mask)  {
+link_range session::find_links(endpoint::state mask)  const {
     link_range r(connection().find_links(mask));
     link_iterator i(r.begin(), this);
     if (i && this != &i->session())

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/terminus.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/terminus.cpp b/proton-c/bindings/cpp/src/terminus.cpp
index 6d17786..8948eb5 100644
--- a/proton-c/bindings/cpp/src/terminus.cpp
+++ b/proton-c/bindings/cpp/src/terminus.cpp
@@ -24,7 +24,7 @@
 
 namespace proton {
 
-terminus::type_t terminus::type() {
+terminus::type_t terminus::type() const {
     return (type_t) pn_terminus_get_type(pn_cast(this));
 }
 
@@ -32,7 +32,7 @@ void terminus::type(type_t type) {
     pn_terminus_set_type(pn_cast(this), (pn_terminus_type_t) type);
 }
 
-terminus::expiry_policy_t terminus::expiry_policy() {
+terminus::expiry_policy_t terminus::expiry_policy() const {
     return (expiry_policy_t) pn_terminus_get_type(pn_cast(this));
 }
 
@@ -40,7 +40,7 @@ void terminus::expiry_policy(expiry_policy_t policy) {
     pn_terminus_set_expiry_policy(pn_cast(this), (pn_expiry_policy_t) policy);
 }
 
-terminus::distribution_mode_t terminus::distribution_mode() {
+terminus::distribution_mode_t terminus::distribution_mode() const {
     return (distribution_mode_t) pn_terminus_get_type(pn_cast(this));
 }
 
@@ -48,7 +48,7 @@ void terminus::distribution_mode(distribution_mode_t mode) {
     pn_terminus_set_distribution_mode(pn_cast(this), (pn_distribution_mode_t) mode);
 }
 
-std::string terminus::address() {
+std::string terminus::address() const {
     const char *addr = pn_terminus_get_address(pn_cast(this));
     return addr ? std::string(addr) : std::string();
 }
@@ -57,7 +57,7 @@ void terminus::address(const std::string &addr) {
     pn_terminus_set_address(pn_cast(this), addr.c_str());
 }
 
-bool terminus::dynamic() {
+bool terminus::dynamic() const {
     return (type_t) pn_terminus_is_dynamic(pn_cast(this));
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/cf221b45/proton-c/bindings/cpp/src/transport.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/transport.cpp b/proton-c/bindings/cpp/src/transport.cpp
index e128492..58114ae 100644
--- a/proton-c/bindings/cpp/src/transport.cpp
+++ b/proton-c/bindings/cpp/src/transport.cpp
@@ -24,7 +24,7 @@
 
 namespace proton {
 
-connection* transport::connection() {
+connection* transport::connection() const {
     return connection::cast(pn_transport_connection(pn_cast(this)));
 }
 


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


[11/50] [abbrv] qpid-proton git commit: NO-JIRA: Deleted useless file (checked in by mistake)

Posted by ac...@apache.org.
NO-JIRA: Deleted useless file (checked in by mistake)


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

Branch: refs/heads/go1
Commit: 2e8995f3be38d3d6226d526a83c546096947c3e2
Parents: 478ba4e
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 8 10:51:11 2015 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Oct 8 10:51:11 2015 -0400

----------------------------------------------------------------------
 proton-c/bindings/cpp/src/grep | 47 -------------------------------------
 1 file changed, 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2e8995f3/proton-c/bindings/cpp/src/grep
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/grep b/proton-c/bindings/cpp/src/grep
deleted file mode 100644
index 2842f5c..0000000
--- a/proton-c/bindings/cpp/src/grep
+++ /dev/null
@@ -1,47 +0,0 @@
-  /home/aconway/proton/proton-c/bindings/cpp/src:
-  total used in directory 256 available 122608224
-  drwxrwxr-x. 3 aconway aconway  4096 Jun 11 14:47 .
-  drwxrwxr-x. 4 aconway aconway  4096 Jun 11 14:48 ..
-  -rw-rw-r--. 1 aconway aconway  1478 Jun 10 08:40 Acceptor.cpp
-  -rw-rw-r--. 1 aconway aconway  1401 Jun 10 08:40 Acking.cpp
-  -rw-rw-r--. 1 aconway aconway  1295 Jun 11 14:45 proton_bits.cpp
-  -rw-rw-r--. 1 aconway aconway   915 Jun 11 14:44 proton_bits.h
-  drwxrwxr-x. 2 aconway aconway  4096 Jun 10 08:40 blocking
-  -rw-rw-r--. 1 aconway aconway  2390 Jun 10 08:40 Connection.cpp
-  -rw-rw-r--. 1 aconway aconway  4285 Jun 10 08:40 ConnectionImpl.cpp
-  -rw-rw-r--. 1 aconway aconway  2531 Jun 10 08:40 ConnectionImpl.h
-  -rw-rw-r--. 1 aconway aconway  2131 Jun 10 08:40 connector.cpp
-  -rw-rw-r--. 1 aconway aconway  1624 Jun 10 08:40 connector.h
-  -rw-rw-r--. 1 aconway aconway  3188 Jun 10 08:40 Container.cpp
-  -rw-rw-r--. 1 aconway aconway 12183 Jun 10 08:40 ContainerImpl.cpp
-  -rw-rw-r--. 1 aconway aconway  2689 Jun 10 08:40 ContainerImpl.h
-  -rw-rw-r--. 1 aconway aconway  2846 Jun 10 08:40 contexts.cpp
-  -rw-rw-r--. 1 aconway aconway  1764 Jun 10 08:40 contexts.h
-  -rw-rw-r--. 1 aconway aconway  4992 Jun 11 14:45 Data.cpp
-  -rw-rw-r--. 1 aconway aconway  4494 Jun 11 14:46 Decoder.cpp
-  -rw-rw-r--. 1 aconway aconway  1590 Jun 10 08:40 Delivery.cpp
-  -rw-rw-r--. 1 aconway aconway  1752 Jun 10 08:40 Duration.cpp
-  -rw-rw-r--. 1 aconway aconway  3933 Jun 11 14:47 Encoder.cpp
-  -rw-rw-r--. 1 aconway aconway  1125 Jun 10 08:40 Endpoint.cpp
-  -rw-rw-r--. 1 aconway aconway  1882 Jun 10 08:40 Event.cpp
-  -rw-rw-r--. 1 aconway aconway  1315 Jun 10 08:40 Handler.cpp
-  -rw-rw-r--. 1 aconway aconway  4220 Jun 11 11:13 interop_test.cpp
-  -rw-rw-r--. 1 aconway aconway  2821 Jun 10 08:40 Link.cpp
-  -rw-rw-r--. 1 aconway aconway 13358 Jun 10 08:40 Message.cpp
-  -rw-rw-r--. 1 aconway aconway 13424 Jun 10 08:40 MessagingAdapter.cpp
-  -rw-rw-r--. 1 aconway aconway  5864 Jun 10 08:40 MessagingEvent.cpp
-  -rw-rw-r--. 1 aconway aconway  5230 Jun 10 08:40 MessagingHandler.cpp
-  -rw-rw-r--. 1 aconway aconway  2587 Jun 10 08:40 Msg.h
-  -rw-rw-r--. 1 aconway aconway  3000 Jun 10 08:40 PrivateImplRef.h
-  -rw-rw-r--. 1 aconway aconway  6032 Jun 10 08:40 ProtonEvent.cpp
-  -rw-rw-r--. 1 aconway aconway  3818 Jun 10 08:40 ProtonHandler.cpp
-  -rw-rw-r--. 1 aconway aconway  2209 Jun 10 08:40 ProtonImplRef.h
-  -rw-rw-r--. 1 aconway aconway  1396 Jun 10 08:40 Receiver.cpp
-  -rw-rw-r--. 1 aconway aconway  2119 Jun 10 08:40 Sender.cpp
-  -rw-rw-r--. 1 aconway aconway  2031 Jun 10 08:40 Session.cpp
-  -rw-rw-r--. 1 aconway aconway  2850 Jun 10 08:40 Terminus.cpp
-  -rw-rw-r--. 1 aconway aconway  1234 Jun 10 08:40 Transport.cpp
-  -rw-rw-r--. 1 aconway aconway  6251 Jun 10 18:27 types.cpp
-  -rw-rw-r--. 1 aconway aconway  1942 Jun 10 08:40 Url.cpp
-  -rw-rw-r--. 1 aconway aconway  1469 Jun 10 08:40 Url.h
-  -rw-rw-r--. 1 aconway aconway  2211 Jun 11 14:47 Value.cpp


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


[42/50] [abbrv] qpid-proton git commit: PROTON-1028: break cyclical reference in BlockingConnection

Posted by ac...@apache.org.
PROTON-1028: break cyclical reference in BlockingConnection


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

Branch: refs/heads/go1
Commit: c799a295b66891940f40c77b0fd5aca9197bc872
Parents: fc6e0d3
Author: Gordon Sim <gs...@redhat.com>
Authored: Wed Oct 21 20:30:53 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Wed Oct 21 20:31:46 2015 +0100

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/c799a295/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 7421a21..935a9d2 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -249,6 +249,7 @@ class BlockingConnection(Handler):
                 self.container.timeout = container_timeout
         if self.disconnected or self._is_closed():
             self.container.stop()
+            self.conn.handler = None # break cyclical reference
         if self.disconnected and not self._is_closed():
             raise ConnectionException("Connection %s disconnected" % self.url)
 


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


[44/50] [abbrv] qpid-proton git commit: NO-JIRA: Add valgrind suppressions for FreeBSD 10.2

Posted by ac...@apache.org.
NO-JIRA: Add valgrind suppressions for FreeBSD 10.2


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

Branch: refs/heads/go1
Commit: 6a306163f94d363a586b3bf68554e2696cfac826
Parents: 60aafbc
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 22 07:14:10 2015 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Oct 22 14:55:04 2015 -0400

----------------------------------------------------------------------
 tests/python/proton_tests/valgrind.supp | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6a306163/tests/python/proton_tests/valgrind.supp
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/valgrind.supp b/tests/python/proton_tests/valgrind.supp
index 17974aa..3cb5034 100644
--- a/tests/python/proton_tests/valgrind.supp
+++ b/tests/python/proton_tests/valgrind.supp
@@ -32,6 +32,26 @@
 }
 
 {
+   SSL does a number of uninitialized accesses (FreeBSD version)
+   Memcheck:Value8
+   fun:BN_num_bits_word
+   fun:BN_num_bits
+   fun:BN_mod_exp_mont_consttime
+   fun:BN_mod_exp_mont
+   obj:*libcrypto.so*
+   fun:ssl3_ctx_ctrl
+}
+
+{
+   SSL does a number of uninitialized accesses (FreeBSD version)
+   Memcheck:Value8
+   fun:BN_mod_exp_mont_consttime
+   fun:BN_mod_exp_mont
+   obj:*libcrypto.so*
+   fun:ssl3_ctx_ctrl
+}
+
+{
    SSL does a number of uninitialized accesses (expected) 5
    Memcheck:Value4
    fun:BN_mod_exp_mont_consttime


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


[36/50] [abbrv] qpid-proton git commit: PROTON-1024: fix handling of disconnection for BlockingConnection

Posted by ac...@apache.org.
PROTON-1024: fix handling of disconnection for BlockingConnection


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

Branch: refs/heads/go1
Commit: d72f161d1d19aad55622adb6469a98ab9f396c1a
Parents: e547d13
Author: Gordon Sim <gs...@redhat.com>
Authored: Tue Oct 20 18:15:08 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Tue Oct 20 18:15:33 2015 +0100

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d72f161d/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 3682455..7421a21 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -249,7 +249,7 @@ class BlockingConnection(Handler):
                 self.container.timeout = container_timeout
         if self.disconnected or self._is_closed():
             self.container.stop()
-        if self.disconnected:
+        if self.disconnected and not self._is_closed():
             raise ConnectionException("Connection %s disconnected" % self.url)
 
     def on_link_remote_close(self, event):
@@ -265,9 +265,11 @@ class BlockingConnection(Handler):
     def on_transport_tail_closed(self, event):
         self.on_transport_closed(event)
 
+    def on_transport_head_closed(self, event):
+        self.on_transport_closed(event)
+
     def on_transport_closed(self, event):
-        if event.connection.state & Endpoint.LOCAL_ACTIVE:
-            self.disconnected = True
+        self.disconnected = True
 
 class AtomicCount(object):
     def __init__(self, start=0, step=1):


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


[40/50] [abbrv] qpid-proton git commit: NO-JIRA: Add missing environment settings for go examples test.

Posted by ac...@apache.org.
NO-JIRA: Add missing environment settings for go examples 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/fc6e0d34
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/fc6e0d34
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/fc6e0d34

Branch: refs/heads/go1
Commit: fc6e0d34cf5d020e2760b8e2c6135b7b27227fdc
Parents: a16c58a
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Oct 21 13:32:45 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Oct 21 13:32:45 2015 -0400

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


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fc6e0d34/examples/go/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt
index 3235880..c345523 100644
--- a/examples/go/CMakeLists.txt
+++ b/examples/go/CMakeLists.txt
@@ -47,7 +47,7 @@ if(BUILD_GO)
 
   add_test(
     NAME go_example_proton_test
-    COMMAND ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
+    COMMAND ${GO_ENV} ${test_exe} -dir ${CMAKE_CURRENT_BINARY_DIR}/electron -broker ../proton/broker)
 
   list(APPEND ADDITIONAL_MAKE_CLEAN_FILES ${examples})
 endif()


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


[30/50] [abbrv] qpid-proton git commit: PROTON-1023: fix handling of detach following attach for BlockingConnection

Posted by ac...@apache.org.
PROTON-1023: fix handling of detach following attach for BlockingConnection


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

Branch: refs/heads/go1
Commit: ea52a2742e9e2e1607dcb1090e52a6a49bef8aa1
Parents: 52dd42d
Author: Gordon Sim <gs...@redhat.com>
Authored: Mon Oct 19 13:54:35 2015 +0100
Committer: Gordon Sim <gs...@redhat.com>
Committed: Mon Oct 19 13:55:11 2015 +0100

----------------------------------------------------------------------
 proton-c/bindings/python/proton/utils.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ea52a274/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 acc4c34..3682455 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -32,10 +32,12 @@ class BlockingLink(object):
                              msg="Opening link %s" % link.name)
         self._checkClosed()
 
-    def _waitForClosed(self, timeout=1):
-        self.connection.wait(lambda: self.link.state & Endpoint.REMOTE_CLOSED,
-                             timeout=timeout,
-                             msg="Opening link %s" % self.link.name)
+    def _waitForClose(self, timeout=1):
+        try:
+            self.connection.wait(lambda: self.link.state & Endpoint.REMOTE_CLOSED,
+                                 timeout=timeout,
+                                 msg="Opening link %s" % self.link.name)
+        except Timeout as e: pass
         self._checkClosed()
 
     def _checkClosed(self):


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