-
Notifications
You must be signed in to change notification settings - Fork 61
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
base: grand_dispatch_queue
Are you sure you want to change the base?
Changes from all commits
14a3386
9715a3e
b830a86
cccbda2
caac9a5
eb59ff1
8a794de
553d45f
cf610e9
07bac64
dd1fbf2
2fd514c
2a0da42
9cc6620
e3281ee
43fd436
1c1cd02
88f6de3
cf53cc6
a7ab224
62fd06d
cbb8c42
4ce33ee
29ab896
f9cd5d0
2e55d2d
6938bc3
4658492
ef8d53f
731ba49
bac8b07
429bf26
2282f8f
8e7b351
54e58e9
b01b510
5b5a953
b7f13df
b325809
86b4343
9471d05
789d446
33aa640
68fa441
a47fd44
b4cd993
d071082
dd33861
f950453
c188594
6a1c03a
871ae9b
a0be9d2
32728ba
9e8015c
3350e6c
2592e47
f8024d2
0e24c22
40b6b81
81992ba
e89119a
776977e
2aafe5f
ada3e09
fbe538f
86f3b2d
72b51a0
69c22b4
1b79cbd
e613e5d
28b7546
351c682
f24d637
0d69dd7
c408e30
145e7d7
3a4eaca
35934d3
11d0f84
8320127
652195b
1637a88
658463a
d0dddda
31fd471
d784f96
d880859
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
|
@@ -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 | ||
|
||
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, | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aws_socket_listen would fail with |
||
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); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) { | ||
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.