9 #define WIN32_LEAN_AND_MEAN
10 #define String _String
13 static WSADATA wsaData;
15 #elif defined(__unix__) || defined(__APPLE__)
22 #include <netinet/in.h>
24 #include <sys/select.h>
25 #include <sys/socket.h>
27 #include <sys/types.h>
29 #include <arpa/inet.h>
33 typedef struct hostent HOSTENT;
34 typedef struct sockaddr SOCKADDR;
35 typedef struct sockaddr_in SOCKADDR_IN;
36 typedef struct in_addr IN_ADDR;
37 #define closesocket(s) close(s)
41 import "GuiApplication"
45 private struct NetworkData
47 // Connections to the outside world
51 // Ongoing Connections
52 OldList connectSockets;
54 fd_set readSet, writeSet, exceptSet;
55 fd_set selectRS, selectWS, selectES;
59 // Synchronization Elements
61 Semaphore socketsSemaphore;
62 Semaphore selectSemaphore;
65 bool networkInitialized;
66 bool networkTerminated;
67 uint errorLevel, lastErrorCode;
79 static class NetworkThread : Thread
84 while(!network.networkTerminated)
90 struct timeval tv = { 0, 0 }; // TESTING 0 INSTEAD OF (int)(1000000 / 18.2) };
92 network.selectRS = network.readSet, network.selectWS = network.writeSet, network.selectES = network.exceptSet;
94 network.mutex.Release();
96 Log("[N] Waiting for network event...\n");
98 if(select(ns, &network.selectRS, &network.selectWS, &network.selectES, &tv))
100 network.mutex.Wait();
101 network.networkEvent = true;
103 Log("[N] Signaling Network event\n");
105 guiApp.SignalEvent();
107 Log("[N] Waiting for select semaphore in Network Thread...\n");
109 network.mutex.Release();
110 network.selectSemaphore.Wait();
111 network.mutex.Wait();
115 ecere::sys::Sleep(1 / 18.2f);
116 network.mutex.Wait();
121 network.mutex.Release();
122 network.socketsSemaphore.Wait();
123 network.mutex.Wait();
127 network.mutex.Release();
132 void Network_DetermineMaxSocket()
137 network.mutex.Wait();
139 for(socket = network.sockets.first; socket; socket = socket.next)
140 if(!socket.processAlone && !socket.destroyed && socket.s >= network.ns)
141 network.ns = (int)(socket.s + 1);
142 for(socket = network.connectSockets.first; socket; socket = socket.next)
143 if(!socket.destroyed && socket.s >= network.ns)
144 network.ns = (int)(socket.s + 1);
146 for(service = network.services.first; service; service = service.next)
148 if(!service.destroyed && !service.processAlone)
150 if(service.s >= network.ns)
151 network.ns = (int)(service.s + 1);
153 for(socket = service.sockets.first; socket; socket = socket.next)
154 if(!socket.destroyed && !socket.processAlone && socket.s >= network.ns)
155 network.ns = (int)(socket.s + 1);
157 network.mutex.Release();
160 // --- Network System ---
163 bool Network_Initialize()
166 if(!network.networkInitialized)
168 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
169 network.networkInitialized = true;
170 network.networkTerminated = false;
171 #if defined(__WIN32__)
172 WSAStartup(0x0002, &wsaData);
175 network.services.Clear();
177 network.services.offset = (uint)(uintptr)&((Service)0).prev;
178 network.sockets.Clear();
180 network.sockets.offset = (uint)(uintptr)&((Socket)0).prev;
182 network.connectSockets.Clear();
183 network.connectSockets.offset = (uint)(uintptr)&((Socket)0).prev;
185 FD_ZERO(&network.readSet);
186 FD_ZERO(&network.writeSet);
187 FD_ZERO(&network.exceptSet);
189 network.socketsSemaphore = Semaphore { };
190 network.selectSemaphore = Semaphore { };
191 network.networkThread = NetworkThread { };
192 incref network.networkThread;
194 network.errorLevel = 2;
196 network.processMutex = Mutex { };
197 network.mutex = Mutex { };
199 network.mainThreadID = GetCurrentThreadID();
201 network.networkThread.Create();
210 void Network_Terminate()
214 if(network.networkInitialized)
216 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
220 guiApp.PauseNetworkEvents();
221 network.networkTerminated = true;
223 delete network.processMutex;
224 delete network.mutex;
226 for(socket = network.connectSockets.first; socket; socket = socket.next)
228 socket.connectThread.Wait();
229 delete socket.connectThread;
232 network.socketsSemaphore.Release();
233 network.selectSemaphore.Release();
235 network.networkThread.Wait();
236 delete network.networkThread;
238 // Cleanup External network.sockets
239 while((socket = network.sockets.first))
242 //network.sockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
244 if(socket._refCount > 1) socket._refCount--;
247 while((socket = network.connectSockets.first))
249 //network.connectSockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
254 // Cleanup network.services
255 while((service = network.services.first))
260 #if defined(__WIN32__)
264 delete network.selectSemaphore;
265 delete network.socketsSemaphore;
268 Log("[P] Network System Terminated\n");
270 network.networkInitialized = false;
277 public bool GetAddressFromName(const char * hostName, char * inetAddress)
281 if(!Network_Initialize())
284 host = gethostbyname(hostName);
287 strcpy(inetAddress, inet_ntoa(*((IN_ADDR *)host->h_addr)));
293 public bool GetNameFromAddress(const char * inetAddress, char * hostName)
298 if(!Network_Initialize())
301 in.s_addr = inet_addr(inetAddress);
302 host = gethostbyaddr((char *)&in, 4, PF_INET);
305 strcpy(hostName, host->h_name);
311 public bool GetHostName(char * hostName, int size)
313 if(!Network_Initialize())
316 return !gethostname(hostName,size);