-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c6dc3da
commit db54296
Showing
9 changed files
with
242 additions
and
18 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
65 changes: 65 additions & 0 deletions
65
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEngine.Wasi.cs
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,65 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections.Concurrent; | ||
using System.Diagnostics; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace System.Net.Sockets | ||
{ | ||
internal sealed partial class SocketAsyncEngine : IThreadPoolWorkItem | ||
{ | ||
private SocketAsyncEngine() | ||
{ | ||
#pragma warning disable CS4014 | ||
WasiSocketsEventLoop(); | ||
#pragma warning restore CS4014 | ||
} | ||
|
||
private async Task WasiSocketsEventLoop() | ||
{ | ||
try | ||
{ | ||
SocketEventHandler handler = new SocketEventHandler(this); | ||
while (true) | ||
{ | ||
int numEvents = EventBufferCount; | ||
await WaitForAnySocketPollable().ConfigureAwait(false); | ||
|
||
// The native shim is responsible for ensuring this condition. | ||
Debug.Assert(numEvents > 0, $"Unexpected numEvents: {numEvents}"); | ||
|
||
// Only enqueue a work item if the stage is NotScheduled. | ||
// Otherwise there must be a work item already queued or another thread already handling parallelization. | ||
if (handler.HandleSocketEvents(numEvents) && | ||
Interlocked.Exchange( | ||
ref _eventQueueProcessingStage, | ||
EventQueueProcessingStage.Scheduled) == EventQueueProcessingStage.NotScheduled) | ||
{ | ||
ThreadPool.UnsafeQueueUserWorkItem(this, preferLocal: false); | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
Environment.FailFast("Exception thrown from SocketAsyncEngine event loop: " + e.ToString(), e); | ||
} | ||
} | ||
|
||
#pragma warning disable CA1822 // TODO remove | ||
private Task WaitForAnySocketPollable() | ||
{ | ||
TaskCompletionSource todo = new TaskCompletionSource(); | ||
/* TODO something like this, but with handle->pollable conversion | ||
Interop.Error err = Interop.Sys.WaitForSocketEvents(_port, handler.Buffer, &numEvents); | ||
if (err != Interop.Error.SUCCESS) | ||
{ | ||
throw new InternalException(err); | ||
}*/ | ||
return todo.Task; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// copy from https:/WebAssembly/wasi-libc/blob/230d4be6c54bec93181050f9e25c87150506bdd0/libc-bottom-half/headers/private/wasi/descriptor_table.h | ||
// https:/WebAssembly/wasi-libc/blob/main/LICENSE-MIT | ||
|
||
#ifndef DESCRIPTOR_TABLE_H | ||
#define DESCRIPTOR_TABLE_H | ||
|
||
#include <wasi/wasip2.h> | ||
|
||
typedef struct { | ||
int dummy; | ||
} tcp_socket_state_unbound_t; | ||
typedef struct { | ||
int dummy; | ||
} tcp_socket_state_bound_t; | ||
typedef struct { | ||
int dummy; | ||
} tcp_socket_state_connecting_t; | ||
typedef struct { | ||
int dummy; | ||
} 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 { | ||
int dummy; | ||
} udp_socket_state_unbound_t; | ||
typedef struct { | ||
int dummy; | ||
} 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.