summaryrefslogtreecommitdiffstats
path: root/source/cSocketThreads.h
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-07 08:49:00 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-07 08:49:00 +0100
commit16feb0924e2b872d9c6f24d97647591ec36b63c7 (patch)
treee27e7fbbd3e283261ad97e80c722e53122b75df1 /source/cSocketThreads.h
parentSlight cleanup (diff)
downloadcuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar.gz
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar.bz2
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar.lz
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar.xz
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.tar.zst
cuberite-16feb0924e2b872d9c6f24d97647591ec36b63c7.zip
Diffstat (limited to '')
-rw-r--r--source/cSocketThreads.h147
1 files changed, 147 insertions, 0 deletions
diff --git a/source/cSocketThreads.h b/source/cSocketThreads.h
new file mode 100644
index 000000000..b43d693ba
--- /dev/null
+++ b/source/cSocketThreads.h
@@ -0,0 +1,147 @@
+
+// cSocketThreads.h
+
+// Interfaces to the cSocketThreads class representing the heart of MCS's client networking.
+// This object takes care of network communication, groups sockets into threads and uses as little threads as possible for full read / write support
+// For more detail, see http://forum.mc-server.org/showthread.php?tid=327
+
+
+
+
+
+/// How many clients should one thread handle? (must be less than FD_SETSIZE - 1 for your platform)
+#define MAX_SLOTS 1
+
+
+
+
+
+#pragma once
+#ifndef CSOCKETTHREADS_H_INCLUDED
+#define CSOCKETTHREADS_H_INCLUDED
+
+#include "packets/cPacket.h"
+#include "cIsThread.h"
+
+
+
+
+// Check MAX_SLOTS:
+#if MAX_SLOTS >= FD_SETSIZE
+ #error "MAX_SLOTS must be less than FD_SETSIZE - 1 for your platform! (otherwise select() won't work)"
+#endif
+
+
+
+
+
+// fwd:
+class cSocket;
+class cClientHandle;
+
+
+
+
+
+class cSocketThreads
+{
+public:
+
+ // Clients of cSocketThreads must implement this interface to be able to communicate
+ class cCallback
+ {
+ public:
+ /// Called when data is received from the remote party
+ virtual void DataReceived(const char * a_Data, int a_Size) = 0;
+
+ /// Called when data can be sent to remote party; the function is supposed to append outgoing data to a_Data
+ virtual void GetOutgoingData(AString & a_Data) = 0;
+
+ /// Called when the socket has been closed for any reason
+ virtual void SocketClosed(void) = 0;
+ } ;
+
+
+ cSocketThreads(void);
+ ~cSocketThreads();
+
+ /// Add a (socket, client) pair for processing, data from a_Socket is to be sent to a_Client
+ void AddClient(cSocket * a_Socket, cCallback * a_Client);
+
+ /// Remove the socket (and associated client) from processing
+ void RemoveClient(cSocket * a_Socket);
+
+ /// Remove the associated socket and the client from processing
+ void RemoveClient(cCallback * a_Client);
+
+ /// Notify the thread responsible for a_Client that the client has something to write
+ void NotifyWrite(cCallback * a_Client);
+
+private:
+
+ class cSocketThread :
+ public cIsThread
+ {
+ typedef cIsThread super;
+
+ public:
+
+ cSocketThread(cSocketThreads * a_Parent);
+
+ // All these methods assume parent's m_CS is locked
+ bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; }
+ bool IsEmpty (void) const {return m_NumSlots == 0; }
+
+ void AddClient (cSocket * a_Socket, cCallback * a_Client);
+ bool RemoveClient(cCallback * a_Client); // Returns true if removed, false if not found
+ bool RemoveSocket(cSocket * a_Socket); // Returns true if removed, false if not found
+ bool HasClient (cCallback * a_Client) const;
+ bool HasSocket (cSocket * a_Socket) const;
+ bool NotifyWrite (cCallback * a_Client); // Returns true if client handled by this thread
+
+ bool Start(void); // Hide the cIsThread's Start method, we need to provide our own startup to create the control socket
+
+ private:
+
+ cSocketThreads * m_Parent;
+
+ // Two ends of the control socket, the first is select()-ed, the second is written to for notifications
+ cSocket m_ControlSocket1;
+ cSocket m_ControlSocket2;
+
+ // Socket-client-packetqueues triplets.
+ // Manipulation with these assumes that the parent's m_CS is locked
+ struct sSlot
+ {
+ cSocket * m_Socket;
+ cCallback * m_Client;
+ AString m_Outgoing; // If sending writes only partial data, the rest is stored here for another send
+ } ;
+ sSlot m_Slots[MAX_SLOTS];
+ int m_NumSlots; // Number of slots actually used
+
+ virtual void Execute(void) override;
+
+ void AddOrUpdatePacket(int a_Slot, cPacket * a_Packet); // Adds the packet to the specified slot, or updates an existing packet in that queue (EntityMoveLook filtering)
+
+ void PrepareSet (fd_set * a_Set, cSocket::xSocket & a_Highest); // Puts all sockets into the set, along with m_ControlSocket1
+ void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read
+ void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write
+ } ;
+
+ typedef std::list<cSocketThread *> cSocketThreadList;
+
+
+ cCriticalSection m_CS;
+ cSocketThreadList m_Threads;
+} ;
+
+
+
+
+
+#endif // CSOCKETTHREADS_H_INCLUDED
+
+
+
+