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