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:trust...@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/<path> 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:passw...@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-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org