Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apple Network Framework Socket Changes #662

Open
wants to merge 88 commits into
base: grand_dispatch_queue
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
14a3386
socket related from network_framework_integration branch
sbSteveK Jul 29, 2024
9715a3e
Merge branch 'grand_dispatch_queue' into nw_socket
sbSteveK Jul 29, 2024
b830a86
missed s_socket_listen
sbSteveK Jul 29, 2024
cccbda2
move aws_socket_init_poll_based platform not supported function into …
sbSteveK Jul 30, 2024
caac9a5
small cleanups/comments
sbSteveK Jul 30, 2024
eb59ff1
Merge branch 'grand_dispatch_queue' into nw_socket
sbSteveK Jul 30, 2024
8a794de
nw_socket.c changes
sbSteveK Aug 8, 2024
553d45f
add nw_connection_t to nw_socket
sbSteveK Aug 9, 2024
cf610e9
read from socket works
sbSteveK Aug 12, 2024
07bac64
remove prints
sbSteveK Aug 13, 2024
dd1fbf2
trivial edits
sbSteveK Aug 13, 2024
2fd514c
check correct vtable func
sbSteveK Aug 13, 2024
2a0da42
clang format
sbSteveK Aug 13, 2024
9cc6620
socket_test add a manual way to set event_loop_style in options
sbSteveK Aug 13, 2024
e3281ee
event_loop add undefined event loop style and clang format
sbSteveK Aug 13, 2024
43fd436
clang format
sbSteveK Aug 13, 2024
1c1cd02
event_loop.c clang formatting and configurations
sbSteveK Aug 13, 2024
88f6de3
formatting
sbSteveK Aug 13, 2024
cf53cc6
format
sbSteveK Aug 13, 2024
a7ab224
macos errors
sbSteveK Aug 13, 2024
62fd06d
fix test
sbSteveK Aug 13, 2024
cbb8c42
formatting
sbSteveK Aug 13, 2024
4ce33ee
test fix
sbSteveK Aug 13, 2024
29ab896
prototype void
sbSteveK Aug 13, 2024
f9cd5d0
fix style func
sbSteveK Aug 13, 2024
2e55d2d
sprintf -> snprintf
sbSteveK Aug 13, 2024
6938bc3
manual default change for testing
sbSteveK Aug 21, 2024
4658492
Merge branch 'grand_dispatch_queue' into nw_socket
sbSteveK Sep 3, 2024
ef8d53f
Merge branch 'grand_dispatch_queue' of https://github.com/awslabs/aws…
xiazhvera Sep 11, 2024
731ba49
setup connection timeout
xiazhvera Sep 13, 2024
bac8b07
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Sep 17, 2024
429bf26
remove debug changes
xiazhvera Sep 17, 2024
2282f8f
Branched nw_socket work (#674)
sbSteveK Sep 24, 2024
8e7b351
veriify_peer spelling
sbSteveK Sep 24, 2024
54e58e9
remove redundant secure_transport_ctx
sbSteveK Sep 24, 2024
b01b510
channel_args creation simplification
sbSteveK Sep 24, 2024
5b5a953
empty line
sbSteveK Sep 24, 2024
b7f13df
clang formatting
sbSteveK Sep 24, 2024
b325809
more clang
sbSteveK Sep 24, 2024
86b4343
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Sep 26, 2024
9471d05
fix merge error and socket completion hanlder changes
xiazhvera Sep 26, 2024
789d446
fix cmakefile
xiazhvera Sep 26, 2024
33aa640
Merge branch 'grand_dispatch_queue' into nw_socket
sbSteveK Oct 3, 2024
68fa441
Clean Up Socket Vtable (#678)
xiazhvera Oct 4, 2024
a47fd44
remove platform.h
xiazhvera Oct 4, 2024
b4cd993
remove platform.h
xiazhvera Oct 4, 2024
d071082
[WIP]nw_socket protect socket data with lock (#685)
xiazhvera Oct 15, 2024
dd33861
clean up comments
xiazhvera Oct 15, 2024
f950453
more read me and clean up
xiazhvera Oct 15, 2024
c188594
add logs to track tls_channel_shutdown_with_cache_window_update_after…
xiazhvera Oct 15, 2024
6a1c03a
clang-format
xiazhvera Oct 15, 2024
871ae9b
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 15, 2024
a0be9d2
clean up comments
xiazhvera Oct 16, 2024
32728ba
wait for socket release
xiazhvera Oct 16, 2024
9e8015c
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 16, 2024
3350e6c
clang-format fix
xiazhvera Oct 16, 2024
2592e47
fix cmake changes
xiazhvera Oct 16, 2024
f8024d2
kqueue and epoll used the posix socket
xiazhvera Oct 16, 2024
0e24c22
update compile flags...
xiazhvera Oct 16, 2024
40b6b81
update dispatch queue
xiazhvera Oct 16, 2024
81992ba
fix merge change
xiazhvera Oct 16, 2024
e89119a
clang-format
xiazhvera Oct 16, 2024
776977e
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 25, 2024
2aafe5f
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 25, 2024
ada3e09
lint
xiazhvera Oct 25, 2024
fbe538f
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 25, 2024
86f3b2d
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Oct 25, 2024
72b51a0
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 8, 2024
69c22b4
clean up merge changes
xiazhvera Nov 8, 2024
1b79cbd
fix dispatch queue test flag
xiazhvera Nov 8, 2024
e613e5d
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 9, 2024
28b7546
update socket api changes for network framework
xiazhvera Nov 9, 2024
351c682
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 9, 2024
f24d637
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 9, 2024
0d69dd7
add apple socket init
xiazhvera Nov 9, 2024
c408e30
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 11, 2024
145e7d7
hide dispatch_queue.h
xiazhvera Nov 11, 2024
3a4eaca
fix merge error
xiazhvera Nov 11, 2024
35934d3
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 12, 2024
11d0f84
rename enum
xiazhvera Nov 12, 2024
8320127
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 12, 2024
652195b
remove warning on nw socket
xiazhvera Nov 12, 2024
1637a88
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 12, 2024
658463a
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 12, 2024
d0dddda
extend the shutdown wait time
xiazhvera Nov 12, 2024
31fd471
Merge branch 'grand_dispatch_queue' of github.com:awslabs/aws-c-io in…
xiazhvera Nov 29, 2024
d784f96
include private socket header
xiazhvera Nov 29, 2024
d880859
improve readme
xiazhvera Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 52 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ Core to Async-IO is the event-loop. We provide an implementation for most platfo
Platform | Implementation
--- | ---
Linux | Edge-Triggered Epoll
BSD Variants and Apple Devices | KQueue
BSD Variants | KQueue
Apple Devices | KQueue or Apple Dispatch Queue
Windows | IOCP (IO Completion Ports)

Also, you can always implement your own as well.
Expand Down Expand Up @@ -645,12 +646,49 @@ All exported functions, simply shim into the v-table and return.

We include a cross-platform API for sockets. We support TCP and UDP using IPv4 and IPv6, and Unix Domain sockets. On Windows,
we use Named Pipes to support the functionality of Unix Domain sockets. On Windows, this is implemented with winsock2, and on
all unix platforms we use the posix API.
all unix platforms we use the posix API. Then we will use Apple Network Framework on Apple platforms.

Upon a connection being established, the new socket (either as the result of a `connect()` or `start_accept()` call)
will not be attached to any event loops. It is your responsibility to register it with an event loop to begin receiving
notifications.


#### V-Table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this documentation necessary in the public readme? A giant list of functions feels like a distraction

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would help with anybody who would like to extend the socket implementation. Also, we listed the vtable for other classes as well.


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);
};

#### API
typedef enum aws_socket_domain {
AWS_SOCKET_IPV4,
Expand Down Expand Up @@ -717,32 +755,33 @@ 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 UDP, this simply binds the socket to a remote address for use with `aws_socket_write()`,
and if the operation is successful, the socket can immediately be used for write operations.
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 TCP, this will function will not block. If the return value is successful, then you 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,
the socket can immediately be used for write operations.

For LOCAL (Unix Domain Sockets or Named Pipes), the socket will be immediately ready for use upon a successful return.

int aws_socket_bind(struct aws_socket *socket, struct aws_socket_endpoint *local_endpoint);

Binds the socket to a local address. In UDP mode, the socket is ready for `aws_socket_read()` operations. In connection oriented
modes, you still must call `aws_socket_listen()` and `aws_socket_start_accept()` before using the socket.
Binds the socket to a local address. In UDP mode, the socket is ready for `aws_socket_read()` operations. In connection oriented
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if-else conditional behavior bothers me. What happens if you call aws_socket_listen on a bound UDP socket?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aws_socket_listen would fail with AWS_IO_SOCKET_ILLEGAL_OPERATION_FOR_STATE on a bounded UDP socket.

modes or if you are using Apple Network Framework (regardless it is UDP or TCP), you still must call `aws_socket_listen()` and
`aws_socket_start_accept()` before using the socket.

int aws_socket_listen(struct aws_socket *socket, int backlog_size);

TCP and LOCAL only. Sets up the socket to listen on the address bound to in `aws_socket_bind()`.
TCP, LOCAL, and Apple Network Framework only. Sets up the socket to listen on the address bound to in `aws_socket_bind()`.

int aws_socket_start_accept(struct aws_socket *socket);

TCP and LOCAL only. The socket will begin accepting new connections. This is an asynchronous operation. New connections will
arrive via the `on_incoming_connection()` callback.
TCP, LOCAL, and Apple Network Framework only. The socket will begin accepting new connections. This is an asynchronous operation. New
connections will arrive via the `on_incoming_connection()` callback.

int aws_socket_stop_accept(struct aws_socket *socket);

TCP and LOCAL only. The socket will shutdown the listener. It is safe to call `aws_socket_start_accept()` again after this
operation.
TCP, LOCAL, and Apple Network Framework only. The socket will shutdown the listener. It is safe to call `aws_socket_start_accept()`
again after this operation.

int aws_socket_close(struct aws_socket *socket);

Expand Down
7 changes: 6 additions & 1 deletion source/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,12 @@ void aws_channel_schedule_task_future(
}

bool aws_channel_thread_is_callers_thread(struct aws_channel *channel) {
return aws_event_loop_thread_is_callers_thread(channel->loop);
// As aws_event_loop is not ref-counted, it is possible that the socket read/write callback get triggered after
// the event loop is released, ignore the function call here.
if (channel && channel->loop) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is alarming. I would like to know a lot more about how this is possible: how can you have a channel still alive while its event loop is not?

return aws_event_loop_thread_is_callers_thread(channel->loop);
}
return true;
}

static void s_update_channel_slot_message_overheads(struct aws_channel *channel) {
Expand Down
20 changes: 8 additions & 12 deletions source/channel_bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,10 @@ static bool s_aws_socket_domain_uses_dns(enum aws_socket_domain domain) {
return domain == AWS_SOCKET_IPV4 || domain == AWS_SOCKET_IPV6;
}

/* Called when a socket connection attempt task completes. First socket to successfully open
* assigns itself to connection_args->channel_data.socket and flips connection_args->connection_chosen
* to true. Subsequent successful sockets will be released and cleaned up
*/
static void s_on_client_connection_established(struct aws_socket *socket, int error_code, void *user_data) {
struct client_connection_args *connection_args = user_data;

Expand Down Expand Up @@ -565,7 +569,6 @@ static void s_on_client_connection_established(struct aws_socket *socket, int er
(void *)connection_args->bootstrap,
(void *)socket);
aws_socket_close(socket);

aws_socket_clean_up(socket);
aws_mem_release(connection_args->bootstrap->allocator, socket);

Expand Down Expand Up @@ -639,7 +642,7 @@ static void s_attempt_connection(struct aws_task *task, void *arg, enum aws_task
goto task_cancelled;
}

struct aws_socket *outgoing_socket = aws_mem_acquire(allocator, sizeof(struct aws_socket));
struct aws_socket *outgoing_socket = aws_mem_calloc(allocator, 1, sizeof(struct aws_socket));
if (aws_socket_init(outgoing_socket, allocator, &task_data->options)) {
goto socket_init_failed;
}
Expand Down Expand Up @@ -832,10 +835,6 @@ int aws_client_bootstrap_new_socket_channel(struct aws_socket_channel_bootstrap_
struct client_connection_args *client_connection_args =
aws_mem_calloc(bootstrap->allocator, 1, sizeof(struct client_connection_args));

if (!client_connection_args) {
return AWS_OP_ERR;
}

const char *host_name = options->host_name;
uint32_t port = options->port;

Expand Down Expand Up @@ -1361,9 +1360,7 @@ void s_on_server_connection_result(
(void *)socket);
struct server_channel_data *channel_data =
aws_mem_calloc(connection_args->bootstrap->allocator, 1, sizeof(struct server_channel_data));
if (!channel_data) {
goto error_cleanup;
}

channel_data->incoming_called = false;
channel_data->socket = new_socket;
channel_data->server_connection_args = connection_args;
Expand All @@ -1376,11 +1373,10 @@ void s_on_server_connection_result(
.setup_user_data = channel_data,
.shutdown_user_data = channel_data,
.on_shutdown_completed = s_on_server_channel_on_shutdown,
.event_loop = event_loop,
.enable_read_back_pressure = channel_data->server_connection_args->enable_read_back_pressure,
};

channel_args.event_loop = event_loop;
channel_args.enable_read_back_pressure = channel_data->server_connection_args->enable_read_back_pressure;

if (aws_socket_assign_to_event_loop(new_socket, event_loop)) {
aws_mem_release(connection_args->bootstrap->allocator, (void *)channel_data);
goto error_cleanup;
Expand Down
Loading
Loading