cleaned all trailing white space from source files.
[sdk] / ecere / src / net / Service.ec
1 #define __statement __extension__   // To compile for Android/X86 (Need to add support to eC)
2                                     // Also had to add __extension__ to __swap16md macro in endian.h
3 namespace net;
4
5 #ifndef ECERE_NONET
6
7 #if defined(__WIN32__)
8
9 #define WIN32_LEAN_AND_MEAN
10 #define String _String
11 #include <winsock.h>
12 #undef String
13 static WSADATA wsaData;
14
15 #elif defined(__unix__) || defined(__APPLE__)
16 default:
17 #define set _set
18 #define uint _uint
19 #include <sys/time.h>
20 #include <unistd.h>
21
22 #include <netinet/in.h>
23 #include <netdb.h>
24 #include <sys/socket.h>
25 #include <sys/wait.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <arpa/inet.h>
29 #undef set
30 #undef uint
31 private:
32
33 typedef int SOCKET;
34 typedef struct hostent HOSTENT;
35 typedef struct sockaddr SOCKADDR;
36 typedef struct sockaddr_in SOCKADDR_IN;
37 typedef struct in_addr IN_ADDR;
38 #define closesocket(s) close(s)
39
40 #endif
41
42 import "network"
43
44 public class Service
45 {
46 public:
47    property int port { set { port = value; } get { return port; } };
48    property Socket firstClient { get { return sockets.first; } };
49    property bool processAlone { get { return processAlone; } set { processAlone = value; } };
50
51    virtual void OnAccept();
52
53    s = -1;
54
55    // --- Services ---
56
57    bool Start()
58    {
59    #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
60       SOCKET s;
61
62    #ifdef DEBUG_SOCKETS
63       Log("[P] [NStartService]\n");
64    #endif
65
66       s = socket(AF_INET,SOCK_STREAM,0);
67       if(s != -1)
68       {
69          SOCKADDR_IN a;
70          bool val = true;
71
72          a.sin_family=AF_INET;
73          a.sin_port=htons((uint16)port);
74          a.sin_addr.s_addr=INADDR_ANY;
75    #ifdef DEBUG_SOCKETS
76          Log("Service Socket: %x\n", s);
77    #endif
78
79          setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
80          if(!bind(s,(SOCKADDR *)&a, sizeof(a)))
81          {
82             if(!listen(s,5))
83             {
84                network.mutex.Wait();
85                network.services.Add(this);
86                this.s = s;
87
88                destroyed = false;
89                sockets.Clear();
90
91                // Fix up the links/offsets here...
92                sockets.offset = (uint)&((Socket)0).prev;
93
94                FD_SET(s, &network.readSet);
95                FD_SET(s, &network.exceptSet);
96                if(s >= network.ns)
97                {
98                   network.ns = (int)(s+1);
99                   network.socketsSemaphore.Release();
100                }
101                network.mutex.Release();
102                return true;
103             }
104          }
105          closesocket(s);
106       }
107    #endif
108       return false;
109    }
110
111    bool Stop(void)
112    {
113    #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
114       SOCKET s = this.s;
115       Socket socket;
116
117    #ifdef DEBUG_SOCKETS
118       Log("[P] [NStopService]\n");
119    #endif
120
121       network.mutex.Wait();
122       while((socket = sockets.first))
123       {
124          socket.Free(false);
125          delete socket;
126       }
127       network.mutex.Release();
128
129       if(s != -1)
130       {
131          network.mutex.Wait();
132          this.s = -1;
133          network.services.Remove(this);
134          FD_CLR(s, &network.readSet);
135          FD_CLR(s, &network.exceptSet);
136          network.mutex.Release();
137          closesocket(s);
138       }
139
140       Network_DetermineMaxSocket();
141       return true;
142    #endif
143       return false;
144    }
145
146    bool Process()
147    {
148       bool gotEvent = false;
149       if(s != -1)
150       {
151          fd_set rs, ws, es;
152          int selectResult;
153          struct timeval tvTO = {0, 200000};
154
155          FD_ZERO(&rs);
156          FD_ZERO(&ws);
157          FD_ZERO(&es);
158          FD_SET(s, &rs);
159          //FD_SET(s, &ws);
160          FD_SET(s, &es);
161
162          selectResult = select((int)(s+1), &rs, &ws, &es, &tvTO);
163          if(selectResult > 0)
164          {
165             if(FD_ISSET(s, &rs))
166             {
167                accepted = false;
168                OnAccept();
169                if(!accepted)
170                {
171                   SOCKET s;
172                   SOCKADDR_IN a;
173                   int addrLen = sizeof(a);
174                   s = accept(this.s,(SOCKADDR *)&a,&addrLen);
175                   closesocket(s);
176                }
177                gotEvent |= true;
178             }
179          }
180       }
181       return gotEvent;
182    }
183
184 private:
185
186    Service()
187    {
188       Network_Initialize();
189    }
190
191    ~Service()
192    {
193       Stop();
194    }
195
196    int port;
197    Service prev, next;
198
199    SOCKET s;
200    OldList sockets;
201    bool destroyed;
202    bool accepted;
203    bool processAlone;
204 }
205 #endif