| #ifndef PROTON_RAW_CONNECTION_H |
| #define PROTON_RAW_CONNECTION_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 |
| * |
| * @addtogroup raw_connection |
| * @{ |
| */ |
| |
| /** |
| * A descriptor used to represent a single raw buffer in memory. |
| * |
| * @note The intent of the offset is to allow the actual bytes being read/written to be at a variable |
| * location relative to the head of the buffer because of other data or structures that are important to the application |
| * associated with the data to be written but not themselves read/written to the connection. |
| * |
| * @note For read buffers: When read buffers are returned to the application size will be the number of bytes read. |
| * Read operations will not change the context, bytes or capacity members of the structure. |
| * |
| * @note For write buffers: When write buffers are returned to the application all of the struct members will be returned |
| * unaltered. Also write operations will not modify the bytes of the buffer passed in at all. In principle this means that |
| * the write buffer can be used for multiple writes at the same time as long as the actual buffer is unmodified by the |
| * application at any time the buffer is being used by any raw connection. |
| */ |
| typedef struct pn_raw_buffer_t { |
| uintptr_t context; /**< Used to associate arbitrary application data with this raw buffer */ |
| char *bytes; /**< Pointer to the start of the raw buffer, if this is null then no buffer is represented */ |
| uint32_t capacity; /**< Count of available bytes starting at @ref bytes */ |
| uint32_t size; /**< Number of bytes read or to be written starting at @ref offset */ |
| uint32_t offset; /**< First byte in the buffer to be read or written */ |
| } pn_raw_buffer_t; |
| |
| |
| /** |
| * Create a new raw connection for use with the @ref proactor. |
| * See @ref pn_proactor_raw_connect and @ref pn_listener_raw_accept. |
| * |
| * @return A newly allocated pn_raw_connection_t or NULL if there wasn't sufficient memory. |
| * |
| * @note This is the only pn_raw_connection_t function that allocates memory. So an application that |
| * wants good control of out of memory conditions should check the return value for NULL. |
| * |
| * @note It would be a good practice is to create a raw connection and attach application |
| * specific context to it before giving it to the proactor. |
| * |
| * @note There is no way to free a pn_raw_connection_t as once passed to the proactor the proactor owns |
| * it and controls its lifecycle. |
| */ |
| PNP_EXTERN pn_raw_connection_t *pn_raw_connection(void); |
| |
| /** |
| * Get the local address of a raw connection. Return `NULL` if not available. |
| * Pointer is invalid after the transport closes (@ref PN_RAW_CONNECTION_DISCONNECTED event is handled) |
| */ |
| PNP_EXTERN const struct pn_netaddr_t *pn_raw_connection_local_addr(pn_raw_connection_t *connection); |
| |
| /** |
| * Get the local address of a raw connection. Return `NULL` if not available. |
| * Pointer is invalid after the transport closes (@ref PN_RAW_CONNECTION_DISCONNECTED event is handled) |
| */ |
| PNP_EXTERN const struct pn_netaddr_t *pn_raw_connection_remote_addr(pn_raw_connection_t *connection); |
| |
| /** |
| * Close a raw connection. |
| * This will flush any buffers to be written; close the underlying socket and release all buffers held by the |
| * raw connection. |
| * |
| * It will cause @ref PN_RAW_CONNECTION_READ and @ref PN_RAW_CONNECTION_WRITTEN to be emitted so |
| * the application can clean up buffers given to the raw connection. After that a |
| * @ref PN_RAW_CONNECTION_DISCONNECTED event will be emitted to allow the application to clean up |
| * any other state held by the raw connection. |
| * |
| */ |
| PNP_EXTERN void pn_raw_connection_close(pn_raw_connection_t *connection); |
| |
| /** |
| * Shutdown a raw connection for reading. |
| * This will close the underlying socket for reading and release all empty read buffers held by the raw connection. |
| * |
| * It will cause @ref PN_RAW_CONNECTION_READ to be emitted so the application can clean up buffers given to the raw |
| * connection. Note that these buffers may still also contain data read from the socket but not yet consumed by the |
| * application. |
| * |
| * If @ref pn_raw_connection_write_close() has already been called then @ref PN_RAW_CONNECTION_DISCONNECTED will then |
| * also be emitted. |
| * |
| * In order to fully close a raw connection the application will need to either call @ref pn_raw_connection_close() |
| * or @ref pn_raw_connection_write_close() after it calls @ref pn_raw_connection_read_close(). |
| */ |
| PNP_EXTERN void pn_raw_connection_read_close(pn_raw_connection_t *connection); |
| |
| /** |
| * Shutdown a raw connection for writing. |
| * This will flush any buffers to be written to the socket; close the underlying socket for writing and release all |
| * write buffers held by the raw connection. |
| * |
| * It will cause @ref PN_RAW_CONNECTION_WRITTEN to be emitted so the application can clean up write buffers given to |
| * the raw connection. |
| * |
| * If @ref pn_raw_connection_read_close() has already been called then @ref PN_RAW_CONNECTION_DISCONNECTED will then |
| * also be emitted. |
| * |
| * In order to fully close a raw connection the application will need to either call @ref pn_raw_connection_close() |
| * or @ref pn_raw_connection_read_close() after it calls @ref pn_raw_connection_write_close(). |
| */ |
| PNP_EXTERN void pn_raw_connection_write_close(pn_raw_connection_t *connection); |
| |
| /** |
| * Query the raw connection for how many more read buffers it can be given |
| */ |
| PNP_EXTERN size_t pn_raw_connection_read_buffers_capacity(pn_raw_connection_t *connection); |
| |
| /** |
| * Query the raw connection for how many more write buffers it can be given |
| */ |
| PNP_EXTERN size_t pn_raw_connection_write_buffers_capacity(pn_raw_connection_t *connection); |
| |
| /** |
| * Give the raw connection buffers to use for reading from the underlying socket. |
| * If the raw socket has no read buffers then the application will never receive |
| * a @ref PN_RAW_CONNECTION_READ event. |
| * |
| * A @ref PN_RAW_CONNECTION_NEED_READ_BUFFERS event will be generated immediately after |
| * the @ref PN_RAW_CONNECTION_CONNECTED event if there are no read buffers. It will also be |
| * generated whenever the raw connection runs out of read buffers. In both these cases the |
| * event will not be generated again until @ref pn_raw_connection_give_read_buffers is called. |
| * |
| * @return the number of buffers actually given to the raw connection. This will only be different |
| * from the number supplied if the connection has no more space to record more buffers. In this case |
| * the buffers taken will be the earlier buffers in the array supplied, the elements 0 to the |
| * returned value-1. |
| * |
| * @note The buffers given to the raw connection are owned by it until the application |
| * receives the buffers back with a @ref pn_raw_connection_take_read_buffers call. They must |
| * not be accessed at all (written or even read) from calling @ref pn_raw_connection_give_read_buffers |
| * until receiving them back. |
| * |
| * @note The application should not assume that the @ref PN_RAW_CONNECTION_NEED_READ_BUFFERS |
| * event signifies that the connection is readable. |
| */ |
| PNP_EXTERN size_t pn_raw_connection_give_read_buffers(pn_raw_connection_t *connection, pn_raw_buffer_t const *buffers, size_t num); |
| |
| /** |
| * Fetch buffers with bytes read from the raw socket |
| * |
| * The buffers will be placed in the buffers array in the order in which they were read. So the first buffer in the array will contain the |
| * first bytes read; the second buffer the next bytes etc. |
| * |
| * @param[out] buffers pointer to an array of @ref pn_raw_buffer_t structures which will be filled in with the read buffer information |
| * @param[in] num the number of buffers allocated in the passed in array of buffers |
| * @return the number of buffers being returned, if there are no read bytes then this will be 0. As many buffers will be returned |
| * as can be given the number that are passed in. So if the number returned is less than the number passed in there are no more buffers |
| * read. But if the number is the same there may be more read buffers to take. |
| * |
| * @note After the application receives @ref PN_RAW_CONNECTION_READ there should be bytes read from the socket and |
| * hence this call should return buffers. It is safe to carry on calling @ref pn_raw_connection_take_read_buffers |
| * until it returns 0. |
| */ |
| PNP_EXTERN size_t pn_raw_connection_take_read_buffers(pn_raw_connection_t *connection, pn_raw_buffer_t *buffers, size_t num); |
| |
| /** |
| * Give the raw connection buffers to write to the underlying socket. |
| * |
| * The buffers will be written to the connection in the order that they are passed in. That is the first buffer in the array of buffers |
| * passed will be the first buffer written to the connection; the second buffer passed in will be the second written etc. |
| * |
| * A @ref PN_RAW_CONNECTION_WRITTEN event will be generated once the buffers have been written to the socket |
| * until this point the buffers must not be accessed at all (written or even read). |
| * |
| * A @ref PN_RAW_CONNECTION_NEED_WRITE_BUFFERS event will be generated immediately after |
| * the @ref PN_RAW_CONNECTION_CONNECTED event if there are no write buffers. It will also be |
| * generated whenever the raw connection finishes writing all the write buffers. In both these cases the |
| * event will not be generated again until @ref pn_raw_connection_write_buffers is called. |
| * |
| * @return the number of buffers actually recorded by the raw connection to write. This will only be different |
| * from the number supplied if the connection has no more space to record more buffers. In this case |
| * the buffers recorded will be the earlier buffers in the array supplied, the elements 0 to the |
| * returned value-1. |
| * |
| */ |
| PNP_EXTERN size_t pn_raw_connection_write_buffers(pn_raw_connection_t *connection, pn_raw_buffer_t const *buffers, size_t num); |
| |
| /** |
| * Return a buffer chain with buffers that have all been written to the raw socket |
| * |
| * @param[out] buffers pointer to an array of @ref pn_raw_buffer_t structures which will be filled in with the written buffer information |
| * @param[in] num the number of buffers allocated in the passed in array of buffers |
| * @return the number of buffers being returned, if there is are no written buffers to return then this will be 0. As many buffers will be returned |
| * as can be given the number that are passed in. So if the number returned is less than the number passed in there are no more buffers |
| * written. But if the number is the same there may be more written buffers to take. |
| * |
| * @note After the application receives @ref PN_RAW_CONNECTION_WRITTEN there should be bytes written to the socket and |
| * hence this call should return buffers. It is safe to carry on calling @ref pn_raw_connection_take_written_buffers |
| * until it returns 0. |
| * |
| * @note The buffers will be returned in the same order as they were originally passed in. |
| */ |
| PNP_EXTERN size_t pn_raw_connection_take_written_buffers(pn_raw_connection_t *connection, pn_raw_buffer_t *buffers, size_t num); |
| |
| /** |
| * Is @p connection closed for read? |
| * |
| * @return true if the raw connection is closed for read. |
| */ |
| PNP_EXTERN bool pn_raw_connection_is_read_closed(pn_raw_connection_t *connection); |
| |
| /** |
| * Is @p connection closed for write? |
| * |
| * @return true if the raw connection is closed for write. |
| */ |
| PNP_EXTERN bool pn_raw_connection_is_write_closed(pn_raw_connection_t *connection); |
| |
| /** |
| * Return a @ref PN_RAW_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 raw connection. Wakes can be "coalesced" - if several |
| * @ref pn_raw_connection_wake() calls happen close together, there may be only one |
| * @ref PN_RAW_CONNECTION_WAKE event that occurs after all of them. |
| * |
| * @note Thread-safe |
| */ |
| PNP_EXTERN void pn_raw_connection_wake(pn_raw_connection_t *connection); |
| |
| /** |
| * Get additional information about a raw connection error. |
| * There is a raw connection error if the @ref PN_RAW_CONNECTION_DISCONNECTED event |
| * is received and the pn_condition_t associated is non null (@see pn_condition_is_set). |
| * |
| * The value returned is only valid until the end of handler for the |
| * @ref PN_RAW_CONNECTION_DISCONNECTED event. |
| */ |
| PNP_EXTERN pn_condition_t *pn_raw_connection_condition(pn_raw_connection_t *connection); |
| |
| /** |
| * Get the application context associated with this raw connection. |
| * |
| * The application context for a raw connection may be set using |
| * ::pn_raw_connection_set_context. |
| * |
| * @param[in] connection the raw connection whose context is to be returned. |
| * @return the application context for the raw connection |
| */ |
| PNP_EXTERN void *pn_raw_connection_get_context(pn_raw_connection_t *connection); |
| |
| /** |
| * Set a new application context for a raw connection. |
| * |
| * The application context for a raw connection may be retrieved |
| * using ::pn_raw_connection_get_context. |
| * |
| * @param[in] connection the raw connection object |
| * @param[in] context the application context |
| */ |
| PNP_EXTERN void pn_raw_connection_set_context(pn_raw_connection_t *connection, void *context); |
| |
| /** |
| * Get the attachments that are associated with a raw connection. |
| */ |
| PNP_EXTERN pn_record_t *pn_raw_connection_attachments(pn_raw_connection_t *connection); |
| |
| /** |
| * Return the raw connection associated with an event. |
| * |
| * @return NULL if the event is not associated with a raw connection. |
| */ |
| PNP_EXTERN pn_raw_connection_t *pn_event_raw_connection(pn_event_t *event); |
| |
| |
| /** |
| * @} |
| */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* raw_connection.h */ |