7 #define WIN32_LEAN_AND_MEAN
9 static WSADATA wsaData;
11 #elif defined(__unix__) || defined(__APPLE__)
17 #include <netinet/in.h>
19 #include <sys/socket.h>
21 #include <sys/types.h>
23 #include <arpa/inet.h>
26 typedef struct hostent HOSTENT;
27 typedef struct sockaddr SOCKADDR;
28 typedef struct sockaddr_in SOCKADDR_IN;
29 typedef struct in_addr IN_ADDR;
30 #define closesocket(s) close(s)
34 import "GuiApplication"
38 private struct NetworkData
40 // Connections to the outside world
44 // Ongoing Connections
45 OldList connectSockets;
47 fd_set readSet, writeSet, exceptSet;
48 fd_set selectRS, selectWS, selectES;
52 // Synchronization Elements
54 Semaphore socketsSemaphore;
55 Semaphore selectSemaphore;
58 bool networkInitialized;
59 bool networkTerminated;
60 uint errorLevel, lastErrorCode;
72 static class NetworkThread : Thread
77 while(!network.networkTerminated)
83 struct timeval tv = { 0, 0 }; // TESTING 0 INSTEAD OF (int)(1000000 / 18.2) };
85 network.selectRS = network.readSet, network.selectWS = network.writeSet, network.selectES = network.exceptSet;
87 network.mutex.Release();
89 Log("[N] Waiting for network event...\n");
91 if(select(ns, &network.selectRS, &network.selectWS, &network.selectES, &tv))
94 network.networkEvent = true;
96 Log("[N] Signaling Network event\n");
100 Log("[N] Waiting for select semaphore in Network Thread...\n");
102 network.mutex.Release();
103 network.selectSemaphore.Wait();
104 network.mutex.Wait();
108 ecere::sys::Sleep(1 / 18.2f);
109 network.mutex.Wait();
114 network.mutex.Release();
115 network.socketsSemaphore.Wait();
116 network.mutex.Wait();
120 network.mutex.Release();
125 void Network_DetermineMaxSocket()
130 network.mutex.Wait();
132 for(socket = network.sockets.first; socket; socket = socket.next)
133 if(!socket.processAlone && !socket.destroyed && socket.s >= network.ns)
134 network.ns = socket.s + 1;
135 for(socket = network.connectSockets.first; socket; socket = socket.next)
136 if(!socket.destroyed && socket.s >= network.ns)
137 network.ns = socket.s + 1;
139 for(service = network.services.first; service; service = service.next)
141 if(!service.destroyed && !service.processAlone)
143 if(service.s >= network.ns)
144 network.ns = service.s + 1;
146 for(socket = service.sockets.first; socket; socket = socket.next)
147 if(!socket.destroyed && !socket.processAlone && socket.s >= network.ns)
148 network.ns = socket.s + 1;
150 network.mutex.Release();
153 // --- Network System ---
156 bool Network_Initialize()
159 if(!network.networkInitialized)
161 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
162 network.networkInitialized = true;
163 network.networkTerminated = false;
164 #if defined(__WIN32__)
165 WSAStartup(0x0002, &wsaData);
168 network.services.Clear();
170 network.services.offset = (uint)&((Service)0).prev;
171 network.sockets.Clear();
173 network.sockets.offset = (uint)&((Socket)0).prev;
175 network.connectSockets.Clear();
176 network.connectSockets.offset = (uint)&((Socket)0).prev;
178 FD_ZERO(&network.readSet);
179 FD_ZERO(&network.writeSet);
180 FD_ZERO(&network.exceptSet);
182 network.socketsSemaphore = Semaphore { };
183 network.selectSemaphore = Semaphore { };
184 network.networkThread = NetworkThread { };
185 incref network.networkThread;
187 network.errorLevel = 2;
189 network.processMutex = Mutex { };
190 network.mutex = Mutex { };
192 network.mainThreadID = GetCurrentThreadID();
194 network.networkThread.Create();
203 void Network_Terminate()
207 if(network.networkInitialized)
209 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
210 Service service, next;
213 guiApp.PauseNetworkEvents();
214 network.networkTerminated = true;
216 delete network.processMutex;
217 delete network.mutex;
219 for(socket = network.connectSockets.first; socket; socket = socket.next)
221 socket.connectThread.Wait();
222 delete socket.connectThread;
225 network.socketsSemaphore.Release();
226 network.selectSemaphore.Release();
228 network.networkThread.Wait();
229 delete network.networkThread;
231 // Cleanup External network.sockets
232 while((socket = network.sockets.first))
235 //network.sockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
237 if(socket._refCount > 1) socket._refCount--;
240 while((socket = network.connectSockets.first))
242 //network.connectSockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
247 // Cleanup network.services
248 while((service = network.services.first))
253 #if defined(__WIN32__)
257 delete network.selectSemaphore;
258 delete network.socketsSemaphore;
261 Log("[P] Network System Terminated\n");
263 network.networkInitialized = false;
270 public bool GetAddressFromName(char * hostName, char * inetAddress)
274 if(!Network_Initialize())
277 host = gethostbyname(hostName);
280 strcpy(inetAddress, inet_ntoa(*((IN_ADDR *)host->h_addr)));
286 public bool GetNameFromAddress(char * inetAddress, char * hostName)
291 if(!Network_Initialize())
294 in.s_addr = inet_addr(inetAddress);
295 host = gethostbyaddr((byte *)&in, 4, PF_INET);
298 strcpy(hostName, host->h_name);
304 public bool GetHostName(char * hostName, int size)
306 if(!Network_Initialize())
309 return !gethostname(hostName,size);