Skip to content

Commit

Permalink
merge with latest nw_socket
Browse files Browse the repository at this point in the history
  • Loading branch information
sbSteveK committed Dec 4, 2024
2 parents 14a79cc + d880859 commit 8daedcb
Show file tree
Hide file tree
Showing 24 changed files with 705 additions and 421 deletions.
17 changes: 8 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,13 @@ elseif (APPLE)
)

find_library(SECURITY_LIB Security)
if (NOT SECURITY_LIB)
message(FATAL_ERROR "Security framework not found")
endif ()

find_library(NETWORK_LIB Network)
if (NOT NETWORK_LIB)
message(FATAL_ERROR "Network framework not found")
endif ()

list(APPEND PLATFORM_LIBS "-framework Security -framework Network")
list(APPEND EVENT_LOOP_DEFINES "DISPATCH_QUEUE")
# Enable dispatch queue if the libraries are avaliable
if (NETWORK_LIB AND SECURITY_LIB)
list(APPEND PLATFORM_LIBS "-framework Security -framework Network")
list(APPEND EVENT_LOOP_DEFINES "DISPATCH_QUEUE")
endif ()

# Enable KQUEUE on MacOS only if AWS_USE_SECITEM is not declared. SecItem requires Dispatch Queue.
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT DEFINED AWS_USE_SECITEM)
Expand Down Expand Up @@ -195,6 +191,9 @@ aws_add_sanitizers(${PROJECT_NAME})
# We are not ABI stable yet
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION 1.0.0)

if (NOT EVENT_LOOP_DEFINES)
message(FATAL_ERROR "Event Loop is not setup on the platform.")
endif()
foreach(EVENT_LOOP_DEFINE IN LISTS EVENT_LOOP_DEFINES)
target_compile_definitions(${PROJECT_NAME} PUBLIC "-DAWS_ENABLE_${EVENT_LOOP_DEFINE}")
endforeach()
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -755,8 +755,7 @@ Shuts down any pending operations on the socket, and cleans up state. The socket

int aws_socket_connect(struct aws_socket *socket, struct aws_socket_endpoint *remote_endpoint);

Connects to a remote endpoint. In TCP and all Apple Network Framework connections (regardless it is UDP, TCP or LOCAL), this will
function will not block. If the return value is successful, then you must wait on the `on_connection_established()` callback to
Connects to a remote endpoint. In TCP and all Apple Network Framework connections (regardless it is UDP, TCP or LOCAL), when the connection succeed, you still must wait on the `on_connection_established()` callback to
be invoked before using the socket.

In UDP, this simply binds the socket to a remote address for use with `aws_socket_write()`, and if the operation is successful,
Expand Down
14 changes: 2 additions & 12 deletions include/aws/io/event_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ struct aws_event_loop_vtable {
*
* Default Event Loop Type
* Linux | AWS_EVENT_LOOP_EPOLL
* Windows | AWS_EVENT_LOOP_IOCP
* Windows | AWS_EVENT_LOOP_IOCP
* BSD Variants| AWS_EVENT_LOOP_KQUEUE
* MacOS | AWS_EVENT_LOOP_KQUEUE
* MacOS | AWS_EVENT_LOOP_KQUEUE
* iOS | AWS_EVENT_LOOP_DISPATCH_QUEUE
*/
enum aws_event_loop_type {
Expand Down Expand Up @@ -103,16 +103,6 @@ struct aws_event_loop_group_options {
aws_io_clock_fn *clock_override;
};

/**
* @internal - Don't use outside of testing.
*
* Return the default event loop type. If the return value is `AWS_ELT_PLATFORM_DEFAULT`, the function failed to
* retrieve the default type value.
* If `aws_event_loop_override_default_type` has been called, return the override default type.
*/
AWS_IO_API
enum aws_event_loop_type aws_event_loop_get_default_type(void);

AWS_EXTERN_C_BEGIN

/**
Expand Down
21 changes: 17 additions & 4 deletions include/aws/io/private/event_loop_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,19 @@ struct aws_event_loop_options {
enum aws_event_loop_type type;
};

struct aws_event_loop *aws_event_loop_new_iocp_with_options(
struct aws_event_loop *aws_event_loop_new_with_iocp(
struct aws_allocator *alloc,
const struct aws_event_loop_options *options);
struct aws_event_loop *aws_event_loop_new_dispatch_queue_with_options(

struct aws_event_loop *aws_event_loop_new_with_dispatch_queue(
struct aws_allocator *alloc,
const struct aws_event_loop_options *options);
struct aws_event_loop *aws_event_loop_new_kqueue_with_options(

struct aws_event_loop *aws_event_loop_new_with_kqueue(
struct aws_allocator *alloc,
const struct aws_event_loop_options *options);
struct aws_event_loop *aws_event_loop_new_epoll_with_options(

struct aws_event_loop *aws_event_loop_new_with_epoll(
struct aws_allocator *alloc,
const struct aws_event_loop_options *options);

Expand Down Expand Up @@ -149,6 +152,16 @@ AWS_IO_API
struct _OVERLAPPED *aws_overlapped_to_windows_overlapped(struct aws_overlapped *overlapped);
#endif /* AWS_ENABLE_IO_COMPLETION_PORTS */

/**
* @internal - Don't use outside of testing.
*
* Return the default event loop type. If the return value is `AWS_ELT_PLATFORM_DEFAULT`, the function failed to
* retrieve the default type value.
* If `aws_event_loop_override_default_type` has been called, return the override default type.
*/
AWS_IO_API
enum aws_event_loop_type aws_event_loop_get_default_type(void);

/**
* Associates an aws_io_handle with the event loop's I/O Completion Port.
*
Expand Down
82 changes: 82 additions & 0 deletions include/aws/io/private/socket_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#ifndef AWS_IO_SOCKET_IMPL_H
#define AWS_IO_SOCKET_IMPL_H

/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/io/io.h>
#include <aws/io/socket.h>

/* These are hacks for working around headers and functions we need for IO work but aren't directly includable or
linkable. these are purposely not exported. These functions only get called internally. The awkward aws_ prefixes are
just in case someone includes this header somewhere they were able to get these definitions included. */
#ifdef _WIN32
typedef void (*aws_ms_fn_ptr)(void);

void aws_check_and_init_winsock(void);
aws_ms_fn_ptr aws_winsock_get_connectex_fn(void);
aws_ms_fn_ptr aws_winsock_get_acceptex_fn(void);
#endif

int aws_socket_init_posix(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);

int aws_socket_init_winsock(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);

int aws_socket_init_apple_nw_socket(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);

struct aws_byte_cursor;
struct aws_string;

struct aws_socket_vtable {
void (*socket_cleanup_fn)(struct aws_socket *socket);
int (*socket_connect_fn)(
struct aws_socket *socket,
const struct aws_socket_endpoint *remote_endpoint,
struct aws_event_loop *event_loop,
aws_socket_on_connection_result_fn *on_connection_result,
aws_socket_retrieve_tls_options_fn *retrieve_tls_options,
void *user_data);
int (*socket_bind_fn)(
struct aws_socket *socket,
const struct aws_socket_endpoint *local_endpoint,
aws_socket_retrieve_tls_options_fn *retrieve_tls_options,
void *user_data);
int (*socket_listen_fn)(struct aws_socket *socket, int backlog_size);
int (*socket_start_accept_fn)(
struct aws_socket *socket,
struct aws_event_loop *accept_loop,
aws_socket_on_accept_result_fn *on_accept_result,
void *user_data);
int (*socket_stop_accept_fn)(struct aws_socket *socket);
int (*socket_close_fn)(struct aws_socket *socket);
int (*socket_shutdown_dir_fn)(struct aws_socket *socket, enum aws_channel_direction dir);
int (*socket_set_options_fn)(struct aws_socket *socket, const struct aws_socket_options *options);
int (*socket_assign_to_event_loop_fn)(struct aws_socket *socket, struct aws_event_loop *event_loop);
int (*socket_subscribe_to_readable_events_fn)(
struct aws_socket *socket,
aws_socket_on_readable_fn *on_readable,
void *user_data);
int (*socket_read_fn)(struct aws_socket *socket, struct aws_byte_buf *buffer, size_t *amount_read);
int (*socket_write_fn)(
struct aws_socket *socket,
const struct aws_byte_cursor *cursor,
aws_socket_on_write_completed_fn *written_fn,
void *user_data);
int (*socket_get_error_fn)(struct aws_socket *socket);
bool (*socket_is_open_fn)(struct aws_socket *socket);
struct aws_byte_buf (*socket_get_protocol_fn)(const struct aws_socket *socket);
struct aws_string *(*socket_get_server_name_fn)(const struct aws_socket *socket);
};

#endif // AWS_IO_SOCKET_IMPL_H
26 changes: 22 additions & 4 deletions include/aws/io/retry_strategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ enum aws_exponential_backoff_jitter_mode {
* "use defaults"
*/
struct aws_exponential_backoff_retry_options {
/** Event loop group to use for scheduling tasks. */
/* Event loop group to use for scheduling tasks. */
struct aws_event_loop_group *el_group;
/** Max retries to allow. The default value is 10 */
/* Max retries to allow. The default value is 10 */
size_t max_retries;
/** Scaling factor to add for the backoff. Default is 500ms */
/* Scaling factor to add for the backoff. Default is 500ms */
uint32_t backoff_scale_factor_ms;
/** Max retry backoff in seconds. Default is 20 seconds */
/* Max retry backoff in seconds. Default is 20 seconds */
uint32_t max_backoff_secs;
/** Jitter mode to use, see comments for aws_exponential_backoff_jitter_mode.
* Default is AWS_EXPONENTIAL_BACKOFF_JITTER_DEFAULT */
Expand All @@ -139,6 +139,14 @@ struct aws_exponential_backoff_retry_options {
const struct aws_shutdown_callback_options *shutdown_options;
};

struct aws_no_retry_options {
/**
* Optional shutdown callback that gets invoked, with appropriate user data,
* when the resources used by the retry_strategy are no longer in use.
*/
const struct aws_shutdown_callback_options *shutdown_options;
};

struct aws_standard_retry_options {
struct aws_exponential_backoff_retry_options backoff_retry_options;
/** capacity for partitions. Defaults to 500 */
Expand Down Expand Up @@ -235,6 +243,16 @@ AWS_IO_API struct aws_retry_strategy *aws_retry_strategy_new_standard(
struct aws_allocator *allocator,
const struct aws_standard_retry_options *config);

/**
* This retry strategy is used to disable retries. Passed config can be null.
* Calling `aws_retry_strategy_acquire_retry_token` will raise error `AWS_IO_RETRY_PERMISSION_DENIED`.
* Calling any function apart from the `aws_retry_strategy_acquire_retry_token` and `aws_retry_strategy_release` will
* result in a fatal error.
*/
AWS_IO_API struct aws_retry_strategy *aws_retry_strategy_new_no_retry(
struct aws_allocator *allocator,
const struct aws_no_retry_options *config);

AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL

Expand Down
75 changes: 4 additions & 71 deletions include/aws/io/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ enum aws_socket_type {
*
* PLATFORM DEFAULT SOCKET IMPLEMENTATION TYPE
* Linux | AWS_SOCKET_IMPL_POSIX
* Windows | AWS_SOCKET_IMPL_WINSOCK
* Windows | AWS_SOCKET_IMPL_WINSOCK
* BSD Variants| AWS_SOCKET_IMPL_POSIX
* MacOS | AWS_SOCKET_IMPL_POSIX
* MacOS | AWS_SOCKET_IMPL_POSIX
* iOS | AWS_SOCKET_IMPL_APPLE_NETWORK_FRAMEWORK
*/
enum aws_socket_impl_type {
Expand Down Expand Up @@ -150,50 +150,6 @@ struct aws_socket_endpoint {
};

struct aws_socket;
struct aws_byte_buf;
struct aws_byte_cursor;
struct aws_string;

struct aws_socket_vtable {
void (*socket_cleanup_fn)(struct aws_socket *socket);
int (*socket_connect_fn)(
struct aws_socket *socket,
const struct aws_socket_endpoint *remote_endpoint,
struct aws_event_loop *event_loop,
aws_socket_on_connection_result_fn *on_connection_result,
aws_socket_retrieve_tls_options_fn *retrieve_tls_options,
void *user_data);
int (*socket_bind_fn)(
struct aws_socket *socket,
const struct aws_socket_endpoint *local_endpoint,
aws_socket_retrieve_tls_options_fn *retrieve_tls_options,
void *user_data);
int (*socket_listen_fn)(struct aws_socket *socket, int backlog_size);
int (*socket_start_accept_fn)(
struct aws_socket *socket,
struct aws_event_loop *accept_loop,
aws_socket_on_accept_result_fn *on_accept_result,
void *user_data);
int (*socket_stop_accept_fn)(struct aws_socket *socket);
int (*socket_close_fn)(struct aws_socket *socket);
int (*socket_shutdown_dir_fn)(struct aws_socket *socket, enum aws_channel_direction dir);
int (*socket_set_options_fn)(struct aws_socket *socket, const struct aws_socket_options *options);
int (*socket_assign_to_event_loop_fn)(struct aws_socket *socket, struct aws_event_loop *event_loop);
int (*socket_subscribe_to_readable_events_fn)(
struct aws_socket *socket,
aws_socket_on_readable_fn *on_readable,
void *user_data);
int (*socket_read_fn)(struct aws_socket *socket, struct aws_byte_buf *buffer, size_t *amount_read);
int (*socket_write_fn)(
struct aws_socket *socket,
const struct aws_byte_cursor *cursor,
aws_socket_on_write_completed_fn *written_fn,
void *user_data);
int (*socket_get_error_fn)(struct aws_socket *socket);
bool (*socket_is_open_fn)(struct aws_socket *socket);
struct aws_byte_buf (*socket_get_protocol_fn)(const struct aws_socket *socket);
struct aws_string *(*socket_get_server_name_fn)(const struct aws_socket *socket);
};

struct aws_socket {
struct aws_socket_vtable *vtable;
Expand All @@ -213,31 +169,8 @@ struct aws_socket {
void *impl;
};

/* These are hacks for working around headers and functions we need for IO work but aren't directly includable or
linkable. these are purposely not exported. These functions only get called internally. The awkward aws_ prefixes are
just in case someone includes this header somewhere they were able to get these definitions included. */
#ifdef _WIN32
typedef void (*aws_ms_fn_ptr)(void);

void aws_check_and_init_winsock(void);
aws_ms_fn_ptr aws_winsock_get_connectex_fn(void);
aws_ms_fn_ptr aws_winsock_get_acceptex_fn(void);
#endif

int aws_socket_init_posix(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);

int aws_socket_init_winsock(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);

int aws_socket_init_apple_nw_socket(
struct aws_socket *socket,
struct aws_allocator *alloc,
const struct aws_socket_options *options);
// struct aws_byte_buf;
// struct aws_byte_cursor;

AWS_EXTERN_C_BEGIN

Expand Down
2 changes: 1 addition & 1 deletion source/bsd/kqueue_event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct aws_event_loop_vtable s_kqueue_vtable = {
};

#ifdef AWS_ENABLE_KQUEUE
struct aws_event_loop *aws_event_loop_new_kqueue_with_options(
struct aws_event_loop *aws_event_loop_new_with_kqueue(
struct aws_allocator *alloc,
const struct aws_event_loop_options *options) {
AWS_ASSERT(alloc);
Expand Down
Loading

0 comments on commit 8daedcb

Please sign in to comment.