bugfixes: miscellaneous
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 24 Sep 2023 21:37:12 +0000 (16:37 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 24 Sep 2023 21:37:12 +0000 (16:37 -0500)
core/encoding/json/types.onyx
core/io/reader.onyx
core/net/tcp.onyx

index 2eb3a4f0593963c51019a631b223ecd659d09b81..6cce0a1bf2401ecece033abf8e5feac5e13412fb 100644 (file)
@@ -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 };
     }
 }
 
index 6858f47cce10f043cc002d4c12832ce659b459a9..239e89cc7ccdb4f1fc74eb668a1d6d82414b50b9 100644 (file)
@@ -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;
index 8b7a1b98afb5168ed338a8761cfa34e80404b36c..7d5f72ebe8b3c4b0c114c5cf1cd1a00cd90eb4ea 100644 (file)
@@ -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);