From 27b731081e09990d4827666a4ac64f48d28d9fe0 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 24 Sep 2023 16:37:12 -0500 Subject: [PATCH] bugfixes: miscellaneous --- core/encoding/json/types.onyx | 20 +++++++++++--------- core/io/reader.onyx | 33 +++++++++++++++------------------ core/net/tcp.onyx | 13 +++++++++++++ 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/core/encoding/json/types.onyx b/core/encoding/json/types.onyx index 2eb3a4f0..6cce0a1b 100644 --- a/core/encoding/json/types.onyx +++ b/core/encoding/json/types.onyx @@ -244,23 +244,25 @@ set :: #match { // Quick thing for allocating json values on the stack. macro (v: Value, key: str, value: str, - dont_copy_key := false, dont_copy_value := false) { + dont_copy_key := false, dont_copy_value := false) -> i32 { _Value_String :: _Value_String; _Value_Object :: _Value_Object; + _Value :: _Value + Value :: Value use core {string} v_ := cast(^_Value) v; - if v_.type == .Object { - k := key if dont_copy_key else string.alloc_copy(key); - v := value if dont_copy_value else string.alloc_copy(value); + if v_.type != .Object do return 0; + k := key if dont_copy_key else string.alloc_copy(key); + val := value if dont_copy_value else string.alloc_copy(value); - json_value := init(_Value_String); - json_value.str_ = v; - json_value.dont_free = dont_copy_value; + json_value := _Value_String.{ + str_ = val, + dont_free = dont_copy_value + }; - (cast(^_Value_Object) v_).object_ << .{ k, dont_copy_key, ^json_value }; - } + (cast(^_Value_Object) v_).object_ << .{ k, dont_copy_key, ~~ cast(&_Value) ^json_value }; } } diff --git a/core/io/reader.onyx b/core/io/reader.onyx index 6858f47c..239e89cc 100644 --- a/core/io/reader.onyx +++ b/core/io/reader.onyx @@ -98,6 +98,14 @@ read_all :: (use reader: &Reader, allocator := context.allocator) -> [] u8 { output := array.make(u8, 128, allocator=allocator); while !reader_empty(reader) { + buffered := reader_get_buffered(reader); + if buffered > 0 { + array.ensure_capacity(&output, output.count + buffered); + memory.copy(output.data + output.count, buffer.data, buffered); + output.count += buffered; + start = end; + } + if err := reader_read_next_chunk(reader); err != .None && err != .ReadPending { break; } @@ -106,14 +114,6 @@ read_all :: (use reader: &Reader, allocator := context.allocator) -> [] u8 { reader_consume_error(reader); break; } - - buffered := reader_get_buffered(reader); - if buffered > 0 { - array.ensure_capacity(&output, output.count + buffered); - memory.copy(output.data + output.count, buffer.data, buffered); - output.count += buffered; - start = end; - } } return output; @@ -206,13 +206,13 @@ read_fill_buffer :: (use reader: &Reader, bytes: [] u8) -> Error { write_index := 0; while n > 0 && !reader_empty(reader) { - reader_read_next_chunk(reader); - - to_write := math.min(n, end); - memory.copy(bytes.data + write_index, buffer.data, to_write); + to_write := math.min(n, end - start); + memory.copy(bytes.data + write_index, buffer.data + start, to_write); n -= to_write; write_index += to_write; start += to_write; + + reader_read_next_chunk(reader); } last_byte = cast(i32) bytes[write_index - 1]; @@ -336,8 +336,7 @@ read_line :: (use reader: &Reader, consume_newline := true, allocator := context return buffer[start .. count]; } - out: [..] u8; - array.init(&out, allocator=allocator); + out := make(dyn_str, allocator); while done := false; !done { if start == end { @@ -406,8 +405,7 @@ read_word :: (use reader: &Reader, numeric_allowed := false, allocator := contex return buffer[start .. count]; } - out: [..] u8; - array.init(&out, allocator=allocator); + out := make(dyn_str, allocator); while done := false; !done { count := start; @@ -473,8 +471,7 @@ read_until :: (use reader: &Reader, until: u8, skip: u32 = 0, allocator := conte return buffer[start .. count]; } - out: [..] u8; - array.init(&out, allocator=allocator); + out := make(dyn_str, allocator); while done := false; !done { count := start; diff --git a/core/net/tcp.onyx b/core/net/tcp.onyx index 8b7a1b98..7d5f72eb 100644 --- a/core/net/tcp.onyx +++ b/core/net/tcp.onyx @@ -350,6 +350,19 @@ wait_to_get_client_messages :: (use server: &TCP_Server) -> [] &TCP_Server.Clien } } + // + // If there are no "active" clients, but we are hitting this function, + // there are clients, but they are still being processed with .ready, + // events. If we continue, we will end up waiting for `pulse_time_ms` + // seconds, since there is nothing to wake up the polling action. In + // a rare chance when this is multi-threaded, waiting could stall other + // threads because we haven't pushed new ready events out. So, we have + // to immediately return, and enter a sort of complicated "spin loop" + // in order to not stall worker threads. + if active_clients.count == 0 { + return .{ null, 0 }; + } + status_buffer := alloc.array_from_stack(Socket_Poll_Status, client_count); socket_poll_all(cast([] &Socket) active_clients, pulse_time_ms, status_buffer); -- 2.25.1