Modules/IPStack - Killing Threads_Yield
authorJohn Hodge (sonata) <[email protected]>
Mon, 28 Jan 2013 15:13:23 +0000 (23:13 +0800)
committerJohn Hodge (sonata) <[email protected]>
Mon, 28 Jan 2013 15:13:23 +0000 (23:13 +0800)
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/IPStack/tcp.h

index 2bb90d1..8b4f99d 100644 (file)
@@ -276,6 +276,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        srv->NewConnections = conn;
                VFS_MarkAvaliable( &srv->Node, 1 );
                SHORTREL(&srv->lConnections);
+               Semaphore_Signal(&srv->WaitingConnections, 1);
 
                // Send the SYN ACK
                hdr->Flags |= TCP_FLAG_ACK;
@@ -380,6 +381,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        {       
                                Log_Log("TCP", "ACKing SYN-ACK");
                                Connection->State = TCP_ST_OPEN;
+                               VFS_MarkFull(&Connection->Node, 0);
                        }
                        else
                        {
@@ -394,8 +396,9 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                if( Header->Flags & TCP_FLAG_ACK )
                {
                        // TODO: Handle max half-open limit
-                       Connection->State = TCP_ST_OPEN;
                        Log_Log("TCP", "Connection fully opened");
+                       Connection->State = TCP_ST_OPEN;
+                       VFS_MarkFull(&Connection->Node, 0);
                }
                break;
                
@@ -915,15 +918,9 @@ int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
        ENTER("pNode iPos", Node, Pos);
 
        Log_Log("TCP", "Thread %i waiting for a connection", Threads_GetTID());
-       for(;;)
-       {
-               SHORTLOCK( &srv->lConnections );
-               if( srv->NewConnections != NULL )       break;
-               SHORTREL( &srv->lConnections );
-               Threads_Yield();        // TODO: Sleep until poked
-       }
+       Semaphore_Wait( &srv->WaitingConnections, 1 );
        
-
+       SHORTLOCK(&srv->lConnections);
        // Increment the new list (the current connection is still on the 
        // normal list)
        conn = srv->NewConnections;
@@ -1076,6 +1073,7 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
        conn->Node.NumACLs = 1;
        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
        conn->Node.Type = &gTCP_ClientNodeType;
+       conn->Node.BufferFull = 1;      // Cleared when connection opens
 
        conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE );
        #if 0
@@ -1112,14 +1110,9 @@ size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
        LOG("conn = %p {State:%i}", conn, conn->State);
        
-       // Check if connection is estabilishing
-       // - TODO: Sleep instead (maybe using VFS_SelectNode to wait for the
-       //   data to be availiable
-       while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
-               Threads_Yield();
-       
-       // If the conneciton is not open, then clean out the recieved buffer
-       if( conn->State != TCP_ST_OPEN )
+       // If the connection has been closed (state > ST_OPEN) then clear
+       // any stale data in the buffer (until it is empty (until it is empty))
+       if( conn->State > TCP_ST_OPEN )
        {
                Mutex_Acquire( &conn->lRecievedPackets );
                len = RingBuffer_Read( Buffer, conn->RecievedBuffer, Length );
@@ -1198,16 +1191,16 @@ size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void
 //             Buffer, Length);
 //     #endif
        
-       // Check if connection is open
-       while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
-               Threads_Yield();
-       
-       if( conn->State != TCP_ST_OPEN ) {
+       // Don't allow a write to a closed connection
+       if( conn->State > TCP_ST_OPEN ) {
                VFS_MarkError(Node, 1);
                LEAVE('i', -1);
                return -1;
        }
        
+       // Wait
+       VFS_SelectNode(Node, VFS_SELECT_WRITE|VFS_SELECT_ERROR, NULL, "TCP_Client_Write");
+       
        do
        {
                 int    len = (rem < TCP_MAX_PACKET_SIZE) ? rem : TCP_MAX_PACKET_SIZE;
@@ -1312,13 +1305,10 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        LEAVE_RET('i', 0);
 
                {
-                       tTime   timeout_end = now() + conn->Interface->TimeoutDelay;
+                       tTime   timeout = conn->Interface->TimeoutDelay;
        
                        TCP_StartConnection(conn);
-                       // TODO: Wait for connection to open
-                       while( conn->State == TCP_ST_SYN_SENT && timeout_end > now() ) {
-                               Threads_Yield();
-                       }
+                       VFS_SelectNode(&conn->Node, VFS_SELECT_WRITE, &timeout, "TCP Connection");
                        if( conn->State == TCP_ST_SYN_SENT )
                                LEAVE_RET('i', 0);
                }
index 2247b90..42682ac 100644 (file)
@@ -8,6 +8,7 @@
 #include "ipstack.h"
 #include <adt.h>       // tRingBuffer
 #include <timers.h>    // tTimer
+#include <semaphore.h> // tSemaphore
 
 typedef struct sTCPHeader      tTCPHeader;
 typedef struct sTCPListener    tTCPListener;
@@ -69,6 +70,7 @@ struct sTCPListener
        tInterface      *Interface;     //!< Listening Interface
        tVFS_Node       Node;   //!< Server Directory node
         int    NextID;         //!< Name of the next connection
+       tSemaphore      WaitingConnections;
        tShortSpinlock  lConnections;   //!< Spinlock for connections
        tTCPConnection  *Connections;   //!< Connections (linked list)
        tTCPConnection  *volatile NewConnections;

UCC git Repository :: git.ucc.asn.au