-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add descriptor table for mapping fds to handles
This introduces `descriptor_table.h` and `descriptor_table.c`, providing a global hashtable for tracking `wasi-libc`-managed file descriptors. WASI Preview 2 has no notion of file descriptors and instead uses unforgeable resource handles. Moreover, there's not necessarily a one-to-one correspondence between POSIX file descriptors and resource handles (e.g. a TCP connection may require separate handles for reading, writing, and polling the same connection). We use this table to map each POSIX descriptor to a set of one or more handles and any extra state which libc needs to track. Note that we've added `descriptor_table.h` to the libc-bottom-half/headers/public/wasi directory, making it part of the public API. The intention is to give applications access to the mapping, enabling them to convert descriptors to handles and vice-versa should they need to interoperate with both libc and WASI directly. Co-authored-by: Dave Bakker <github@davebakker.io> Signed-off-by: Joel Dice <joel.dice@fermyon.com>
- Loading branch information
Showing
7 changed files
with
389 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
libc-bottom-half/headers/public/wasi/descriptor_table.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#ifndef DESCRIPTOR_TABLE_H | ||
#define DESCRIPTOR_TABLE_H | ||
|
||
#include <wasi/preview2.h> | ||
|
||
typedef struct { | ||
} tcp_socket_state_unbound_t; | ||
typedef struct { | ||
} tcp_socket_state_bound_t; | ||
typedef struct { | ||
} tcp_socket_state_connecting_t; | ||
typedef struct { | ||
} tcp_socket_state_listening_t; | ||
|
||
typedef struct { | ||
streams_own_input_stream_t input; | ||
poll_own_pollable_t input_pollable; | ||
streams_own_output_stream_t output; | ||
poll_own_pollable_t output_pollable; | ||
} tcp_socket_state_connected_t; | ||
|
||
typedef struct { | ||
network_error_code_t error_code; | ||
} tcp_socket_state_connect_failed_t; | ||
|
||
// This is a tagged union. When adding/removing/renaming cases, be sure to keep the tag and union definitions in sync. | ||
typedef struct { | ||
enum { | ||
TCP_SOCKET_STATE_UNBOUND, | ||
TCP_SOCKET_STATE_BOUND, | ||
TCP_SOCKET_STATE_CONNECTING, | ||
TCP_SOCKET_STATE_CONNECTED, | ||
TCP_SOCKET_STATE_CONNECT_FAILED, | ||
TCP_SOCKET_STATE_LISTENING, | ||
} tag; | ||
union { | ||
tcp_socket_state_unbound_t unbound; | ||
tcp_socket_state_bound_t bound; | ||
tcp_socket_state_connecting_t connecting; | ||
tcp_socket_state_connected_t connected; | ||
tcp_socket_state_connect_failed_t connect_failed; | ||
tcp_socket_state_listening_t listening; | ||
}; | ||
} tcp_socket_state_t; | ||
|
||
typedef struct { | ||
tcp_own_tcp_socket_t socket; | ||
poll_own_pollable_t socket_pollable; | ||
bool blocking; | ||
bool fake_nodelay; | ||
bool fake_reuseaddr; | ||
network_ip_address_family_t family; | ||
tcp_socket_state_t state; | ||
} tcp_socket_t; | ||
|
||
typedef struct { | ||
udp_own_incoming_datagram_stream_t incoming; | ||
poll_own_pollable_t incoming_pollable; | ||
udp_own_outgoing_datagram_stream_t outgoing; | ||
poll_own_pollable_t outgoing_pollable; | ||
} udp_socket_streams_t; | ||
|
||
typedef struct { | ||
} udp_socket_state_unbound_t; | ||
typedef struct { | ||
} udp_socket_state_bound_nostreams_t; | ||
|
||
typedef struct { | ||
udp_socket_streams_t streams; // Streams have no remote_address | ||
} udp_socket_state_bound_streaming_t; | ||
|
||
typedef struct { | ||
udp_socket_streams_t streams; // Streams have a remote_address | ||
} udp_socket_state_connected_t; | ||
|
||
// This is a tagged union. When adding/removing/renaming cases, be sure to keep the tag and union definitions in sync. | ||
// The "bound" state is split up into two distinct tags: | ||
// - "bound_nostreams": Bound, but no datagram streams set up (yet). That will be done the first time send or recv is called. | ||
// - "bound_streaming": Bound with active streams. | ||
typedef struct { | ||
enum { | ||
UDP_SOCKET_STATE_UNBOUND, | ||
UDP_SOCKET_STATE_BOUND_NOSTREAMS, | ||
UDP_SOCKET_STATE_BOUND_STREAMING, | ||
UDP_SOCKET_STATE_CONNECTED, | ||
} tag; | ||
union { | ||
udp_socket_state_unbound_t unbound; | ||
udp_socket_state_bound_nostreams_t bound_nostreams; | ||
udp_socket_state_bound_streaming_t bound_streaming; | ||
udp_socket_state_connected_t connected; | ||
}; | ||
} udp_socket_state_t; | ||
|
||
typedef struct { | ||
udp_own_udp_socket_t socket; | ||
poll_own_pollable_t socket_pollable; | ||
bool blocking; | ||
network_ip_address_family_t family; | ||
udp_socket_state_t state; | ||
} udp_socket_t; | ||
|
||
// This is a tagged union. When adding/removing/renaming cases, be sure to keep the tag and union definitions in sync. | ||
typedef struct { | ||
enum { | ||
DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET, | ||
DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET, | ||
} tag; | ||
union { | ||
tcp_socket_t tcp_socket; | ||
udp_socket_t udp_socket; | ||
}; | ||
} descriptor_table_entry_t; | ||
|
||
bool descriptor_table_insert(descriptor_table_entry_t entry, int *fd); | ||
|
||
bool descriptor_table_get_ref(int fd, descriptor_table_entry_t **entry); | ||
|
||
bool descriptor_table_remove(int fd, descriptor_table_entry_t *entry); | ||
|
||
#endif |
Oops, something went wrong.