You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by jr...@apache.org on 2018/04/05 19:34:20 UTC

[45/51] [partial] qpid-proton git commit: PROTON-1728: Reorganize the source tree

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/c/include/proton/messenger.h
----------------------------------------------------------------------
diff --git a/c/include/proton/messenger.h b/c/include/proton/messenger.h
new file mode 100644
index 0000000..0445865
--- /dev/null
+++ b/c/include/proton/messenger.h
@@ -0,0 +1,1058 @@
+#ifndef PROTON_MESSENGER_H
+#define PROTON_MESSENGER_H 1
+
+/*
+ *
+ * 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/import_export.h>
+#include <proton/message.h>
+#include <proton/selectable.h>
+#include <proton/link.h>
+#include <proton/transport.h>
+#include <proton/ssl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ *
+ * @copybrief messenger
+ *
+ * @addtogroup messenger
+ * @{
+ */
+
+/**
+ * A ::pn_messenger_t provides a high level interface for sending and
+ * receiving messages (See ::pn_message_t).
+ *
+ * Every messenger contains a single logical queue of incoming
+ * messages and a single logical queue of outgoing messages. The
+ * messages in these queues may be destined for, or originate from, a
+ * variety of addresses.
+ *
+ * The messenger interface is single-threaded. All methods except one
+ * (::pn_messenger_interrupt()) are intended to be used by one thread
+ * at a time.
+ *
+ *
+ * Address Syntax
+ * ==============
+ *
+ * An address has the following form::
+ *
+ *   [ amqp[s]:// ] [user[:password]@] domain [/[name]]
+ *
+ * Where domain can be one of::
+ *
+ *   host | host:port | ip | ip:port | name
+ *
+ * The following are valid examples of addresses:
+ *
+ *  - example.org
+ *  - example.org:1234
+ *  - amqp://example.org
+ *  - amqps://example.org
+ *  - example.org/incoming
+ *  - amqps://example.org/outgoing
+ *  - amqps://fred:trustno1@example.org
+ *  - 127.0.0.1:1234
+ *  - amqps://127.0.0.1:1234
+ *
+ * Sending & Receiving Messages
+ * ============================
+ *
+ * The messenger API works in conjunction with the ::pn_message_t API.
+ * A ::pn_message_t is a mutable holder of message content.
+ *
+ * The ::pn_messenger_put() operation copies content from the supplied
+ * ::pn_message_t to the outgoing queue, and may send queued messages
+ * if it can do so without blocking. The ::pn_messenger_send()
+ * operation blocks until it has sent the requested number of
+ * messages, or until a timeout interrupts the attempt.
+ *
+ *
+ *   pn_messenger_t *messenger = pn_messenger(NULL);
+ *   pn_message_t *message = pn_message();
+ *   char subject[1024];
+ *   for (int i = 0; i < 3; i++) {
+ *     pn_message_set_address(message, "amqp://host/queue");
+ *     sprintf(subject, "Hello World! %i", i);
+ *     pn_message_set_subject(message, subject);
+ *     pn_messenger_put(messenger, message)
+ *   pn_messenger_send(messenger);
+ *
+ * Similarly, the ::pn_messenger_recv() method receives messages into
+ * the incoming queue, and may block as it attempts to receive up to
+ * the requested number of messages, or until the timeout is reached.
+ * It may receive fewer than the requested number. The
+ * ::pn_messenger_get() method pops the eldest message off the
+ * incoming queue and copies its content into the supplied
+ * ::pn_message_t object. It will not block.
+ *
+ *
+ *   pn_messenger_t *messenger = pn_messenger(NULL);
+ *   pn_message_t *message = pn_message()
+ *   pn_messenger_recv(messenger):
+ *   while (pn_messenger_incoming(messenger) > 0) {
+ *     pn_messenger_get(messenger, message);
+ *     printf("%s", message.subject);
+ *   }
+ *
+ *   Output:
+ *     Hello World 0
+ *     Hello World 1
+ *     Hello World 2
+ *
+ * The blocking flag allows you to turn off blocking behavior
+ * entirely, in which case ::pn_messenger_send() and
+ * ::pn_messenger_recv() will do whatever they can without blocking,
+ * and then return. You can then look at the number of incoming and
+ * outgoing messages to see how much outstanding work still remains.
+ *
+ * Authentication Mechanisms
+ * ========================
+ *
+ * The messenger API authenticates using some specific mechanisms. In prior versions
+ * of Proton the only authentication mechanism available was the PLAIN mechanism
+ * which transports the user's password over the network unencrypted. The Proton versions
+ * 0.10 and newer support other more secure mechanisms which avoid sending the users's
+ * password over the network unencrypted. For backwards compatibility the 0.10 version
+ * of the messenger API will also allow the use of the unencrypted PLAIN mechanism. From the
+ * 0.11 version and onwards you will need to set the flag PN_FLAGS_ALLOW_INSECURE_MECHS to
+ * carry on using the unencrypted PLAIN mechanism.
+ *
+ * The code for this looks like:
+ *
+ *   ...
+ *   pn_messenger_set_flags(messenger, PN_FLAGS_ALLOW_INSECURE_MECHS);
+ *   ...
+ *
+ * Note that the use of the PLAIN mechanism over an SSL connection is allowed as the
+ * password is not sent unencrypted.
+ */
+typedef struct pn_messenger_t pn_messenger_t;
+
+/**
+ * A subscription is a request for incoming messages.
+ *
+ * @todo currently the subscription API is under developed, this
+ * should allow more explicit control over subscription properties and
+ * behaviour
+ */
+typedef struct pn_subscription_t pn_subscription_t;
+
+/**
+ * Trackers provide a lightweight handle used to track the status of
+ * incoming and outgoing deliveries.
+ */
+typedef int64_t pn_tracker_t;
+
+/**
+ * Describes all the possible states for a message associated with a
+ * given tracker.
+ */
+typedef enum {
+  PN_STATUS_UNKNOWN = 0, /**< The tracker is unknown. */
+  PN_STATUS_PENDING = 1, /**< The message is in flight. For outgoing
+                            messages, use ::pn_messenger_buffered to
+                            see if it has been sent or not. */
+  PN_STATUS_ACCEPTED = 2, /**< The message was accepted. */
+  PN_STATUS_REJECTED = 3, /**< The message was rejected. */
+  PN_STATUS_RELEASED = 4, /**< The message was released. */
+  PN_STATUS_MODIFIED = 5, /**< The message was modified. */
+  PN_STATUS_ABORTED = 6, /**< The message was aborted. */
+  PN_STATUS_SETTLED = 7 /**< The remote party has settled the message. */
+} pn_status_t;
+
+/**
+ * Construct a new ::pn_messenger_t with the given name. The name is
+ * global. If a NULL name is supplied, a UUID based name will be
+ * chosen.
+ *
+ * @param[in] name the name of the messenger or NULL
+ *
+ * @return pointer to a new ::pn_messenger_t
+ */
+PNX_EXTERN pn_messenger_t *pn_messenger(const char *name);
+
+/**
+ * Get the name of a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return the name of the messenger
+ */
+PNX_EXTERN const char *pn_messenger_name(pn_messenger_t *messenger);
+
+/**
+ * Sets the path that will be used to get the certificate that will be
+ * used to identify this messenger to its peers. The validity of the
+ * path is not checked by this function.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] certificate a path to a certificate file
+ * @return an error code of zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_certificate(pn_messenger_t *messenger, const char *certificate);
+
+/**
+ * Get the certificate path. This value may be set by
+ * pn_messenger_set_certificate. The default certificate path is null.
+ *
+ * @param[in] messenger the messenger
+ * @return the certificate file path
+ */
+PNX_EXTERN const char *pn_messenger_get_certificate(pn_messenger_t *messenger);
+
+/**
+ * Set path to the private key that was used to sign the certificate.
+ * See ::pn_messenger_set_certificate
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] private_key a path to a private key file
+ * @return an error code of zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_private_key(pn_messenger_t *messenger, const char *private_key);
+
+/**
+ * Gets the private key file for a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return the messenger's private key file path
+ */
+PNX_EXTERN const char *pn_messenger_get_private_key(pn_messenger_t *messenger);
+
+/**
+ * Sets the private key password for a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] password the password for the private key file
+ *
+ * @return an error code of zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_password(pn_messenger_t *messenger, const char *password);
+
+/**
+ * Gets the private key file password for a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return password for the private key file
+ */
+PNX_EXTERN const char *pn_messenger_get_password(pn_messenger_t *messenger);
+
+/**
+ * Sets the trusted certificates database for a messenger.
+ *
+ * The messenger will use this database to validate the certificate
+ * provided by the peer.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] cert_db a path to the certificates database
+ *
+ * @return an error code of zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_trusted_certificates(pn_messenger_t *messenger, const char *cert_db);
+
+/**
+ * Gets the trusted certificates database for a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return path to the trusted certificates database
+ */
+PNX_EXTERN const char *pn_messenger_get_trusted_certificates(pn_messenger_t *messenger);
+
+/**
+ * Set the default timeout for a messenger.
+ *
+ * Any messenger call that blocks during execution will stop blocking
+ * and return control when this timeout is reached, if you have set it
+ * to a value greater than zero. The timeout is expressed in
+ * milliseconds.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] timeout a new timeout for the messenger, in milliseconds
+ * @return an error code or zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_timeout(pn_messenger_t *messenger, int timeout);
+
+/**
+ * Gets the timeout for a messenger object.
+ *
+ * See ::pn_messenger_set_timeout() for details.
+ *
+ * @param[in] messenger a messenger object
+ * @return the timeout for the messenger, in milliseconds
+ */
+PNX_EXTERN int pn_messenger_get_timeout(pn_messenger_t *messenger);
+
+/**
+ * Check if a messenger is in blocking mode.
+ *
+ * @param[in] messenger a messenger object
+ * @return true if blocking has been enabled, false otherwise
+ */
+PNX_EXTERN bool pn_messenger_is_blocking(pn_messenger_t *messenger);
+
+/**
+ * Enable or disable blocking behavior for a messenger during calls to
+ * ::pn_messenger_send and ::pn_messenger_recv.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] blocking the value of the blocking flag
+ * @return an error code or zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_blocking(pn_messenger_t *messenger, bool blocking);
+
+/**
+ * Check if a messenger is in passive mode.
+ *
+ * A messenger that is in passive mode will never attempt to perform
+ * I/O internally, but instead will make all internal file descriptors
+ * accessible through ::pn_messenger_selectable() to be serviced
+ * externally. This can be useful for integrating messenger into an
+ * external event loop.
+ *
+ * @param[in] messenger a messenger object
+ * @return true if the messenger is in passive mode, false otherwise
+ */
+PNX_EXTERN bool pn_messenger_is_passive(pn_messenger_t *messenger);
+
+/**
+ * Set the passive mode for a messenger.
+ *
+ * See ::pn_messenger_is_passive() for details on passive mode.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] passive true to enable passive mode, false to disable
+ * passive mode
+ * @return an error code or zero on success
+ */
+PNX_EXTERN int pn_messenger_set_passive(pn_messenger_t *messenger, bool passive);
+
+/** Frees a Messenger.
+ *
+ * @param[in] messenger the messenger to free (or NULL), no longer
+ *                      valid on return
+ */
+PNX_EXTERN void pn_messenger_free(pn_messenger_t *messenger);
+
+/**
+ * Get the code for a messenger's most recent error.
+ *
+ * The error code is initialized to zero at messenger creation. The
+ * error number is "sticky" i.e. error codes are not reset to 0 at the
+ * end of successful API calls. You can use ::pn_messenger_error to
+ * access the messenger's error object and clear explicitly if
+ * desired.
+ *
+ * @param[in] messenger the messenger to check for errors
+ * @return an error code or zero if there is no error
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_errno(pn_messenger_t *messenger);
+
+/**
+ * Get a messenger's error object.
+ *
+ * Returns a pointer to a pn_error_t that is valid until the messenger
+ * is freed. The pn_error_* API allows you to access the text, error
+ * number, and lets you set or clear the error code explicitly.
+ *
+ * @param[in] messenger the messenger to check for errors
+ * @return a pointer to the messenger's error descriptor
+ * @see error.h
+ */
+PNX_EXTERN pn_error_t *pn_messenger_error(pn_messenger_t *messenger);
+
+/**
+ * Get the size of a messenger's outgoing window.
+ *
+ * The size of the outgoing window limits the number of messages whose
+ * status you can check with a tracker. A message enters this window
+ * when you call pn_messenger_put on the message. For example, if your
+ * outgoing window size is 10, and you call pn_messenger_put 12 times,
+ * new status information will no longer be available for the first 2
+ * messages.
+ *
+ * The default outgoing window size is 0.
+ *
+ * @param[in] messenger a messenger object
+ * @return the outgoing window for the messenger
+ */
+PNX_EXTERN int pn_messenger_get_outgoing_window(pn_messenger_t *messenger);
+
+/**
+ * Set the size of a messenger's outgoing window.
+ *
+ * See ::pn_messenger_get_outgoing_window() for details.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] window the number of deliveries to track
+ * @return an error or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_set_outgoing_window(pn_messenger_t *messenger, int window);
+
+/**
+ * Get the size of a messenger's incoming window.
+ *
+ * The size of a messenger's incoming window limits the number of
+ * messages that can be accepted or rejected using trackers. Messages
+ * *do not* enter this window when they have been received
+ * (::pn_messenger_recv) onto you incoming queue. Messages only enter
+ * this window only when you access them using pn_messenger_get. If
+ * your incoming window size is N, and you get N+1 messages without
+ * explicitly accepting or rejecting the oldest message, then it will
+ * be implicitly accepted when it falls off the edge of the incoming
+ * window.
+ *
+ * The default incoming window size is 0.
+ *
+ * @param[in] messenger a messenger object
+ * @return the incoming window for the messenger
+ */
+PNX_EXTERN int pn_messenger_get_incoming_window(pn_messenger_t *messenger);
+
+/**
+ * Set the size of a messenger's incoming window.
+ *
+ * See ::pn_messenger_get_incoming_window() for details.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] window the number of deliveries to track
+ * @return an error or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_set_incoming_window(pn_messenger_t *messenger,
+                                               int window);
+
+/**
+ * Currently a no-op placeholder. For future compatibility, do not
+ * send or receive messages before starting the messenger.
+ *
+ * @param[in] messenger the messenger to start
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_start(pn_messenger_t *messenger);
+
+/**
+ * Stops a messenger.
+ *
+ * Stopping a messenger will perform an orderly shutdown of all
+ * underlying connections. This may require some time. If the
+ * messenger is in non blocking mode (see ::pn_messenger_is_blocking),
+ * this operation will return PN_INPROGRESS if it cannot finish
+ * immediately. In that case, you can use ::pn_messenger_stopped() to
+ * determine when the messenger has finished stopping.
+ *
+ * @param[in] messenger the messenger to stop
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_stop(pn_messenger_t *messenger);
+
+/**
+ * Returns true if a messenger is in the stopped state. This function
+ * does not block.
+ *
+ * @param[in] messenger the messenger to stop
+ *
+ */
+PNX_EXTERN bool pn_messenger_stopped(pn_messenger_t *messenger);
+
+/**
+ * Subscribes a messenger to messages from the specified source.
+ *
+ * @param[in] messenger the messenger to subscribe
+ * @param[in] source
+ * @return a subscription
+ */
+PNX_EXTERN pn_subscription_t *pn_messenger_subscribe(pn_messenger_t *messenger, const char *source);
+
+/**
+ * Subscribes a messenger to messages from the specified source with the given
+ * timeout for the subscription's lifetime.
+ *
+ * @param[in] messenger the messenger to subscribe
+ * @param[in] source
+ * @param[in] timeout the maximum time to keep the subscription alive once the
+ *            link is closed.
+ * @return a subscription
+ */
+PNX_EXTERN pn_subscription_t *
+pn_messenger_subscribe_ttl(pn_messenger_t *messenger, const char *source,
+                           pn_seconds_t timeout);
+
+/**
+ * Get a link based on link name and whether the link is a sender or receiver
+ *
+ * @param[in] messenger the messenger to get the link from
+ * @param[in] address the link address that identifies the link to receive
+ * @param[in] sender true if the link is a sender, false if the link is a
+ *            receiver
+ * @return a link, or NULL if no link matches the address / sender parameters
+ */
+PNX_EXTERN pn_link_t *pn_messenger_get_link(pn_messenger_t *messenger,
+                                           const char *address, bool sender);
+
+/**
+ * Get a subscription's application context.
+ *
+ * See ::pn_subscription_set_context().
+ *
+ * @param[in] sub a subscription object
+ * @return the subscription's application context
+ */
+PNX_EXTERN void *pn_subscription_get_context(pn_subscription_t *sub);
+
+/**
+ * Set an application context for a subscription.
+ *
+ * @param[in] sub a subscription object
+ * @param[in] context the application context for the subscription
+ */
+PNX_EXTERN void pn_subscription_set_context(pn_subscription_t *sub, void *context);
+
+/**
+ * Get the source address of a subscription.
+ *
+ * @param[in] sub a subscription object
+ * @return the subscription's source address
+ */
+PNX_EXTERN const char *pn_subscription_address(pn_subscription_t *sub);
+
+/**
+ * Puts a message onto the messenger's outgoing queue. The message may
+ * also be sent if transmission would not cause blocking. This call
+ * will not block.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] msg a message to put on the messenger's outgoing queue
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_put(pn_messenger_t *messenger, pn_message_t *msg);
+
+/**
+ * Track the status of a delivery.
+ *
+ * Get the current status of the delivery associated with the supplied
+ * tracker. This may return PN_STATUS_UNKOWN if the tracker has fallen
+ * outside the incoming/outgoing tracking windows of the messenger.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] tracker the tracker identifying the delivery
+ * @return a status code for the delivery
+ */
+PNX_EXTERN pn_status_t pn_messenger_status(pn_messenger_t *messenger, pn_tracker_t tracker);
+
+/**
+ * Get delivery information about a delivery.
+ *
+ * Returns the delivery information associated with the supplied tracker.
+ * This may return NULL if the tracker has fallen outside the
+ * incoming/outgoing tracking windows of the messenger.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] tracker the tracker identifying the delivery
+ * @return a pn_delivery_t representing the delivery.
+ */
+PNX_EXTERN pn_delivery_t *pn_messenger_delivery(pn_messenger_t *messenger,
+                                               pn_tracker_t tracker);
+
+/**
+ * Check if the delivery associated with a given tracker is still
+ * waiting to be sent.
+ *
+ * Note that returning false does not imply that the delivery was
+ * actually sent over the wire.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] tracker the tracker identifying the delivery
+ *
+ * @return true if the delivery is still buffered
+ */
+PNX_EXTERN bool pn_messenger_buffered(pn_messenger_t *messenger, pn_tracker_t tracker);
+
+/**
+ * Frees a Messenger from tracking the status associated with a given
+ * tracker. Use the PN_CUMULATIVE flag to indicate everything up to
+ * (and including) the given tracker.
+ *
+ * @param[in] messenger the Messenger
+ * @param[in] tracker identifies a delivery
+ * @param[in] flags 0 or PN_CUMULATIVE
+ *
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_settle(pn_messenger_t *messenger, pn_tracker_t tracker, int flags);
+
+/**
+ * Get a tracker for the outgoing message most recently given to
+ * pn_messenger_put.
+ *
+ * This tracker may be used with pn_messenger_status to determine the
+ * delivery status of the message, as long as the message is still
+ * within your outgoing window.
+ *
+ * @param[in] messenger the messenger
+ *
+ * @return a pn_tracker_t or an undefined value if pn_messenger_get
+ *         has never been called for the given messenger
+ */
+PNX_EXTERN pn_tracker_t pn_messenger_outgoing_tracker(pn_messenger_t *messenger);
+
+/**
+ * Sends or receives any outstanding messages queued for a messenger.
+ * This will block for the indicated timeout.
+ *
+ * @param[in] messenger the Messenger
+ * @param[in] timeout the maximum time to block in milliseconds, -1 ==
+ * forever, 0 == do not block
+ *
+ * @return 0 if no work to do, < 0 if error, or 1 if work was done.
+ */
+PNX_EXTERN int pn_messenger_work(pn_messenger_t *messenger, int timeout);
+
+/**
+ * Interrupt a messenger object that may be blocking in another
+ * thread.
+ *
+ * The messenger interface is single-threaded. This is the only
+ * messenger function intended to be concurrently called from another
+ * thread. It will interrupt any messenger function which is currently
+ * blocking and cause it to return with a status of ::PN_INTR.
+ *
+ * @param[in] messenger the Messenger to interrupt
+ */
+PNX_EXTERN int pn_messenger_interrupt(pn_messenger_t *messenger);
+
+/**
+ * Send messages from a messenger's outgoing queue.
+ *
+ * If a messenger is in blocking mode (see
+ * ::pn_messenger_is_blocking()), this operation will block until N
+ * messages have been sent from the outgoing queue. A value of -1 for
+ * N means "all messages in the outgoing queue". See below for a full
+ * definition of what sent from the outgoing queue means.
+ *
+ * Any blocking will end once the messenger's configured timeout (if
+ * any) has been reached. When this happens an error code of
+ * ::PN_TIMEOUT is returned.
+ *
+ * If the messenger is in non blocking mode, this call will return an
+ * error code of ::PN_INPROGRESS if it is unable to send the requested
+ * number of messages without blocking.
+ *
+ * A message is considered to be sent from the outgoing queue when its
+ * status has been fully determined. This does not necessarily mean
+ * the message was successfully sent to the final recipient though,
+ * for example of the receiver rejects the message, the final status
+ * will be ::PN_STATUS_REJECTED. Similarly, if a message is sent to an
+ * invalid address, it may be removed from the outgoing queue without
+ * ever even being transmitted. In this case the final status will be
+ * ::PN_STATUS_ABORTED.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] n the number of messages to send
+ *
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_send(pn_messenger_t *messenger, int n);
+
+/**
+ * Retrieve messages into a messenger's incoming queue.
+ *
+ * Instructs a messenger to receive up to @c limit messages into the
+ * incoming message queue of a messenger. If @c limit is -1, the
+ * messenger will receive as many messages as it can buffer
+ * internally. If the messenger is in blocking mode, this call will
+ * block until at least one message is available in the incoming
+ * queue.
+ *
+ * Each call to pn_messenger_recv replaces the previous receive
+ * operation, so pn_messenger_recv(messenger, 0) will cancel any
+ * outstanding receive.
+ *
+ * After receiving messages onto your incoming queue use
+ * ::pn_messenger_get() to access message content.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] limit the maximum number of messages to receive or -1 to
+ *                  to receive as many messages as it can buffer
+ *                  internally.
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_recv(pn_messenger_t *messenger, int limit);
+
+/**
+ * Get the capacity of the incoming message queue of a messenger.
+ *
+ * Note this count does not include those messages already available
+ * on the incoming queue (@see pn_messenger_incoming()). Rather it
+ * returns the number of incoming queue entries available for
+ * receiving messages.
+ *
+ * @param[in] messenger the messenger
+ */
+PNX_EXTERN int pn_messenger_receiving(pn_messenger_t *messenger);
+
+/**
+ * Get the next message from the head of a messenger's incoming queue.
+ *
+ * The get operation copies the message data from the head of the
+ * messenger's incoming queue into the provided ::pn_message_t object.
+ * If provided ::pn_message_t pointer is NULL, the head message will be
+ * discarded. This operation will return ::PN_EOS if there are no
+ * messages left on the incoming queue.
+ *
+ * @param[in] messenger a messenger object
+ * @param[out] message upon return contains the message from the head of the queue
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_get(pn_messenger_t *messenger, pn_message_t *message);
+
+/**
+ * Get a tracker for the message most recently retrieved by
+ * ::pn_messenger_get().
+ *
+ * A tracker for an incoming message allows you to accept or reject
+ * the associated message. It can also be used for cumulative
+ * accept/reject operations for the associated message and all prior
+ * messages as well.
+ *
+ * @param[in] messenger a messenger object
+ * @return a pn_tracker_t or an undefined value if pn_messenger_get
+ *         has never been called for the given messenger
+ */
+PNX_EXTERN pn_tracker_t pn_messenger_incoming_tracker(pn_messenger_t *messenger);
+
+/**
+ * Get the subscription of the message most recently retrieved by ::pn_messenger_get().
+ *
+ * This operation will return NULL if ::pn_messenger_get() has never
+ * been successfully called.
+ *
+ * @param[in] messenger a messenger object
+ * @return a pn_subscription_t or NULL
+ */
+PNX_EXTERN pn_subscription_t *pn_messenger_incoming_subscription(pn_messenger_t *messenger);
+
+/**
+ * Indicates that an accept or reject should operate cumulatively.
+ */
+#define PN_CUMULATIVE (0x1)
+
+/**
+ * Signal successful processing of message(s).
+ *
+ * With no flags this operation will signal the sender that the
+ * message referenced by the tracker was accepted. If the
+ * PN_CUMULATIVE flag is set, this operation will also reject all
+ * pending messages prior to the message indicated by the tracker.
+ *
+ * Note that when a message is accepted or rejected multiple times,
+ * either explicitly, or implicitly through use of the ::PN_CUMULATIVE
+ * flag, only the first outcome applies. For example if a sequence of
+ * three messages are received: M1, M2, M3, and M2 is rejected, and M3
+ * is cumulatively accepted, M2 will remain rejected and only M1 and
+ * M3 will be considered accepted.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] tracker an incoming tracker
+ * @param[in] flags 0 or PN_CUMULATIVE
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_accept(pn_messenger_t *messenger, pn_tracker_t tracker, int flags);
+
+/**
+ * Signal unsuccessful processing of message(s).
+ *
+ * With no flags this operation will signal the sender that the
+ * message indicated by the tracker was rejected. If the PN_CUMULATIVE
+ * flag is used this operation will also reject all pending messages
+ * prior to the message indicated by the tracker.
+ *
+ * Note that when a message is accepted or rejected multiple times,
+ * either explicitly, or implicitly through use of the ::PN_CUMULATIVE
+ * flag, only the first outcome applies. For example if a sequence of
+ * three messages are received: M1, M2, M3, and M2 is accepted, and M3
+ * is cumulatively rejected, M2 will remain accepted and only M1 and
+ * M3 will be considered rejected.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] tracker an incoming tracker
+ * @param[in] flags 0 or PN_CUMULATIVE
+ * @return an error code or zero on success
+ * @see error.h
+ */
+PNX_EXTERN int pn_messenger_reject(pn_messenger_t *messenger, pn_tracker_t tracker, int flags);
+
+/**
+ * Get  link for the message referenced by the given tracker.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] tracker a tracker object
+ * @return a pn_link_t or NULL if the link could not be determined.
+ */
+PNX_EXTERN pn_link_t *pn_messenger_tracker_link(pn_messenger_t *messenger,
+                                               pn_tracker_t tracker);
+
+/**
+ * Get the number of messages in the outgoing message queue of a
+ * messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return the outgoing queue depth
+ */
+PNX_EXTERN int pn_messenger_outgoing(pn_messenger_t *messenger);
+
+/**
+ * Get the number of messages in the incoming message queue of a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return the incoming queue depth
+ */
+PNX_EXTERN int pn_messenger_incoming(pn_messenger_t *messenger);
+
+//! Adds a routing rule to a Messenger's internal routing table.
+//!
+//! The route procedure may be used to influence how a messenger will
+//! internally treat a given address or class of addresses. Every call
+//! to the route procedure will result in messenger appending a routing
+//! rule to its internal routing table.
+//!
+//! Whenever a message is presented to a messenger for delivery, it
+//! will match the address of this message against the set of routing
+//! rules in order. The first rule to match will be triggered, and
+//! instead of routing based on the address presented in the message,
+//! the messenger will route based on the address supplied in the rule.
+//!
+//! The pattern matching syntax supports two types of matches, a '%'
+//! will match any character except a '/', and a '*' will match any
+//! character including a '/'.
+//!
+//! A routing address is specified as a normal AMQP address, however it
+//! may additionally use substitution variables from the pattern match
+//! that triggered the rule.
+//!
+//! Any message sent to "foo" will be routed to "amqp://foo.com":
+//!
+//!   pn_messenger_route("foo", "amqp://foo.com");
+//!
+//! Any message sent to "foobar" will be routed to
+//! "amqp://foo.com/bar":
+//!
+//!   pn_messenger_route("foobar", "amqp://foo.com/bar");
+//!
+//! Any message sent to bar/&lt;path&gt; will be routed to the corresponding
+//! path within the amqp://bar.com domain:
+//!
+//!   pn_messenger_route("bar/*", "amqp://bar.com/$1");
+//!
+//! Route all messages over TLS:
+//!
+//!   pn_messenger_route("amqp:*", "amqps:$1")
+//!
+//! Supply credentials for foo.com:
+//!
+//!   pn_messenger_route("amqp://foo.com/*", "amqp://user:password@foo.com/$1");
+//!
+//! Supply credentials for all domains:
+//!
+//!   pn_messenger_route("amqp://*", "amqp://user:password@$1");
+//!
+//! Route all addresses through a single proxy while preserving the
+//! original destination:
+//!
+//!   pn_messenger_route("amqp://%/*", "amqp://user:password@proxy/$1/$2");
+//!
+//! Route any address through a single broker:
+//!
+//!   pn_messenger_route("*", "amqp://user:password@broker/$1");
+//!
+//! @param[in] messenger the Messenger
+//! @param[in] pattern a glob pattern
+//! @param[in] address an address indicating alternative routing
+//!
+//! @return an error code or zero on success
+//! @see error.h
+PNX_EXTERN int pn_messenger_route(pn_messenger_t *messenger, const char *pattern,
+                                 const char *address);
+
+/**
+ * Rewrite message addresses prior to transmission.
+ *
+ * This operation is similar to pn_messenger_route, except that the
+ * destination of the message is determined before the message address
+ * is rewritten.
+ *
+ * The outgoing address is only rewritten after routing has been
+ * finalized.  If a message has an outgoing address of
+ * "amqp://0.0.0.0:5678", and a rewriting rule that changes its
+ * outgoing address to "foo", it will still arrive at the peer that
+ * is listening on "amqp://0.0.0.0:5678", but when it arrives there,
+ * the receiver will see its outgoing address as "foo".
+ *
+ * The default rewrite rule removes username and password from
+ * addresses before they are transmitted.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] pattern a glob pattern to select messages
+ * @param[in] address an address indicating outgoing address rewrite
+ * @return an error code or zero on success
+ */
+PNX_EXTERN int pn_messenger_rewrite(pn_messenger_t *messenger, const char *pattern,
+                                   const char *address);
+
+/**
+ * Extract selectables from a passive messenger.
+ *
+ * A messenger that is in passive mode (see
+ * ::pn_messenger_is_passive()) will never attempt to perform any I/O
+ * internally, but instead make its internal file descriptors
+ * available for external processing via the
+ * ::pn_messenger_selectable() operation.
+ *
+ * An application wishing to perform I/O on behalf of a passive
+ * messenger must extract all available selectables by calling this
+ * operation until it returns NULL. The selectable interface may then
+ * be used by the application to perform I/O outside the messenger.
+ *
+ * All selectables returned by this operation must be serviced until
+ * they reach a terminal state and then freed. See
+ * `pn_selectable_is_terminal()` for more details.
+ *
+ * By default any given selectable will only ever be returned once by
+ * this operation, however if the selectable's registered flag is set
+ * to true (see `pn_selectable_set_registered()`), then the selectable
+ * will be returned whenever its interest set may have changed.
+ *
+ * @param[in] messenger a messenger object
+ * @return the next selectable, or NULL if there are none left
+ */
+PNX_EXTERN pn_selectable_t *pn_messenger_selectable(pn_messenger_t *messenger);
+
+/**
+ * Get the nearest deadline for selectables associated with a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @return the nearest deadline
+ */
+PNX_EXTERN pn_timestamp_t pn_messenger_deadline(pn_messenger_t *messenger);
+
+#define PN_FLAGS_CHECK_ROUTES                                                   \
+  (0x1) /**< Messenger flag to indicate that a call                             \
+             to pn_messenger_start should check that                            \
+             any defined routes are valid */
+
+#define PN_FLAGS_ALLOW_INSECURE_MECHS                                           \
+  (0x2) /**< Messenger flag to indicate that the PLAIN                          \
+             mechanism is allowed on an unencrypted                             \
+             connection */
+
+/**
+ * Sets control flags to enable additional function for the Messenger.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] flags 0 or PN_FLAGS_CHECK_ROUTES
+ *
+ * @return an error code of zero if there is no error
+ */
+PNX_EXTERN int pn_messenger_set_flags(pn_messenger_t *messenger,
+                                     const int flags);
+
+/**
+ * Gets the flags for a Messenger.
+ *
+ * @param[in] messenger the messenger
+ * @return The flags set for the messenger
+ */
+PNX_EXTERN int pn_messenger_get_flags(pn_messenger_t *messenger);
+
+/**
+ * Set the local sender settle mode for the underlying link.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] mode the sender settle mode
+ */
+PNX_EXTERN int pn_messenger_set_snd_settle_mode(pn_messenger_t *messenger,
+                                               const pn_snd_settle_mode_t mode);
+
+/**
+ * Set the local receiver settle mode for the underlying link.
+ *
+ * @param[in] messenger the messenger
+ * @param[in] mode the receiver settle mode
+ */
+PNX_EXTERN int pn_messenger_set_rcv_settle_mode(pn_messenger_t *messenger,
+                                               const pn_rcv_settle_mode_t mode);
+
+/**
+ * Set the tracer associated with a messenger.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] tracer the tracer callback
+ */
+PNX_EXTERN void pn_messenger_set_tracer(pn_messenger_t *messenger,
+                                       pn_tracer_t tracer);
+
+/**
+ * Gets the remote idle timeout for the specified remote service address
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] address of remote service whose idle timeout is required
+ * @return the timeout in milliseconds or -1 if an error occurs
+ */
+PNX_EXTERN pn_millis_t
+    pn_messenger_get_remote_idle_timeout(pn_messenger_t *messenger,
+                                         const char *address);
+
+/**
+ * Sets the SSL peer authentication mode required when a trust
+ * certificate is used.
+ *
+ * @param[in] messenger a messenger object
+ * @param[in] mode the mode required (see pn_ssl_verify_mode_t
+ *             enum for valid values)
+ * @return 0 if successful or -1 if an error occurs
+ */
+PNX_EXTERN int
+pn_messenger_set_ssl_peer_authentication_mode(pn_messenger_t *messenger,
+                                              const pn_ssl_verify_mode_t mode);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* messenger.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/c/include/proton/netaddr.h
----------------------------------------------------------------------
diff --git a/c/include/proton/netaddr.h b/c/include/proton/netaddr.h
new file mode 100644
index 0000000..4d422cf
--- /dev/null
+++ b/c/include/proton/netaddr.h
@@ -0,0 +1,126 @@
+#ifndef PROTON_NETADDR_H
+#define PROTON_NETADDR_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/import_export.h>
+#include <proton/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ *
+ * @copybrief pn_netaddr_t
+ *
+ * @addtogroup proactor
+ * @{
+ */
+
+/**
+ * **Unsettled API** - The network address of a proactor transport.
+ */
+typedef struct pn_netaddr_t pn_netaddr_t;
+
+/**
+ * Format a network address as a human-readable string in `buf`.
+ *
+ * @return the length of the string (excluding trailing '\0'), if >= size then
+ * the address was truncated.
+ */
+PNP_EXTERN int pn_netaddr_str(const pn_netaddr_t *addr, char *buf, size_t size);
+
+/**
+ * Get the local address of a transport. Return `NULL` if not available.
+ * Pointer is invalid after the transport closes (PN_TRANSPORT_CLOSED event is handled)
+ */
+PNP_EXTERN const pn_netaddr_t *pn_transport_local_addr(pn_transport_t *t);
+
+/**
+ * Get the local address of a transport. Return `NULL` if not available.
+ * Pointer is invalid after the transport closes (PN_TRANSPORT_CLOSED event is handled)
+ */
+PNP_EXTERN const pn_netaddr_t *pn_transport_remote_addr(pn_transport_t *t);
+
+/**
+ * Get the listening addresses of a listener.
+ * Addresses are only available after the @ref PN_LISTENER_OPEN event for the listener.
+ *
+ * A listener can have more than one address for several reasons:
+ * - DNS host records may indicate more than one address
+ * - On a multi-homed host, listening on the default host "" will listen on all local addresses.
+ * - Some IPv4/IPV6 configurations may expand a single address into a v4/v6 pair.
+ *
+ * pn_netaddr_next() will iterate over the addresses in the list.
+ *
+ * @param l points to the listener
+ * @return The first listening address or NULL if there are no addresses are available.
+ * Use pn_netaddr_next() to iterate over the list.
+ * Pointer is invalid after the listener closes (PN_LISTENER_CLOSED event is handled)
+ */
+PNP_EXTERN const pn_netaddr_t *pn_listener_addr(pn_listener_t *l);
+
+/**
+ * @return Pointer to the next address in a list of addresses, NULL if at the end of the list or
+ * if this address is not part of a list.
+ */
+PNP_EXTERN const pn_netaddr_t *pn_netaddr_next(const pn_netaddr_t *na);
+
+struct sockaddr;
+
+/**
+ * On POSIX or Windows, get the underlying `struct sockaddr`.
+ * Return NULL if not available.
+ */
+PNP_EXTERN const struct sockaddr *pn_netaddr_sockaddr(const pn_netaddr_t *na);
+
+/**
+ * On POSIX or Windows, get the size of the underlying `struct sockaddr`.
+ * Return 0 if not available.
+ */
+PNP_EXTERN size_t pn_netaddr_socklen(const pn_netaddr_t *na);
+
+/**
+ * Get the host and port name from na as separate strings.
+ * Returns 0 if successful, non-0 on error.
+ */
+PNP_EXTERN int pn_netaddr_host_port(const pn_netaddr_t* na, char *host, size_t hlen, char *port, size_t plen);
+
+/* These function names will be deprecated in a future release of proton */
+/**  @deprecated @{ */
+/* PN_DEPRECATED("use pn_transport_local_addr") */
+PNP_EXTERN const pn_netaddr_t *pn_netaddr_local(pn_transport_t *t);
+/* PN_DEPRECATED("use pn_transport_remote_addr()") */
+PNP_EXTERN const pn_netaddr_t *pn_netaddr_remote(pn_transport_t *t);
+/* PN_DEPRECATED("use pn_listener_addr()") */
+PNP_EXTERN const pn_netaddr_t *pn_netaddr_listening(pn_listener_t *l);
+/** @} */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROTON_NETADDR_H */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/c/include/proton/object.h
----------------------------------------------------------------------
diff --git a/c/include/proton/object.h b/c/include/proton/object.h
new file mode 100644
index 0000000..2761091
--- /dev/null
+++ b/c/include/proton/object.h
@@ -0,0 +1,345 @@
+#ifndef PROTON_OBJECT_H
+#define PROTON_OBJECT_H 1
+
+/*
+ *
+ * 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/cid.h>
+#include <proton/types.h>
+#include <stdarg.h>
+#include <proton/type_compat.h>
+#include <stddef.h>
+#include <proton/import_export.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @cond INTERNAL
+ */
+
+typedef const void* pn_handle_t;
+typedef intptr_t pn_shandle_t;
+
+typedef struct pn_class_t pn_class_t;
+typedef struct pn_string_t pn_string_t;
+typedef struct pn_list_t pn_list_t;
+typedef struct pn_map_t pn_map_t;
+typedef struct pn_hash_t pn_hash_t;
+typedef void *(*pn_iterator_next_t)(void *state);
+typedef struct pn_iterator_t pn_iterator_t;
+typedef struct pn_record_t pn_record_t;
+
+struct pn_class_t {
+  const char *name;
+  const pn_cid_t cid;
+  void *(*newinst)(const pn_class_t *, size_t);
+  void (*initialize)(void *);
+  void (*incref)(void *);
+  void (*decref)(void *);
+  int (*refcount)(void *);
+  void (*finalize)(void *);
+  void (*free)(void *);
+  const pn_class_t *(*reify)(void *);
+  uintptr_t (*hashcode)(void *);
+  intptr_t (*compare)(void *, void *);
+  int (*inspect)(void *, pn_string_t *);
+};
+
+/* Hack alert: Declare these as arrays so we can treat the name of the single
+   object as the address */
+PN_EXTERN extern const pn_class_t PN_OBJECT[];
+PN_EXTERN extern const pn_class_t PN_VOID[];
+PN_EXTERN extern const pn_class_t PN_WEAKREF[];
+
+#define PN_CLASSDEF(PREFIX)                                               \
+static void PREFIX ## _initialize_cast(void *object) {                    \
+  PREFIX ## _initialize((PREFIX ## _t *) object);                         \
+}                                                                         \
+                                                                          \
+static void PREFIX ## _finalize_cast(void *object) {                      \
+  PREFIX ## _finalize((PREFIX ## _t *) object);                           \
+}                                                                         \
+                                                                          \
+static uintptr_t PREFIX ## _hashcode_cast(void *object) {                 \
+  uintptr_t (*fp)(PREFIX ## _t *) = PREFIX ## _hashcode;                  \
+  if (fp) {                                                               \
+    return fp((PREFIX ## _t *) object);                                   \
+  } else {                                                                \
+    return (uintptr_t) object;                                            \
+  }                                                                       \
+}                                                                         \
+                                                                          \
+static intptr_t PREFIX ## _compare_cast(void *a, void *b) {               \
+  intptr_t (*fp)(PREFIX ## _t *, PREFIX ## _t *) = PREFIX ## _compare;    \
+  if (fp) {                                                               \
+    return fp((PREFIX ## _t *) a, (PREFIX ## _t *) b);                    \
+  } else {                                                                \
+    return (intptr_t) a - (intptr_t) b;                                   \
+  }                                                                       \
+}                                                                         \
+                                                                          \
+static int PREFIX ## _inspect_cast(void *object, pn_string_t *str) {      \
+  int (*fp)(PREFIX ## _t *, pn_string_t *) = PREFIX ## _inspect;          \
+  if (fp) {                                                               \
+    return fp((PREFIX ## _t *) object, str);                              \
+  } else {                                                                \
+    return pn_string_addf(str, "%s<%p>", #PREFIX, object);                \
+  }                                                                       \
+}                                                                         \
+                                                                          \
+const pn_class_t *PREFIX ## __class(void) {                               \
+  static const pn_class_t clazz = {                                       \
+    #PREFIX,                                                              \
+    CID_ ## PREFIX,                                                       \
+    pn_object_new,                                                        \
+    PREFIX ## _initialize_cast,                                           \
+    pn_object_incref,                                                     \
+    pn_object_decref,                                                     \
+    pn_object_refcount,                                                   \
+    PREFIX ## _finalize_cast,                                             \
+    pn_object_free,                                                       \
+    pn_object_reify,                                                      \
+    PREFIX ## _hashcode_cast,                                             \
+    PREFIX ## _compare_cast,                                              \
+    PREFIX ## _inspect_cast                                               \
+  };                                                                      \
+  return &clazz;                                                          \
+}                                                                         \
+                                                                          \
+PREFIX ## _t *PREFIX ## _new(void) {                                      \
+  return (PREFIX ## _t *) pn_class_new(PREFIX ## __class(),               \
+                                       sizeof(PREFIX ## _t));             \
+}
+
+#define PN_CLASS(PREFIX) {                      \
+    #PREFIX,                                    \
+    CID_ ## PREFIX,                             \
+    pn_object_new,                              \
+    PREFIX ## _initialize,                      \
+    pn_object_incref,                           \
+    pn_object_decref,                           \
+    pn_object_refcount,                         \
+    PREFIX ## _finalize,                        \
+    pn_object_free,                             \
+    pn_object_reify,                            \
+    PREFIX ## _hashcode,                        \
+    PREFIX ## _compare,                         \
+    PREFIX ## _inspect                          \
+}
+
+#define PN_METACLASS(PREFIX) {                  \
+    #PREFIX,                                    \
+    CID_ ## PREFIX,                             \
+    PREFIX ## _new,                             \
+    PREFIX ## _initialize,                      \
+    PREFIX ## _incref,                          \
+    PREFIX ## _decref,                          \
+    PREFIX ## _refcount,                        \
+    PREFIX ## _finalize,                        \
+    PREFIX ## _free,                            \
+    PREFIX ## _reify,                           \
+    PREFIX ## _hashcode,                        \
+    PREFIX ## _compare,                         \
+    PREFIX ## _inspect                          \
+}
+
+/* Class to identify a plain C struct in a pn_event_t. No refcounting or memory management. */
+#define PN_STRUCT_CLASSDEF(PREFIX, CID)                                 \
+  const pn_class_t *PREFIX ## __class(void);                            \
+  static const pn_class_t *PREFIX ## _reify(void *p) { return PREFIX ## __class(); } \
+  const pn_class_t *PREFIX  ##  __class(void) {                         \
+  static const pn_class_t clazz = {                                     \
+    #PREFIX,                                                            \
+    CID,                                                                \
+    NULL, /*_new*/                                                      \
+    NULL, /*_initialize*/                                               \
+    pn_void_incref,                                                     \
+    pn_void_decref,                                                     \
+    pn_void_refcount,                                                   \
+    NULL, /* _finalize */                                               \
+    NULL, /* _free */                                                   \
+    PREFIX ## _reify,                                                   \
+    pn_void_hashcode,                                                   \
+    pn_void_compare,                                                    \
+    pn_void_inspect                                                     \
+    };                                                                  \
+  return &clazz;                                                        \
+  }
+
+PN_EXTERN pn_cid_t pn_class_id(const pn_class_t *clazz);
+PN_EXTERN const char *pn_class_name(const pn_class_t *clazz);
+PN_EXTERN void *pn_class_new(const pn_class_t *clazz, size_t size);
+
+/* pn_incref, pn_decref and pn_refcount are for internal use by the proton
+   library, the should not be called by application code. Application code
+   should use the appropriate pn_*_free function (pn_link_free, pn_session_free
+   etc.) when it is finished with a proton value. Proton values should only be
+   used when handling a pn_event_t that refers to them.
+*/
+PN_EXTERN void *pn_class_incref(const pn_class_t *clazz, void *object);
+PN_EXTERN int pn_class_refcount(const pn_class_t *clazz, void *object);
+PN_EXTERN int pn_class_decref(const pn_class_t *clazz, void *object);
+
+PN_EXTERN void pn_class_free(const pn_class_t *clazz, void *object);
+
+PN_EXTERN const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object);
+PN_EXTERN uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object);
+PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
+PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
+PN_EXTERN int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst);
+
+PN_EXTERN void *pn_void_new(const pn_class_t *clazz, size_t size);
+PN_EXTERN void pn_void_incref(void *object);
+PN_EXTERN void pn_void_decref(void *object);
+PN_EXTERN int pn_void_refcount(void *object);
+PN_EXTERN uintptr_t pn_void_hashcode(void *object);
+PN_EXTERN intptr_t pn_void_compare(void *a, void *b);
+PN_EXTERN int pn_void_inspect(void *object, pn_string_t *dst);
+
+PN_EXTERN void *pn_object_new(const pn_class_t *clazz, size_t size);
+PN_EXTERN const pn_class_t *pn_object_reify(void *object);
+PN_EXTERN void pn_object_incref(void *object);
+PN_EXTERN int pn_object_refcount(void *object);
+PN_EXTERN void pn_object_decref(void *object);
+PN_EXTERN void pn_object_free(void *object);
+
+PN_EXTERN void *pn_incref(void *object);
+PN_EXTERN int pn_decref(void *object);
+PN_EXTERN int pn_refcount(void *object);
+PN_EXTERN void pn_free(void *object);
+PN_EXTERN const pn_class_t *pn_class(void* object);
+PN_EXTERN uintptr_t pn_hashcode(void *object);
+PN_EXTERN intptr_t pn_compare(void *a, void *b);
+PN_EXTERN bool pn_equals(void *a, void *b);
+PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
+
+#define PN_REFCOUNT (0x1)
+
+PN_EXTERN pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity);
+PN_EXTERN size_t pn_list_size(pn_list_t *list);
+PN_EXTERN void *pn_list_get(pn_list_t *list, int index);
+PN_EXTERN void pn_list_set(pn_list_t *list, int index, void *value);
+PN_EXTERN int pn_list_add(pn_list_t *list, void *value);
+PN_EXTERN void *pn_list_pop(pn_list_t *list);
+PN_EXTERN ssize_t pn_list_index(pn_list_t *list, void *value);
+PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
+PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
+PN_EXTERN void pn_list_clear(pn_list_t *list);
+PN_EXTERN void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter);
+PN_EXTERN void pn_list_minpush(pn_list_t *list, void *value);
+PN_EXTERN void *pn_list_minpop(pn_list_t *list);
+
+#define PN_REFCOUNT_KEY (0x2)
+#define PN_REFCOUNT_VALUE (0x4)
+
+PN_EXTERN pn_map_t *pn_map(const pn_class_t *key, const pn_class_t *value,
+                           size_t capacity, float load_factor);
+PN_EXTERN size_t pn_map_size(pn_map_t *map);
+PN_EXTERN int pn_map_put(pn_map_t *map, void *key, void *value);
+PN_EXTERN void *pn_map_get(pn_map_t *map, void *key);
+PN_EXTERN void pn_map_del(pn_map_t *map, void *key);
+PN_EXTERN pn_handle_t pn_map_head(pn_map_t *map);
+PN_EXTERN pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry);
+PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
+PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
+
+PN_EXTERN pn_hash_t *pn_hash(const pn_class_t *clazz, size_t capacity, float load_factor);
+PN_EXTERN size_t pn_hash_size(pn_hash_t *hash);
+PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
+PN_EXTERN void *pn_hash_get(pn_hash_t *hash, uintptr_t key);
+PN_EXTERN void pn_hash_del(pn_hash_t *hash, uintptr_t key);
+PN_EXTERN pn_handle_t pn_hash_head(pn_hash_t *hash);
+PN_EXTERN pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry);
+PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
+PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
+
+PN_EXTERN pn_string_t *pn_string(const char *bytes);
+PN_EXTERN pn_string_t *pn_stringn(const char *bytes, size_t n);
+PN_EXTERN const char *pn_string_get(pn_string_t *string);
+PN_EXTERN size_t pn_string_size(pn_string_t *string);
+PN_EXTERN int pn_string_set(pn_string_t *string, const char *bytes);
+PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
+PN_EXTERN ssize_t pn_string_put(pn_string_t *string, char *dst);
+PN_EXTERN void pn_string_clear(pn_string_t *string);
+PN_EXTERN int pn_string_format(pn_string_t *string, const char *format, ...)
+#ifdef __GNUC__
+  __attribute__ ((format (printf, 2, 3)))
+#endif
+    ;
+PN_EXTERN int pn_string_vformat(pn_string_t *string, const char *format, va_list ap);
+PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
+#ifdef __GNUC__
+  __attribute__ ((format (printf, 2, 3)))
+#endif
+    ;
+PN_EXTERN int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap);
+PN_EXTERN int pn_string_grow(pn_string_t *string, size_t capacity);
+PN_EXTERN char *pn_string_buffer(pn_string_t *string);
+PN_EXTERN size_t pn_string_capacity(pn_string_t *string);
+PN_EXTERN int pn_string_resize(pn_string_t *string, size_t size);
+PN_EXTERN int pn_string_copy(pn_string_t *string, pn_string_t *src);
+
+PN_EXTERN pn_iterator_t *pn_iterator(void);
+PN_EXTERN void *pn_iterator_start(pn_iterator_t *iterator,
+                                  pn_iterator_next_t next, size_t size);
+PN_EXTERN void *pn_iterator_next(pn_iterator_t *iterator);
+
+#define PN_LEGCTX ((pn_handle_t) 0)
+
+/**
+   PN_HANDLE is a trick to define a unique identifier by using the address of a static variable.
+   You MUST NOT use it in a .h file, since it must be defined uniquely in one compilation unit.
+   Your .h file can provide access to the handle (if needed) via a function. For example:
+
+       /// my_thing.h
+       pn_handle_t get_my_thing(void);
+
+       /// my_thing.c
+       PN_HANDLE(MY_THING);
+       pn_handle_t get_my_thing(void) { return MY_THING; }
+
+   Note that the name "MY_THING" is not exported and is not required to be
+   unique except in the .c file. The linker will guarantee that the *address* of
+   MY_THING, as returned by get_my_thing() *is* unique across the entire linked
+   executable.
+ */
+#define PN_HANDLE(name) \
+  static const char _PN_HANDLE_ ## name = 0; \
+  static const pn_handle_t name = ((pn_handle_t) &_PN_HANDLE_ ## name);
+
+PN_EXTERN pn_record_t *pn_record(void);
+PN_EXTERN void pn_record_def(pn_record_t *record, pn_handle_t key, const pn_class_t *clazz);
+PN_EXTERN bool pn_record_has(pn_record_t *record, pn_handle_t key);
+PN_EXTERN void *pn_record_get(pn_record_t *record, pn_handle_t key);
+PN_EXTERN void pn_record_set(pn_record_t *record, pn_handle_t key, void *value);
+PN_EXTERN void pn_record_clear(pn_record_t *record);
+
+/**
+ * @endcond
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* object.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/c/include/proton/proactor.h
----------------------------------------------------------------------
diff --git a/c/include/proton/proactor.h b/c/include/proton/proactor.h
new file mode 100644
index 0000000..be20ff1
--- /dev/null
+++ b/c/include/proton/proactor.h
@@ -0,0 +1,375 @@
+#ifndef PROTON_PROACTOR_H
+#define PROTON_PROACTOR_H 1
+
+/*
+ * 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/condition.h>
+#include <proton/event.h>
+#include <proton/import_export.h>
+#include <proton/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ *
+ * @copybrief proactor
+ *
+ * @addtogroup proactor
+ * @{
+ *
+ * The proactor associates an abstract AMQP protocol @ref connection
+ * with a concrete IO @ref transport implementation for outgoing and
+ * incoming connections. pn_proactor_wait() returns @ref
+ * proactor_events to application threads for handling.
+ *
+ * The `pn_proactor_*` functions are thread-safe, but to handle @ref
+ * proactor_events you must also use the @ref core APIs, which are
+ * not. @ref core objects associated with different connections can be
+ * used concurrently, but objects associated with a single connection
+ * can only be used from their own thread.
+ *
+ * The proactor *serializes* @ref proactor_events for each connection
+ * - it never returns @ref proactor_events for the same connection
+ * concurrently in different threads. Event-handling code can safely
+ * use any @ref core object obtained from the current event. You can
+ * attach application data to @ref core objects (for example with
+ * pn_connection_attachments()).
+ *
+ * pn_connection_wake() allows any thread to "wake up" a
+ * connection. It causes pn_proactor_wait() to return a @ref
+ * PN_CONNECTION_WAKE event that is serialized with the connection's
+ * other @ref proactor_events. You can use this to implement
+ * communication between different connections, or from non-proactor
+ * threads.
+ *
+ * Serialization and pn_connection_wake() simplify building
+ * applications with a shared thread pool, which serialize work per
+ * connection. Many other variations are possible, but you are
+ * responsible for any additional synchronization needed.
+ */
+
+/**
+ * Size of buffer that can hold the largest connection or listening address.
+ */
+#define PN_MAX_ADDR 1060
+
+/**
+ * Format a host:port address string for pn_proactor_connect2() or pn_proactor_listen2()
+ *
+ * @param[out] addr address is copied to this buffer, with trailing '\0'
+ * @param[in] size  size of addr buffer
+ * @param[in] host network host name, DNS name or IP address
+ * @param[in] port network service name or decimal port number, e.g. "amqp" or "5672"
+ * @return the length of network address (excluding trailing '\0'), if >= size
+ * then the address was truncated
+ */
+PNP_EXTERN int pn_proactor_addr(char *addr, size_t size, const char *host, const char *port);
+
+/**
+ * Create a proactor. Must be freed with pn_proactor_free()
+ */
+PNP_EXTERN pn_proactor_t *pn_proactor(void);
+
+/**
+ * Free the proactor. Abort open connections/listeners, clean up all resources.
+ */
+PNP_EXTERN void pn_proactor_free(pn_proactor_t *proactor);
+
+/**
+ * Connect @p transport to @p addr and bind to @p connection.
+ * Errors are returned as  @ref PN_TRANSPORT_CLOSED events by pn_proactor_wait().
+ *
+ * @note Thread-safe
+ *
+ * @param[in] proactor the proactor object
+ *
+ * @param[in] connection If NULL a new connection is created.
+ * @p proactor *takes ownership* of @p connection and will
+ * automatically call pn_connection_free() after the final @ref
+ * PN_TRANSPORT_CLOSED event is handled, or when pn_proactor_free() is
+ * called. You can prevent the automatic free with
+ * pn_proactor_release_connection()
+ *
+ * @param[in] transport If NULL a new transport is created.
+ * @p proactor *takes ownership* of @p transport, it will be freed even
+ * if pn_proactor_release_connection() is called.
+ *
+ * @param[in] addr the "host:port" network address, constructed by pn_proactor_addr()
+ * An empty host will connect to the local host via the default protocol (IPV6 or IPV4).
+ * An empty port will connect to the standard AMQP port (5672).
+ *
+ */
+PNP_EXTERN void pn_proactor_connect2(pn_proactor_t *proactor, pn_connection_t *connection, pn_transport_t *transport, const char *addr);
+
+/**
+ * @deprecated Equivalent to pn_proactor_connect2(proactor, connection, NULL, addr)
+ */
+PNP_EXTERN void pn_proactor_connect(pn_proactor_t *proactor, pn_connection_t *connection, const char *addr);
+
+/**
+ * Start listening for incoming connections.
+ *
+ * pn_proactor_wait() will return a @ref PN_LISTENER_OPEN event when the
+ * listener is ready to accept connections, or a PN_LISTENER_CLOSE if the listen
+ * operation fails. If the listen failed, pn_listener_condition() will be set.
+ *
+ * When the listener is closed by pn_listener_close(), or because of an error, a
+ * PN_LISTENER_CLOSE event will be returned and pn_listener_condition() will be set
+ * for an error.
+ *
+ * @note Thread-safe
+ *
+ * @param[in] proactor the proactor object
+ *
+ * @param[in] listener @p proactor *takes ownership* of @p listener, and will
+ * automatically call pn_listener_free() after the final PN_LISTENER_CLOSE event
+ * is handled, or when pn_proactor_free() is called.
+ *
+ * @param[in] addr the "host:port" network address, constructed by pn_proactor_addr()
+ * An empty host will listen for all protocols (IPV6 and IPV4) on all local interfaces.
+ * An empty port will listen on the standard AMQP port (5672).
+ *
+ * @param[in] backlog of un-handled connection requests to allow before refusing
+ * connections. If @p addr resolves to multiple interface/protocol combinations,
+ * the backlog applies to each separately.
+ */
+PNP_EXTERN void pn_proactor_listen(pn_proactor_t *proactor, pn_listener_t *listener, const char *addr, int backlog);
+
+/**
+ * Disconnect all connections and listeners belonging to the proactor.
+ *
+ * @ref PN_LISTENER_CLOSE, @ref PN_TRANSPORT_CLOSED and other @ref proactor_events are
+ * generated as usual.
+ *
+ * A @ref PN_PROACTOR_INACTIVE event will be generated when all connections and
+ * listeners are disconnected and no timeout is pending. The event will also be
+ * generated if there are no listeners, connections or timeout when
+ * pn_proactor_disconnect() is called.
+ *
+ * Creating new connections and listeners after this call and before the
+ * PN_PROACTOR_INACTIVE event may prevent the proactor from becoming inactive.
+ * After the PN_PROACTOR_INACTIVE event, the proactor can be used normally.
+ *
+ * @note Thread-safe
+ *
+ * @param proactor the proactor
+ *
+ * @param condition if not NULL the condition data is copied to each
+ * disconnected transports and listener and is available in the close event.
+ */
+PNP_EXTERN void pn_proactor_disconnect(pn_proactor_t *proactor, pn_condition_t *condition);
+
+/**
+ * Wait until there are @ref proactor_events to handle.
+ *
+ * You must call pn_proactor_done() when you are finished with the batch, you
+ * must not use the batch pointer after calling pn_proactor_done().
+ *
+ * Normally it is most efficient to handle the entire batch in the calling
+ * thread and then call pn_proactor_done(), but see pn_proactor_done() for more options.
+ *
+ * pn_proactor_get() is a non-blocking version of this call.
+ *
+ * @note Thread-safe
+ *
+ * @return a non-empty batch of events that must be processed in sequence.
+ *
+ */
+PNP_EXTERN pn_event_batch_t *pn_proactor_wait(pn_proactor_t *proactor);
+
+/**
+ * Return @ref proactor_events if any are available immediately.  If not, return NULL.
+ * If the return value is not NULL, the behavior is the same as pn_proactor_wait()
+ *
+ * @note Thread-safe
+ */
+PNP_EXTERN pn_event_batch_t *pn_proactor_get(pn_proactor_t *proactor);
+
+/**
+ * Call when finished handling a batch of events.
+ *
+ * Must be called exactly once to match each call to pn_proactor_wait().
+ *
+ * @note Thread-safe: May be called from any thread provided the exactly once
+ * rule is respected.
+ */
+PNP_EXTERN void pn_proactor_done(pn_proactor_t *proactor, pn_event_batch_t *events);
+
+/**
+ * Return a @ref PN_PROACTOR_INTERRUPT event as soon as possible.
+ *
+ * At least one PN_PROACTOR_INTERRUPT event will be returned after this call.
+ * Interrupts can be "coalesced" - if several pn_proactor_interrupt() calls
+ * happen close together, there may be only one PN_PROACTOR_INTERRUPT event that
+ * occurs after all of them.
+ *
+ * @note Thread-safe and async-signal-safe: can be called in a signal handler.
+ * This is the only pn_proactor function that is async-signal-safe.
+ */
+PNP_EXTERN void pn_proactor_interrupt(pn_proactor_t *proactor);
+
+/**
+ * Return a @ref PN_PROACTOR_TIMEOUT after @p timeout milliseconds elapse. If no
+ * threads are blocked in pn_proactor_wait() when the timeout elapses, the event
+ * will be delivered to the next available thread.
+ *
+ * Calling pn_proactor_set_timeout() again before the PN_PROACTOR_TIMEOUT
+ * is delivered will cancel the previous timeout and deliver an event only after
+ * the new timeout.
+ *
+ * @note Thread-safe
+ */
+PNP_EXTERN void pn_proactor_set_timeout(pn_proactor_t *proactor, pn_millis_t timeout);
+
+/**
+ * Cancel the pending timeout set by pn_proactor_set_timeout(). Does nothing
+ * if no timeout is set.
+ *
+ * @note Thread-safe
+ */
+PNP_EXTERN void pn_proactor_cancel_timeout(pn_proactor_t *proactor);
+
+/**
+ * Release ownership of @p connection, disassociate it from its proactor.
+ *
+ * The connection and related objects (@ref session "sessions", @ref link "links"
+ * and so on) remain intact, but the transport is closed and unbound. The
+ * proactor will not return any more events for this connection. The caller must
+ * call pn_connection_free(), either directly or indirectly by re-using @p
+ * connection in another call to pn_proactor_connect2() or pn_proactor_listen2().
+ *
+ * @note **Not thread-safe**.  Call this function from a connection
+ * event handler.
+ *
+ * @note If @p connection does not belong to a proactor, this call does nothing.
+ *
+ * @note This has nothing to do with pn_connection_release().
+ */
+PNP_EXTERN void pn_proactor_release_connection(pn_connection_t *connection);
+
+/**
+ * Return a @ref PN_CONNECTION_WAKE event for @p connection as soon as possible.
+ *
+ * At least one wake event will be returned, serialized with other @ref proactor_events
+ * for the same connection.  Wakes can be "coalesced" - if several
+ * pn_connection_wake() calls happen close together, there may be only one
+ * PN_CONNECTION_WAKE event that occurs after all of them.
+ *
+ * @note If @p connection does not belong to a proactor, this call does nothing.
+ *
+ * @note Thread-safe
+ */
+PNP_EXTERN void pn_connection_wake(pn_connection_t *connection);
+
+/**
+ * Return the proactor associated with a connection.
+ *
+ * @note **Not thread-safe**
+ *
+ * @return the proactor or NULL if the connection does not belong to a proactor.
+ */
+PNP_EXTERN pn_proactor_t *pn_connection_proactor(pn_connection_t *connection);
+
+/**
+ * Return the proactor associated with an event.
+ *
+ * @note **Not thread-safe**
+ *
+ * @return the proactor or NULL if the connection does not belong to a proactor.
+ */
+PNP_EXTERN pn_proactor_t *pn_event_proactor(pn_event_t *event);
+
+/**
+ * Get the real elapsed time since an arbitrary point in the past in milliseconds.
+ *
+ * This may be used as a portable way to get a process-local timestamp for the
+ * current time. It is monotonically increasing and will never go backwards.
+ *
+ * Note: this is not a suitable value for an AMQP timestamp to be sent as part
+ * of a message.  Such a timestamp should use the real time in milliseconds
+ * since the epoch.
+ *
+ * @note Thread-safe
+ */
+PNP_EXTERN pn_millis_t pn_proactor_now(void);
+
+/**
+ * @}
+ */
+
+/**
+ * pn_proactor_wait() returns a subset of the event types defined by
+ * @ref pn_event_type_t.  The PN_REACTOR_\*, PN_SELECTABLE_\*, and
+ * PN_\*_FINAL events are not returned.
+ *
+ * @addtogroup proactor_events
+ * @{
+ *
+ * Enumeration | Brief description, see @ref pn_event_type_t for more
+ * :-- | :--
+ * @ref PN_CONNECTION_INIT | @copybrief PN_CONNECTION_INIT
+ * @ref PN_CONNECTION_BOUND |  @copybrief PN_CONNECTION_BOUND
+ * @ref PN_TIMER_TASK | @copybrief PN_TIMER_TASK
+ * @ref PN_CONNECTION_INIT | @copybrief PN_CONNECTION_INIT
+ * @ref PN_CONNECTION_BOUND | @copybrief PN_CONNECTION_BOUND
+ * @ref PN_CONNECTION_UNBOUND | @copybrief PN_CONNECTION_UNBOUND
+ * @ref PN_CONNECTION_LOCAL_OPEN | @copybrief PN_CONNECTION_LOCAL_OPEN
+ * @ref PN_CONNECTION_REMOTE_OPEN | @copybrief PN_CONNECTION_REMOTE_OPEN
+ * @ref PN_CONNECTION_LOCAL_CLOSE | @copybrief PN_CONNECTION_LOCAL_CLOSE
+ * @ref PN_CONNECTION_REMOTE_CLOSE | @copybrief PN_CONNECTION_REMOTE_CLOSE
+ * @ref PN_SESSION_INIT | @copybrief PN_SESSION_INIT
+ * @ref PN_SESSION_LOCAL_OPEN | @copybrief PN_SESSION_LOCAL_OPEN
+ * @ref PN_SESSION_REMOTE_OPEN | @copybrief PN_SESSION_REMOTE_OPEN
+ * @ref PN_SESSION_LOCAL_CLOSE | @copybrief PN_SESSION_LOCAL_CLOSE
+ * @ref PN_SESSION_REMOTE_CLOSE | @copybrief PN_SESSION_REMOTE_CLOSE
+ * @ref PN_LINK_INIT | @copybrief PN_LINK_INIT
+ * @ref PN_LINK_LOCAL_OPEN | @copybrief PN_LINK_LOCAL_OPEN
+ * @ref PN_LINK_REMOTE_OPEN | @copybrief PN_LINK_REMOTE_OPEN
+ * @ref PN_LINK_LOCAL_CLOSE | @copybrief PN_LINK_LOCAL_CLOSE
+ * @ref PN_LINK_REMOTE_CLOSE | @copybrief PN_LINK_REMOTE_CLOSE
+ * @ref PN_LINK_LOCAL_DETACH | @copybrief PN_LINK_LOCAL_DETACH
+ * @ref PN_LINK_REMOTE_DETACH | @copybrief PN_LINK_REMOTE_DETACH
+ * @ref PN_LINK_FLOW | @copybrief PN_LINK_FLOW
+ * @ref PN_DELIVERY | @copybrief PN_DELIVERY
+ * @ref PN_TRANSPORT | @copybrief PN_TRANSPORT
+ * @ref PN_TRANSPORT_AUTHENTICATED | @copybrief PN_TRANSPORT_AUTHENTICATED
+ * @ref PN_TRANSPORT_ERROR | @copybrief PN_TRANSPORT_ERROR
+ * @ref PN_TRANSPORT_HEAD_CLOSED | @copybrief PN_TRANSPORT_HEAD_CLOSED
+ * @ref PN_TRANSPORT_TAIL_CLOSED | @copybrief PN_TRANSPORT_TAIL_CLOSED
+ * @ref PN_TRANSPORT_CLOSED | The final event for a proactor connection, the transport is closed.
+ * @ref PN_LISTENER_OPEN | @copybrief PN_LISTENER_OPEN
+ * @ref PN_LISTENER_ACCEPT | @copybrief PN_LISTENER_ACCEPT
+ * @ref PN_LISTENER_CLOSE | @copybrief PN_LISTENER_CLOSE
+ * @ref PN_PROACTOR_INTERRUPT | @copybrief PN_PROACTOR_INTERRUPT
+ * @ref PN_PROACTOR_TIMEOUT | @copybrief PN_PROACTOR_TIMEOUT
+ * @ref PN_PROACTOR_INACTIVE | @copybrief PN_PROACTOR_INACTIVE
+ * @ref PN_CONNECTION_WAKE | @copybrief PN_CONNECTION_WAKE
+ *
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* proactor.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/37136940/c/include/proton/reactor.h
----------------------------------------------------------------------
diff --git a/c/include/proton/reactor.h b/c/include/proton/reactor.h
new file mode 100644
index 0000000..e8a8864
--- /dev/null
+++ b/c/include/proton/reactor.h
@@ -0,0 +1,189 @@
+#ifndef PROTON_REACTOR_H
+#define PROTON_REACTOR_H 1
+
+/*
+ *
+ * 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/import_export.h>
+#include <proton/type_compat.h>
+#include <proton/error.h>
+#include <proton/event.h>
+#include <proton/selectable.h>
+#include <proton/ssl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @cond INTERNAL
+ */
+
+typedef struct pn_reactor_t pn_reactor_t;
+typedef struct pn_acceptor_t pn_acceptor_t;
+typedef struct pn_timer_t pn_timer_t;
+typedef struct pn_task_t pn_task_t;
+
+PNX_EXTERN pn_handler_t *pn_handler(void (*dispatch)(pn_handler_t *, pn_event_t *, pn_event_type_t));
+PNX_EXTERN pn_handler_t *pn_handler_new(void (*dispatch)(pn_handler_t *, pn_event_t *, pn_event_type_t), size_t size,
+                                       void (*finalize)(pn_handler_t *));
+PNX_EXTERN void pn_handler_free(pn_handler_t *handler);
+PNX_EXTERN void *pn_handler_mem(pn_handler_t *handler);
+PNX_EXTERN void pn_handler_add(pn_handler_t *handler, pn_handler_t *child);
+PNX_EXTERN void pn_handler_clear(pn_handler_t *handler);
+PNX_EXTERN void pn_handler_dispatch(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type);
+
+PNX_EXTERN pn_reactor_t *pn_reactor(void);
+PNX_EXTERN pn_record_t *pn_reactor_attachments(pn_reactor_t *reactor);
+PNX_EXTERN pn_millis_t pn_reactor_get_timeout(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_set_timeout(pn_reactor_t *reactor, pn_millis_t timeout);
+PNX_EXTERN pn_timestamp_t pn_reactor_mark(pn_reactor_t *reactor);
+PNX_EXTERN pn_timestamp_t pn_reactor_now(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_yield(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_free(pn_reactor_t *reactor);
+PNX_EXTERN pn_collector_t *pn_reactor_collector(pn_reactor_t *reactor);
+PNX_EXTERN pn_handler_t *pn_reactor_get_global_handler(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_set_global_handler(pn_reactor_t *reactor, pn_handler_t *handler);
+PNX_EXTERN pn_handler_t *pn_reactor_get_handler(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_set_handler(pn_reactor_t *reactor, pn_handler_t *handler);
+PNX_EXTERN pn_list_t *pn_reactor_children(pn_reactor_t *reactor);
+PNX_EXTERN pn_selectable_t *pn_reactor_selectable(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_update(pn_reactor_t *reactor, pn_selectable_t *selectable);
+PNX_EXTERN pn_acceptor_t *pn_reactor_acceptor(pn_reactor_t *reactor, const char *host, const char *port,
+                                             pn_handler_t *handler);
+PNX_EXTERN pn_error_t *pn_reactor_error(pn_reactor_t *reactor);
+
+/**
+ * Create an outgoing connection that will be managed by the reactor.
+ *
+ * The reactor's pn_iohandler will create a socket connection to the host
+ * once the connection is opened.
+ *
+ * @param[in] reactor the reactor that will own the connection.
+ * @param[in] host the address of the remote host. e.g. "localhost"
+ * @param[in] port the port to connect to. e.g. "5672"
+ * @param[in] handler the handler that will process all events generated by
+ * this connection.
+ * @return a connection object
+ */
+PNX_EXTERN pn_connection_t *pn_reactor_connection_to_host(pn_reactor_t *reactor,
+                                                         const char *host,
+                                                         const char *port,
+                                                         pn_handler_t *handler);
+
+/**
+ * **Deprecated** - Use ::pn_reactor_connection_to_host().
+ *
+ * Create an outgoing connection that will be managed by the reactor.
+ *
+ * The host address for the connection must be set via
+ * ::pn_reactor_set_connection_host() prior to opening the connection.
+ * Typically this can be done by the handler when processing the
+ * ::PN_CONNECTION_INIT event.
+ *
+ * @param[in] reactor the reactor that will own the connection.
+ * @param[in] handler the handler that will process all events generated by
+ * this connection.
+ * @return a connection object
+ */
+PNX_EXTERN pn_connection_t *pn_reactor_connection(pn_reactor_t *reactor,
+                                                 pn_handler_t *handler);
+
+/**
+ * Change the host address used by an outgoing reactor connection.
+ *
+ * The address is used by the reactor's iohandler to create an outgoing socket
+ * connection.  This must be set prior to (re)opening the connection.
+ *
+ * @param[in] reactor the reactor that owns the connection.
+ * @param[in] connection the connection created by the reactor.
+ * @param[in] host the network address or DNS name of the host to connect to.
+ * @param[in] port the network port to use. Optional - default is "5672"
+ */
+PNX_EXTERN void pn_reactor_set_connection_host(pn_reactor_t *reactor,
+                                              pn_connection_t *connection,
+                                              const char *host,
+                                              const char *port);
+/**
+ * Retrieve the peer host address for a reactor connection.
+ *
+ * This may be used to retrieve the host address used by the reactor to
+ * establish the outgoing socket connection.  In the case of an accepted
+ * connection the returned value is the address of the remote.
+ *
+ * @note Note that the returned address may be in numeric IP format.
+ *
+ * The pointer returned by this operation is valid until either the address is
+ * changed via ::pn_reactor_set_connection_host() or the connection object
+ * is freed.
+ *
+ * @param[in] reactor the reactor that owns the connection.
+ * @param[in] connection the reactor connection
+ * @return a C string containing the address in URL format or NULL if no
+ * address available.  ::pn_url_parse() may be used to create a Proton pn_url_t
+ * instance from the returned value.
+ */
+PNX_EXTERN const char *pn_reactor_get_connection_address(pn_reactor_t *reactor,
+                                                        pn_connection_t *connection);
+
+PNX_EXTERN int pn_reactor_wakeup(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_start(pn_reactor_t *reactor);
+PNX_EXTERN bool pn_reactor_quiesced(pn_reactor_t *reactor);
+PNX_EXTERN bool pn_reactor_process(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_stop(pn_reactor_t *reactor);
+PNX_EXTERN void pn_reactor_run(pn_reactor_t *reactor);
+PNX_EXTERN pn_task_t *pn_reactor_schedule(pn_reactor_t *reactor, int delay, pn_handler_t *handler);
+
+
+PNX_EXTERN void pn_acceptor_set_ssl_domain(pn_acceptor_t *acceptor, pn_ssl_domain_t *domain);
+PNX_EXTERN void pn_acceptor_close(pn_acceptor_t *acceptor);
+PNX_EXTERN pn_acceptor_t *pn_connection_acceptor(pn_connection_t *connection);
+
+PNX_EXTERN pn_timer_t *pn_timer(pn_collector_t *collector);
+PNX_EXTERN pn_timestamp_t pn_timer_deadline(pn_timer_t *timer);
+PNX_EXTERN void pn_timer_tick(pn_timer_t *timer, pn_timestamp_t now);
+PNX_EXTERN pn_task_t *pn_timer_schedule(pn_timer_t *timer, pn_timestamp_t deadline);
+PNX_EXTERN int pn_timer_tasks(pn_timer_t *timer);
+
+PNX_EXTERN pn_record_t *pn_task_attachments(pn_task_t *task);
+PNX_EXTERN void pn_task_cancel(pn_task_t *task);
+
+PNX_EXTERN pn_reactor_t *pn_class_reactor(const pn_class_t *clazz, void *object);
+PNX_EXTERN pn_reactor_t *pn_object_reactor(void *object);
+PNX_EXTERN pn_reactor_t *pn_event_reactor(pn_event_t *event);
+
+PNX_EXTERN pn_handler_t *pn_record_get_handler(pn_record_t *record);
+PNX_EXTERN void pn_record_set_handler(pn_record_t *record, pn_handler_t *handler);
+
+/**
+ * Get the root handler the current event was dispatched to.
+ */
+PNX_EXTERN pn_handler_t *pn_event_root(pn_event_t *event);
+
+/**
+ * @endcond
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* reactor.h */


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