Skip to content

Commit

Permalink
Merge branch 'runtime_select_event_loop' of github.com:awslabs/aws-c-…
Browse files Browse the repository at this point in the history
…io into grand_dispatch_queue
  • Loading branch information
xiazhvera committed Nov 25, 2024
2 parents 7d20796 + 1afb859 commit 691aa17
Show file tree
Hide file tree
Showing 21 changed files with 499 additions and 264 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
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
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
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
20 changes: 16 additions & 4 deletions include/aws/io/private/event_loop_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,35 @@ 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);

typedef struct aws_event_loop *(aws_new_event_loop_fn)(struct aws_allocator *alloc,
const struct aws_event_loop_options *options,
void *new_loop_user_data);

/**
* @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.
*/
enum aws_event_loop_type aws_event_loop_get_default_type(void);

struct aws_event_loop_group {
struct aws_allocator *allocator;
struct aws_array_list event_loops;
Expand Down
72 changes: 72 additions & 0 deletions include/aws/io/private/socket_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#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_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,
void *user_data);
int (*socket_bind_fn)(struct aws_socket *socket, const struct aws_socket_endpoint *local_endpoint);
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);
};

#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
60 changes: 0 additions & 60 deletions include/aws/io/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,40 +140,6 @@ struct aws_socket_endpoint {

struct aws_socket;

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,
void *user_data);
int (*socket_bind_fn)(struct aws_socket *socket, const struct aws_socket_endpoint *local_endpoint);
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_socket {
struct aws_socket_vtable *vtable;
struct aws_allocator *allocator;
Expand All @@ -195,32 +161,6 @@ struct aws_socket {
struct aws_byte_buf;
struct aws_byte_cursor;

/* 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);

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
2 changes: 1 addition & 1 deletion source/darwin/dispatch_queue_event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static struct aws_string *s_get_unique_dispatch_queue_id(struct aws_allocator *a
}

/* Setup a dispatch_queue with a scheduler. */
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) {
AWS_PRECONDITION(options);
Expand Down
Loading

0 comments on commit 691aa17

Please sign in to comment.