bugfix: removed threading in TCP server for now, due to race condition
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 7 Apr 2023 15:09:15 +0000 (10:09 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 7 Apr 2023 15:09:15 +0000 (10:09 -0500)
core/net/tcp.onyx

index b2685f412c3a0e11e00ed7e2c5d2c554dec2ce66..0408c81cf37b5d76da9122c7e2d2dea7256d6aa4 100644 (file)
@@ -4,7 +4,6 @@ package core.net
     #error "Cannot include this file. Platform not supported.";
 }
 
-use core.sync
 use core.thread
 use core.array
 use core.memory
@@ -25,8 +24,6 @@ TCP_Connection :: struct {
     event_allocator: Allocator;
     events: [..] TCP_Event;
     event_cursor := 0;
-
-    event_mutex: sync.Mutex;
 }
 
 TCP_Event :: struct {
@@ -108,9 +105,7 @@ TCP_Server :: struct {
 
     client_allocator: Allocator;
     clients: [] &Client;
-
-    // max clients is stored as clients.count.
-    client_count: u32;
+    client_count: u32; // max clients is stored as clients.count.
 
     listener_thread: thread.Thread;
 
@@ -166,48 +161,16 @@ tcp_server_make :: (max_clients := 32, allocator := context.allocator) -> &TCP_S
     server.clients = make([] &TCP_Server.Client, max_clients, allocator=allocator);
     array.fill(server.clients, null);
 
-    sync.mutex_init(&server.event_mutex);
-
     return server;
 }
 
-#local tcp_server_listener :: (use server: &TCP_Server) {
-    while server.alive {
-        if server.client_count == server.clients.count {
-            os.sleep(1);
-            continue;
-        }
-
-        client_socket, client_addr := socket->accept();
-        if !client_socket.vtable {
-            continue;
-        }
-
-        client := new(TCP_Server.Client, allocator=client_allocator);
-        client.state = .Alive;
-        client.socket = client_socket;
-        client.address = client_addr;
-
-        for& clients do if *it == null { *it = client; break; }
-        server.client_count += 1;
-
-        conn_event := new(TCP_Event.Connection, allocator=server.event_allocator);
-        conn_event.address = &client.address;
-        conn_event.client = client;
-
-        sync.critical_section(&server.event_mutex) {
-            server.events << .{ .Connection, conn_event }; // @Threading
-        }
-    }
-}
-
 tcp_server_listen :: (use server: &TCP_Server, port: u16) -> bool {
     sa: Socket_Address;
     make_ipv4_address(&sa, 0x00000000, port);
     if !(socket->bind(&sa)) do return false;
 
     socket->listen();
-    thread.spawn(&listener_thread, server, tcp_server_listener);
+    socket->setting(.NonBlocking, 1);
     return true;
 }
 
@@ -225,6 +188,27 @@ tcp_server_stop :: (use server: &TCP_Server) {
 }
 
 tcp_server_pulse :: (use server: &TCP_Server) -> bool {
+    //
+    // Check for new connection
+    client_socket, client_addr := socket->accept();
+    if client_socket.vtable {
+        client := new(TCP_Server.Client, allocator=client_allocator);
+        client.state = .Alive;
+        client.socket = client_socket;
+        client.address = client_addr;
+
+        for& clients do if *it == null { *it = client; break; }
+        server.client_count += 1;
+
+        conn_event := new(TCP_Event.Connection, allocator=server.event_allocator);
+        conn_event.address = &client.address;
+        conn_event.client = client;
+
+        server.events << .{ .Connection, conn_event };
+    }
+
+    // 
+    // Process dead clients
     for& clients {
         client := *it;
         if !client do continue;
@@ -284,18 +268,14 @@ tcp_server_pulse :: (use server: &TCP_Server) -> bool {
             data_event.client  = it;
             data_event.address = &it.address;
             data_event.contents = memory.copy_slice(msg_buffer[0 .. bytes_read], allocator=server.event_allocator);
-            sync.critical_section(&server.event_mutex) {
-                server.events << .{ .Data, data_event }; // @Threading // See comment above.
-            }
+            server.events << .{ .Data, data_event };
 
         } elseif !it.recv_ready_event_present {
             it.recv_ready_event_present = true;
             ready_event := new(TCP_Event.Ready, allocator=server.event_allocator);
             ready_event.client  = it;
             ready_event.address = &it.address;
-            sync.critical_section(&server.event_mutex) {
-                server.events << .{ .Ready, ready_event }; // @Threading // See comment above.
-            }
+            server.events << .{ .Ready, ready_event };
         }
     }
 
@@ -305,9 +285,7 @@ tcp_server_pulse :: (use server: &TCP_Server) -> bool {
             disconnect_event := new(TCP_Event.Disconnection, allocator=server.event_allocator);
             disconnect_event.client  = it;
             disconnect_event.address = &it.address;
-            sync.critical_section(&server.event_mutex) {
-                server.events << .{ .Disconnection, disconnect_event }; // @Threading // See comment above.
-            }
+            server.events << .{ .Disconnection, disconnect_event };
         }
     }