7 #define WIN32_LEAN_AND_MEAN
11 static WSADATA wsaData;
13 #elif defined(__unix__) || defined(__APPLE__)
20 #include <netinet/in.h>
22 #include <sys/socket.h>
24 #include <sys/types.h>
26 #include <arpa/inet.h>
30 typedef struct hostent HOSTENT;
31 typedef struct sockaddr SOCKADDR;
32 typedef struct sockaddr_in SOCKADDR_IN;
33 typedef struct in_addr IN_ADDR;
34 #define closesocket(s) close(s)
38 import "GuiApplication"
42 private struct NetworkData
44 // Connections to the outside world
48 // Ongoing Connections
49 OldList connectSockets;
51 fd_set readSet, writeSet, exceptSet;
52 fd_set selectRS, selectWS, selectES;
56 // Synchronization Elements
58 Semaphore socketsSemaphore;
59 Semaphore selectSemaphore;
62 bool networkInitialized;
63 bool networkTerminated;
64 uint errorLevel, lastErrorCode;
76 static class NetworkThread : Thread
81 while(!network.networkTerminated)
87 struct timeval tv = { 0, 0 }; // TESTING 0 INSTEAD OF (int)(1000000 / 18.2) };
89 network.selectRS = network.readSet, network.selectWS = network.writeSet, network.selectES = network.exceptSet;
91 network.mutex.Release();
93 Log("[N] Waiting for network event...\n");
95 if(select(ns, &network.selectRS, &network.selectWS, &network.selectES, &tv))
98 network.networkEvent = true;
100 Log("[N] Signaling Network event\n");
102 guiApp.SignalEvent();
104 Log("[N] Waiting for select semaphore in Network Thread...\n");
106 network.mutex.Release();
107 network.selectSemaphore.Wait();
108 network.mutex.Wait();
112 ecere::sys::Sleep(1 / 18.2f);
113 network.mutex.Wait();
118 network.mutex.Release();
119 network.socketsSemaphore.Wait();
120 network.mutex.Wait();
124 network.mutex.Release();
129 void Network_DetermineMaxSocket()
134 network.mutex.Wait();
136 for(socket = network.sockets.first; socket; socket = socket.next)
137 if(!socket.processAlone && !socket.destroyed && socket.s >= network.ns)
138 network.ns = (int)(socket.s + 1);
139 for(socket = network.connectSockets.first; socket; socket = socket.next)
140 if(!socket.destroyed && socket.s >= network.ns)
141 network.ns = (int)(socket.s + 1);
143 for(service = network.services.first; service; service = service.next)
145 if(!service.destroyed && !service.processAlone)
147 if(service.s >= network.ns)
148 network.ns = (int)(service.s + 1);
150 for(socket = service.sockets.first; socket; socket = socket.next)
151 if(!socket.destroyed && !socket.processAlone && socket.s >= network.ns)
152 network.ns = (int)(socket.s + 1);
154 network.mutex.Release();
157 // --- Network System ---
160 bool Network_Initialize()
163 if(!network.networkInitialized)
165 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
166 network.networkInitialized = true;
167 network.networkTerminated = false;
168 #if defined(__WIN32__)
169 WSAStartup(0x0002, &wsaData);
172 network.services.Clear();
174 network.services.offset = (uint)&((Service)0).prev;
175 network.sockets.Clear();
177 network.sockets.offset = (uint)&((Socket)0).prev;
179 network.connectSockets.Clear();
180 network.connectSockets.offset = (uint)&((Socket)0).prev;
182 FD_ZERO(&network.readSet);
183 FD_ZERO(&network.writeSet);
184 FD_ZERO(&network.exceptSet);
186 network.socketsSemaphore = Semaphore { };
187 network.selectSemaphore = Semaphore { };
188 network.networkThread = NetworkThread { };
189 incref network.networkThread;
191 network.errorLevel = 2;
193 network.processMutex = Mutex { };
194 network.mutex = Mutex { };
196 network.mainThreadID = GetCurrentThreadID();
198 network.networkThread.Create();
207 void Network_Terminate()
211 if(network.networkInitialized)
213 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
217 guiApp.PauseNetworkEvents();
218 network.networkTerminated = true;
220 delete network.processMutex;
221 delete network.mutex;
223 for(socket = network.connectSockets.first; socket; socket = socket.next)
225 socket.connectThread.Wait();
226 delete socket.connectThread;
229 network.socketsSemaphore.Release();
230 network.selectSemaphore.Release();
232 network.networkThread.Wait();
233 delete network.networkThread;
235 // Cleanup External network.sockets
236 while((socket = network.sockets.first))
239 //network.sockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
241 if(socket._refCount > 1) socket._refCount--;
244 while((socket = network.connectSockets.first))
246 //network.connectSockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
251 // Cleanup network.services
252 while((service = network.services.first))
257 #if defined(__WIN32__)
261 delete network.selectSemaphore;
262 delete network.socketsSemaphore;
265 Log("[P] Network System Terminated\n");
267 network.networkInitialized = false;
274 public bool GetAddressFromName(char * hostName, char * inetAddress)
278 if(!Network_Initialize())
281 host = gethostbyname(hostName);
284 strcpy(inetAddress, inet_ntoa(*((IN_ADDR *)host->h_addr)));
290 public bool GetNameFromAddress(char * inetAddress, char * hostName)
295 if(!Network_Initialize())
298 in.s_addr = inet_addr(inetAddress);
299 host = gethostbyaddr((byte *)&in, 4, PF_INET);
302 strcpy(hostName, host->h_name);
308 public bool GetHostName(char * hostName, int size)
310 if(!Network_Initialize())
313 return !gethostname(hostName,size);