mirror of https://github.com/adamdruppe/arsd.git
Added support to wasm and custom runtimes
Use `ArsdUseCustomRuntime` for supporting them.
This commit is contained in:
parent
8cb756ba6f
commit
9f59feeca4
88
core.d
88
core.d
|
@ -32,11 +32,30 @@ module arsd.core;
|
||||||
|
|
||||||
// see: https://wiki.openssl.org/index.php/Simple_TLS_Server
|
// see: https://wiki.openssl.org/index.php/Simple_TLS_Server
|
||||||
|
|
||||||
import core.thread;
|
///ArsdUseCustomRuntime is used since other derived work from WebAssembly may be used and thus specified in the CLI
|
||||||
import core.volatile;
|
version(WebAssembly) version = ArsdUseCustomRuntime;
|
||||||
import core.atomic;
|
version(ArsdUseCustomRuntime)
|
||||||
import core.time;
|
{
|
||||||
|
version = EmptyEventLoop;
|
||||||
|
version = UseStdioWriteln;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
version = HasFile;
|
||||||
|
version = HasSocket;
|
||||||
|
version = HasThread;
|
||||||
|
version = HasErrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(HasThread)
|
||||||
|
{
|
||||||
|
import core.thread;
|
||||||
|
import core.volatile;
|
||||||
|
import core.atomic;
|
||||||
|
import core.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(HasErrno)
|
||||||
import core.stdc.errno;
|
import core.stdc.errno;
|
||||||
|
|
||||||
import core.attribute;
|
import core.attribute;
|
||||||
|
@ -2083,7 +2102,7 @@ package(arsd) enum EventLoopType {
|
||||||
|
|
||||||
|
|
||||||
// the GC may not be able to see this! remember, it can be hidden inside kernel buffers
|
// the GC may not be able to see this! remember, it can be hidden inside kernel buffers
|
||||||
private class CallbackHelper {
|
version(HasThread) private class CallbackHelper {
|
||||||
import core.memory;
|
import core.memory;
|
||||||
|
|
||||||
void call() {
|
void call() {
|
||||||
|
@ -2307,7 +2326,7 @@ version(Windows) {
|
||||||
/++
|
/++
|
||||||
An `AbstractFile` represents a file handle on the operating system level. You cannot do much with it.
|
An `AbstractFile` represents a file handle on the operating system level. You cannot do much with it.
|
||||||
+/
|
+/
|
||||||
class AbstractFile {
|
version(HasFile) class AbstractFile {
|
||||||
private {
|
private {
|
||||||
NativeFileHandle handle;
|
NativeFileHandle handle;
|
||||||
}
|
}
|
||||||
|
@ -2514,7 +2533,7 @@ class AbstractFile {
|
||||||
/++
|
/++
|
||||||
|
|
||||||
+/
|
+/
|
||||||
class File : AbstractFile {
|
version(HasFile) class File : AbstractFile {
|
||||||
|
|
||||||
/++
|
/++
|
||||||
Opens a file in synchronous access mode.
|
Opens a file in synchronous access mode.
|
||||||
|
@ -2553,7 +2572,7 @@ class File : AbstractFile {
|
||||||
/++
|
/++
|
||||||
Only one operation can be pending at any time in the current implementation.
|
Only one operation can be pending at any time in the current implementation.
|
||||||
+/
|
+/
|
||||||
class AsyncFile : AbstractFile {
|
version(HasFile) class AsyncFile : AbstractFile {
|
||||||
/++
|
/++
|
||||||
Opens a file in asynchronous access mode.
|
Opens a file in asynchronous access mode.
|
||||||
+/
|
+/
|
||||||
|
@ -2855,7 +2874,7 @@ enum OnOutOfSpace {
|
||||||
|
|
||||||
interface lookup for bind (stream or dgram)
|
interface lookup for bind (stream or dgram)
|
||||||
+/
|
+/
|
||||||
struct SocketAddress {
|
version(HasSocket) struct SocketAddress {
|
||||||
import core.sys.posix.netdb;
|
import core.sys.posix.netdb;
|
||||||
|
|
||||||
/++
|
/++
|
||||||
|
@ -3098,7 +3117,7 @@ private version(Windows) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncSocket : AsyncFile {
|
version(HasFile) class AsyncSocket : AsyncFile {
|
||||||
// otherwise: accept, bind, connect, shutdown, close.
|
// otherwise: accept, bind, connect, shutdown, close.
|
||||||
|
|
||||||
static auto lastError() {
|
static auto lastError() {
|
||||||
|
@ -3297,7 +3316,7 @@ class AsyncSocket : AsyncFile {
|
||||||
|
|
||||||
NOT IMPLEMENTED / NOT STABLE
|
NOT IMPLEMENTED / NOT STABLE
|
||||||
+/
|
+/
|
||||||
class AsyncConnectRequest : AsyncOperationRequest {
|
version(HasSocket) class AsyncConnectRequest : AsyncOperationRequest {
|
||||||
// FIXME: i should take a list of addresses and take the first one that succeeds, so a getaddrinfo can be sent straight in.
|
// FIXME: i should take a list of addresses and take the first one that succeeds, so a getaddrinfo can be sent straight in.
|
||||||
this(AsyncSocket socket, SocketAddress address, ubyte[] dataToWrite) {
|
this(AsyncSocket socket, SocketAddress address, ubyte[] dataToWrite) {
|
||||||
|
|
||||||
|
@ -3310,7 +3329,7 @@ class AsyncConnectRequest : AsyncOperationRequest {
|
||||||
}
|
}
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncConnectResponse : AsyncOperationResponse {
|
version(HasSocket) class AsyncConnectResponse : AsyncOperationResponse {
|
||||||
const SystemErrorCode errorCode;
|
const SystemErrorCode errorCode;
|
||||||
|
|
||||||
this(SystemErrorCode errorCode) {
|
this(SystemErrorCode errorCode) {
|
||||||
|
@ -3330,7 +3349,7 @@ class AsyncConnectResponse : AsyncOperationResponse {
|
||||||
|
|
||||||
NOT IMPLEMENTED / NOT STABLE
|
NOT IMPLEMENTED / NOT STABLE
|
||||||
+/
|
+/
|
||||||
class AsyncAcceptRequest : AsyncOperationRequest {
|
version(HasSocket) class AsyncAcceptRequest : AsyncOperationRequest {
|
||||||
AsyncSocket socket;
|
AsyncSocket socket;
|
||||||
|
|
||||||
override void start() {}
|
override void start() {}
|
||||||
|
@ -3387,7 +3406,7 @@ class AsyncAcceptRequest : AsyncOperationRequest {
|
||||||
}
|
}
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncAcceptResponse : AsyncOperationResponse {
|
version(HasSocket) class AsyncAcceptResponse : AsyncOperationResponse {
|
||||||
AsyncSocket newSocket;
|
AsyncSocket newSocket;
|
||||||
const SystemErrorCode errorCode;
|
const SystemErrorCode errorCode;
|
||||||
|
|
||||||
|
@ -3407,7 +3426,7 @@ class AsyncAcceptResponse : AsyncOperationResponse {
|
||||||
|
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncReceiveRequest : AsyncOperationRequest {
|
version(HasSocket) class AsyncReceiveRequest : AsyncOperationRequest {
|
||||||
struct LowLevelOperation {
|
struct LowLevelOperation {
|
||||||
AsyncSocket file;
|
AsyncSocket file;
|
||||||
ubyte[] buffer;
|
ubyte[] buffer;
|
||||||
|
@ -3455,7 +3474,7 @@ class AsyncReceiveRequest : AsyncOperationRequest {
|
||||||
}
|
}
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncReceiveResponse : AsyncOperationResponse {
|
version(HasSocket) class AsyncReceiveResponse : AsyncOperationResponse {
|
||||||
const ubyte[] bufferWritten;
|
const ubyte[] bufferWritten;
|
||||||
const SystemErrorCode errorCode;
|
const SystemErrorCode errorCode;
|
||||||
|
|
||||||
|
@ -3471,7 +3490,7 @@ class AsyncReceiveResponse : AsyncOperationResponse {
|
||||||
|
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncSendRequest : AsyncOperationRequest {
|
version(HasSocket) class AsyncSendRequest : AsyncOperationRequest {
|
||||||
struct LowLevelOperation {
|
struct LowLevelOperation {
|
||||||
AsyncSocket file;
|
AsyncSocket file;
|
||||||
const(ubyte)[] buffer;
|
const(ubyte)[] buffer;
|
||||||
|
@ -3517,7 +3536,7 @@ class AsyncSendRequest : AsyncOperationRequest {
|
||||||
|
|
||||||
/++
|
/++
|
||||||
+/
|
+/
|
||||||
class AsyncSendResponse : AsyncOperationResponse {
|
version(HasSocket) class AsyncSendResponse : AsyncOperationResponse {
|
||||||
const ubyte[] bufferWritten;
|
const ubyte[] bufferWritten;
|
||||||
const SystemErrorCode errorCode;
|
const SystemErrorCode errorCode;
|
||||||
|
|
||||||
|
@ -3539,7 +3558,7 @@ class AsyncSendResponse : AsyncOperationResponse {
|
||||||
|
|
||||||
NOT IMPLEMENTED / NOT STABLE
|
NOT IMPLEMENTED / NOT STABLE
|
||||||
+/
|
+/
|
||||||
class StreamServer {
|
version(HasSocket) class StreamServer {
|
||||||
AsyncSocket[] sockets;
|
AsyncSocket[] sockets;
|
||||||
|
|
||||||
this(SocketAddress[] listenTo, int backlog = 8) {
|
this(SocketAddress[] listenTo, int backlog = 8) {
|
||||||
|
@ -3586,7 +3605,7 @@ unittest {
|
||||||
|
|
||||||
NOT IMPLEMENTED / NOT STABLE
|
NOT IMPLEMENTED / NOT STABLE
|
||||||
+/
|
+/
|
||||||
class DatagramListener {
|
version(HasSocket) class DatagramListener {
|
||||||
// whenever a udp message arrives, it calls your callback
|
// whenever a udp message arrives, it calls your callback
|
||||||
// can be on a specific thread or on any thread
|
// can be on a specific thread or on any thread
|
||||||
|
|
||||||
|
@ -3597,7 +3616,7 @@ class DatagramListener {
|
||||||
/++
|
/++
|
||||||
Just in case I decide to change the implementation some day.
|
Just in case I decide to change the implementation some day.
|
||||||
+/
|
+/
|
||||||
alias AsyncAnonymousPipe = AsyncFile;
|
version(HasFile) alias AsyncAnonymousPipe = AsyncFile;
|
||||||
|
|
||||||
|
|
||||||
// AsyncAnonymousPipe connectNamedPipe(AsyncAnonymousPipe preallocated, string name)
|
// AsyncAnonymousPipe connectNamedPipe(AsyncAnonymousPipe preallocated, string name)
|
||||||
|
@ -3614,7 +3633,7 @@ alias AsyncAnonymousPipe = AsyncFile;
|
||||||
History:
|
History:
|
||||||
previously in minigui as a private function. Moved to arsd.core on April 3, 2023
|
previously in minigui as a private function. Moved to arsd.core on April 3, 2023
|
||||||
+/
|
+/
|
||||||
GetFilesResult getFiles(string directory, scope void delegate(string name, bool isDirectory) dg) {
|
version(HasFile) GetFilesResult getFiles(string directory, scope void delegate(string name, bool isDirectory) dg) {
|
||||||
// FIXME: my buffers here aren't great lol
|
// FIXME: my buffers here aren't great lol
|
||||||
|
|
||||||
SavedArgument[1] argsForException() {
|
SavedArgument[1] argsForException() {
|
||||||
|
@ -4220,7 +4239,7 @@ mixin template OverlappedIoRequest(Response, LowLevelOperation) {
|
||||||
/++
|
/++
|
||||||
You can write to a file asynchronously by creating one of these.
|
You can write to a file asynchronously by creating one of these.
|
||||||
+/
|
+/
|
||||||
final class AsyncWriteRequest : AsyncOperationRequest {
|
version(HasSocket) final class AsyncWriteRequest : AsyncOperationRequest {
|
||||||
struct LowLevelOperation {
|
struct LowLevelOperation {
|
||||||
AsyncFile file;
|
AsyncFile file;
|
||||||
ubyte[] buffer;
|
ubyte[] buffer;
|
||||||
|
@ -4274,7 +4293,7 @@ class AsyncWriteResponse : AsyncOperationResponse {
|
||||||
/++
|
/++
|
||||||
|
|
||||||
+/
|
+/
|
||||||
final class AsyncReadRequest : AsyncOperationRequest {
|
version(HasSocket) final class AsyncReadRequest : AsyncOperationRequest {
|
||||||
struct LowLevelOperation {
|
struct LowLevelOperation {
|
||||||
AsyncFile file;
|
AsyncFile file;
|
||||||
ubyte[] buffer;
|
ubyte[] buffer;
|
||||||
|
@ -4344,7 +4363,7 @@ class AsyncReadResponse : AsyncOperationResponse {
|
||||||
runHelperFunction() - whomever it reports to is the parent
|
runHelperFunction() - whomever it reports to is the parent
|
||||||
+/
|
+/
|
||||||
|
|
||||||
class ScheduableTask : Fiber {
|
version(HasThread) class ScheduableTask : Fiber {
|
||||||
private void delegate() dg;
|
private void delegate() dg;
|
||||||
|
|
||||||
// linked list stuff
|
// linked list stuff
|
||||||
|
@ -4435,7 +4454,7 @@ void delegate(Throwable t) taskUncaughtException;
|
||||||
History:
|
History:
|
||||||
Added August 11, 2023 (dub v11.1)
|
Added August 11, 2023 (dub v11.1)
|
||||||
+/
|
+/
|
||||||
SchedulableTaskController inSchedulableTask() {
|
version(HasThread) SchedulableTaskController inSchedulableTask() {
|
||||||
import core.thread.fiber;
|
import core.thread.fiber;
|
||||||
|
|
||||||
if(auto fiber = Fiber.getThis) {
|
if(auto fiber = Fiber.getThis) {
|
||||||
|
@ -4446,7 +4465,7 @@ SchedulableTaskController inSchedulableTask() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ditto
|
/// ditto
|
||||||
struct SchedulableTaskController {
|
version(HasThread) struct SchedulableTaskController {
|
||||||
private this(ScheduableTask fiber) {
|
private this(ScheduableTask fiber) {
|
||||||
this.fiber = fiber;
|
this.fiber = fiber;
|
||||||
}
|
}
|
||||||
|
@ -4497,7 +4516,7 @@ class TaskCancelledException : object.Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CoreWorkerThread : Thread {
|
version(HasThread) private class CoreWorkerThread : Thread {
|
||||||
this(EventLoopType type) {
|
this(EventLoopType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
|
@ -4596,7 +4615,7 @@ private int numberOfCpus() {
|
||||||
Its destructor runs the event loop then waits to for the workers to finish to clean them up.
|
Its destructor runs the event loop then waits to for the workers to finish to clean them up.
|
||||||
+/
|
+/
|
||||||
// FIXME: single instance?
|
// FIXME: single instance?
|
||||||
struct ArsdCoreApplication {
|
version(HasThread) struct ArsdCoreApplication {
|
||||||
private ICoreEventLoop impl;
|
private ICoreEventLoop impl;
|
||||||
|
|
||||||
/++
|
/++
|
||||||
|
@ -4650,6 +4669,7 @@ struct ArsdCoreApplication {
|
||||||
|
|
||||||
|
|
||||||
private class CoreEventLoopImplementation : ICoreEventLoop {
|
private class CoreEventLoopImplementation : ICoreEventLoop {
|
||||||
|
version(EmptyEventLoop) void runOnce(){}
|
||||||
|
|
||||||
version(Arsd_core_kqueue) {
|
version(Arsd_core_kqueue) {
|
||||||
// this thread apc dispatches go as a custom event to the queue
|
// this thread apc dispatches go as a custom event to the queue
|
||||||
|
@ -5579,7 +5599,7 @@ class WritableStream {
|
||||||
|
|
||||||
It reads binary data.
|
It reads binary data.
|
||||||
+/
|
+/
|
||||||
class ReadableStream {
|
version(HasThread) class ReadableStream {
|
||||||
|
|
||||||
this() {
|
this() {
|
||||||
|
|
||||||
|
@ -6259,7 +6279,13 @@ void writeln(T...)(T t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void actuallyWriteToStdout(scope char[] buffer) @trusted {
|
private void actuallyWriteToStdout(scope char[] buffer) @trusted {
|
||||||
version(Windows) {
|
|
||||||
|
version(UseStdioWriteln)
|
||||||
|
{
|
||||||
|
import std.stdio;
|
||||||
|
writeln(buffer);
|
||||||
|
}
|
||||||
|
else version(Windows) {
|
||||||
import core.sys.windows.wincon;
|
import core.sys.windows.wincon;
|
||||||
|
|
||||||
auto hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
auto hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
Loading…
Reference in New Issue